time.unix() 是最直接的秒级时间戳转换方式,正确用法为 time.unix(timestamp, 0),需避免误用 unixmilli/unixmicro,并注意时区、layout 格式、负值兼容性及函数封装的时区透明性。

time.Unix() 是最直接的转换方式
Go 标准库的 time.Unix() 函数专为秒级时间戳设计,它接受两个参数:sec(秒)和 nsec(纳秒),返回一个 time.Time 实例。秒级时间戳只需把 nsec 设为 0,无需手动除法或字符串拼接。
常见错误是误用 time.UnixMilli() 或 time.UnixMicro()——它们只接受毫秒/微秒级输入,传入秒级数值会导致时间偏移约 49 天(因为 Go 把它当成了毫秒处理)。
- 正确写法:
time.Unix(timestamp, 0) - 错误写法:
time.UnixMilli(timestamp)(timestamp是秒级,不是毫秒) - 注意时区:默认返回本地时区时间;如需 UTC,调用
.UTC()
格式化输出要显式指定 layout 字符串
Go 的时间格式化不使用常见的 YYYY-MM-DD HH:mm:ss 模板,而是基于一个固定参考时间(Mon Jan 2 15:04:05 MST 2006)的 layout 字符串。这是 Go 独有的约定,不能省略或随意改动数字。
标准 RFC3339 格式(如 2006-01-02T15:04:05Z)可直接用 time.RFC3339 常量,但要注意它默认输出 UTC 时间;若要本地时区的类似格式,需先调用 .Local() 再格式化。
- 本地时间 ISO 格式:
t.Local().Format("2006-01-02 15:04:05") - UTC 时间 RFC3339:
t.UTC().Format(time.RFC3339) - 避免硬编码
"yyyy-mm-dd"——这会输出字面量,不是真实日期
处理负数时间戳(1970 年前)要留意 Unix 时间定义
秒级时间戳可以是负数,表示 1970-01-01 00:00:00 UTC 之前的时间。time.Unix() 完全支持负值,但部分系统或前端 JS 的 Date() 构造函数对负时间戳兼容性较差,尤其在旧版浏览器中可能解析失败或显示为 Invalid Date。
- Go 层面无需额外处理,
time.Unix(-31536000, 0)正确对应 1969-01-01 - 若 API 需兼容 JS,建议统一转为毫秒级并用
new Date(ms)(JS 支持负毫秒) - 注意:某些数据库驱动(如 pq)对负时间戳支持有限,入库前建议校验范围
封装成函数时别忽略 error 和时区透明性
单纯转换时间戳不会出错,但封装成工具函数时,用户常期望明确的时区语义。比如“标准格式”到底指本地时间还是 UTC?这个必须由调用方决定,函数内部不应擅自调用 .Local() 或 .UTC()。
也不需要返回 error——time.Unix() 是纯函数,只要输入是 int64 就一定成功。加 error 返回值反而误导使用者以为存在失败路径。
- 推荐签名:
func TimestampToTime(ts int64) time.Time { return time.Unix(ts, 0) } - 格式化交给调用方:
TimestampToTime(1717027200).Format("2006-01-02 15:04:05") - 若业务强依赖某一时区,应单独提供带时区参数的版本,而不是默认绑定
真正容易被忽略的是 layout 字符串里每个数字的含义和位置——它不是占位符,而是参考时间的具体值。写错一个数字(比如把 02 写成 01)会导致整个格式崩掉,且无编译错误或运行时提示。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











