ffcb1a77b9
对 60 个非测试源文件做文档/注释/代码一致性审查,修复 23 项。全部为注释/文档 改动 + 1 处死代码删除,无运行逻辑变更,无 breaking change。 A 档·实质错误(10 项,会误导下游): - app.go: closeResources 三连契约注释统一修正--failAfterInit 走 rollbackReplacedResources 不走 closeResources,closeResources 仅供 doShutdown 复用 - database/manager.go: RandomPicker 注释从过时的 rand.Intn/issue 54899 改为 crypto/rand - model/base.go: datetime(0) 与“亚秒精度”矛盾,改为 datetime(6) - cache/keybuilder.go: 三处示例下划线分隔符改为冒号(与默认分隔符 : 一致) - repository/repository.go: Delete 接口注释从绝对“软删除”改为条件性; UpdateFields 示例移除把字段名当 WHERE 条件的误用写法 - middleware/csrf.go: CSRFToken 注释从“用于 API 模式”改为 Cookie/双重提交模式说明 - examples/full/main.go: POST /users 补上“需 Authorization”标注;删除 _ = app 死代码 - utils/random.go: RandInt/RandInt64 补 min==max 边界说明(对齐 RandIntSecure 写法) B 档·导出符号注释缺失/不完整(6 项): - ws/ws.go: 5 个 Type* 常量、4 个 Err* 变量补注释 - console/console.go: 5 个 Level 常量补注释 - jwt/jwt.go: 2 个 Blacklist 常量补注释 - router/router.go: 包级 GroupWithMiddlewareGroup 补注释 - middleware/ratelimit.go: NewRateLimiter 补 panic 条件与 Stop 生命周期说明 C 档·描述不完整(7 项): - utils/strings.go Substr、convert.go CalcPageCount/CalcOffset、datetime.go StartOfMonth/EndOfMonth、file.go CopyFile、validator.go IsChinese、crypto.go HashFile 补全边界/默认行为/返回值语义 - response/error.go: WithDetail 补 nil 接收者行为说明 验证:go build / go vet / go test -race 全绿。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
package utils
|
|
|
|
import (
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// NowUnix 返回当前秒级时间戳
|
|
func NowUnix() int64 {
|
|
return time.Now().Unix()
|
|
}
|
|
|
|
// NowTimestamp 返回当前毫秒时间戳
|
|
func NowTimestamp() int64 {
|
|
return time.Now().UnixMilli()
|
|
}
|
|
|
|
// FromUnix 秒级时间戳转 time.Time
|
|
func FromUnix(unix int64) time.Time {
|
|
return time.Unix(unix, 0)
|
|
}
|
|
|
|
// FromTimestamp 毫秒时间戳转 time.Time
|
|
func FromTimestamp(timestamp int64) time.Time {
|
|
return time.UnixMilli(timestamp)
|
|
}
|
|
|
|
// FormatTime 格式化时间
|
|
func FormatTime(t time.Time, layout string) string {
|
|
return t.Format(layout)
|
|
}
|
|
|
|
// ParseTime 解析时间字符串
|
|
func ParseTime(timeStr, layout string) (time.Time, error) {
|
|
return time.Parse(layout, timeStr)
|
|
}
|
|
|
|
// FormatDateTime 格式化为标准日期时间 "2006-01-02 15:04:05"
|
|
func FormatDateTime(t time.Time) string {
|
|
return t.Format("2006-01-02 15:04:05")
|
|
}
|
|
|
|
// FormatDate 格式化为日期 "2006-01-02"
|
|
func FormatDate(t time.Time) string {
|
|
return t.Format("2006-01-02")
|
|
}
|
|
|
|
// FormatTimeOnly 格式化为时间 "15:04:05"
|
|
func FormatTimeOnly(t time.Time) string {
|
|
return t.Format("15:04:05")
|
|
}
|
|
|
|
// StartOfDay 返回指定时间当天的开始时间 (00:00:00)
|
|
func StartOfDay(t time.Time) time.Time {
|
|
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
|
}
|
|
|
|
// EndOfDay 返回指定时间当天的结束时间 (23:59:59.999999999)
|
|
func EndOfDay(t time.Time) time.Time {
|
|
return time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 999999999, t.Location())
|
|
}
|
|
|
|
// StartOfWeek 返回指定时间当周的开始时间(周一为第一天,00:00:00)。
|
|
//
|
|
// 用日历日回退而非 t.Add(-N*24h),避免 DST 切换日 24h ≠ 1 个日历日导致落错日(M4)。
|
|
func StartOfWeek(t time.Time) time.Time {
|
|
weekday := int(t.Weekday())
|
|
if weekday == 0 {
|
|
weekday = 7 // 周日归为 7,使周一为第一天
|
|
}
|
|
// 回退到本周周一的日历日,再取当日 00:00:00(保留原时区)。
|
|
monday := time.Date(t.Year(), t.Month(), t.Day()-(weekday-1), 0, 0, 0, 0, t.Location())
|
|
return StartOfDay(monday)
|
|
}
|
|
|
|
// StartOfMonth 返回指定时间当月 1 日 00:00:00(保留原时区)。
|
|
func StartOfMonth(t time.Time) time.Time {
|
|
return time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, t.Location())
|
|
}
|
|
|
|
// EndOfMonth 返回指定时间当月最后一天 23:59:59.999999999(保留原时区)。
|
|
func EndOfMonth(t time.Time) time.Time {
|
|
return time.Date(t.Year(), t.Month()+1, 0, 23, 59, 59, 999999999, t.Location())
|
|
}
|
|
|
|
// GetDateInt 返回 yyyyMMdd 格式的日期整数
|
|
func GetDateInt(t time.Time) int {
|
|
ret, _ := strconv.Atoi(t.Format("20060102"))
|
|
return ret
|
|
}
|
|
|
|
// ParseDateInt 将 yyyyMMdd 格式的整数转为时间(当日 00:00:00,本地时区)。
|
|
//
|
|
// 注意:非法输入(如 month=13、day=32)会被 time.Date 静默规范化(溢出进位),
|
|
// 调用方需自行保证输入合法或在使用前校验(M4)。
|
|
func ParseDateInt(date int) time.Time {
|
|
year := date / 10000
|
|
month := (date % 10000) / 100
|
|
day := date % 100
|
|
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
|
|
}
|