time.now() 返回带时区的完整时间对象;需秒级戳用 unix(),毫秒级用 unixmilli(),格式化用 format(),强制 utc 用 utc(),指定时区用 in(loc);高频场景应缓存或用 since()。

直接用 time.Now(),别绕弯。Go 没有“当前函数时间读取方法”这种抽象概念,只有标准库 time 包提供的确定、可复用的时间获取方式。
为什么不是 time.Now().Unix() 或其他变体?
因为需求决定返回值类型:
- 要带时区的完整时间对象 → 用
time.Now()(返回time.Time) - 要秒级时间戳(int64)→ 用
time.Now().Unix() - 要毫秒级时间戳 → 用
time.Now().UnixMilli()(Go 1.17+)或time.Now().UnixNano() / 1e6 - 要格式化字符串(如 "2006-01-02")→ 用
time.Now().Format("2006-01-02")
硬套某个“固定写法”反而容易出错——比如在日志里误用 Unix() 导致丢失毫秒精度,或在定时逻辑中忽略时区导致跨地域部署行为不一致。
time.Now() 的时区行为必须手动确认
它默认返回本地时区时间,但 Go 程序常运行在 UTC 容器或不同系统 locale 下,结果不可靠:
- 想强制 UTC → 写
time.Now().UTC() - 想指定时区(如上海)→ 先
loc, _ := time.LoadLocation("Asia/Shanghai"),再time.Now().In(loc) - 用
time.Now().Zone()可检查当前时区名和偏移量,但别在生产逻辑里依赖它自动推断
常见坑:本地开发显示 “CST”(中国标准时间),上线后变成 “CST”(美国中部时间),只因系统 locale 不同——time.Now() 本身不带时区标识,Zone() 返回的是运行时系统设置。
性能敏感场景下避免高频调用 time.Now()
它底层调用系统 clock_gettime 等 syscall,虽快但非零开销。高并发服务中每毫秒调用几百次会明显拖慢吞吐:
- 单次计算、日志打点、HTTP 响应头赋值 → 直接用没问题
- 循环内逐条记录时间(如批量处理 10 万条数据)→ 提前缓存一次
start := time.Now(),后续用start.Add(...)推算 - 需要纳秒级单调时钟(防系统时间跳变)→ 改用
time.Since(start)或runtime.nanotime()(后者无类型,慎用)
注意:time.Now() 不是纯函数,每次调用都可能返回不同值;若误把它当常量缓存(如包级变量初始化),会导致整个程序时间冻结。
真正麻烦的从来不是怎么取时间,而是没想清楚这个时间要用来做什么——比对、序列化、持久化、还是跨系统传递。选对类型、定准时区、控好调用频次,比记住某一行代码重要得多。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











