go 中 time.unix 用于秒+纳秒转 time.time,参数为 int64 秒和纳秒(0–999999999),默认本地时区;time.time.unix 才是时间转 unix 秒戳,返回 utc 秒数,与时区无关。

Go 语言里不需要自己写 Unix 时间戳转换函数,time.Unix 和 time.Time.Unix 已经覆盖全部常见场景;但用错参数顺序、忽略时区或误判单位是高频翻车点。
time.Unix 是把秒+纳秒转成 time.Time,不是“时间转时间戳”
time.Unix 的作用是「从 Unix 时间戳构造 time.Time」,输入是秒数(sec)和纳秒数(nsec),不是字符串或其它格式。很多人误以为它能直接解析 "1717027200" 这样的字符串——它不能。
- 第一个参数是秒(int64),第二个是纳秒(int64),纳秒部分必须在 [0, 999999999] 范围内,超出会 panic
- 结果时间默认基于本地时区,不是 UTC;如果需要 UTC 时间,得显式调用
.UTC() - 常见错误:
time.Unix(1717027200, 0).Format("2006-01-02")在 CST 时区输出的是2024-05-31,不是 UTC 的2024-06-01
time.Time.Unix 才是“时间转时间戳”,返回秒级整数
如果你手头有一个 time.Time 变量,想得到标准 Unix 秒级时间戳,直接调用 .Unix() 方法即可。它永远返回自 1970-01-01 00:00:00 UTC 起的秒数(int64),与时区无关。
- 注意:它只返回秒,不带毫秒或纳秒 —— 如果需要毫秒,用
t.UnixMilli()(Go 1.17+) - Go 1.17 之前没
UnixMilli?那就用t.Unix()*1000 + int64(t.Nanosecond()/1e6),但要注意负时间戳下Nanosecond()返回的是正偏移,需手动处理符号 - 别用
fmt.Sprintf("%d", t.Unix())做 JSON 序列化 ——json.Marshal默认把time.Time编成字符串,要序列化为数字得自定义MarshalJSON
解析字符串时间戳(如 "1717027200")必须先转 int64
Go 没有内置函数直接把字符串时间戳转 time.Time,你得先 strconv.ParseInt,再喂给 time.Unix。
- 错误写法:
time.Unix("1717027200", 0)—— 类型不匹配,编译失败 - 正确写法:
sec, _ := strconv.ParseInt("1717027200", 10, 64); t := time.Unix(sec, 0) - 务必检查
err:空字符串、超范围值(如大于1)、非数字字符都会导致解析失败 - 如果字符串带毫秒(如
"1717027200123"),拆成秒和毫秒:秒 =1717027200,纳秒 =123 * 1e6,再传给time.Unix
time.UnixNano 和 UnixMilli 的边界容易混淆
time.UnixNano() 返回纳秒级时间戳(自 epoch 起的纳秒数),而 time.UnixMilli() 返回毫秒级。它们都不能直接用于 time.Unix() —— 因为 time.Unix() 的两个参数是「秒 + 纳秒」,不是「总纳秒」。
- 错误:把
t.UnixNano()直接当sec传给time.Unix—— 会得到一个离谱的时间(比如公元 5000+ 年) - 正确换算:
sec := nano / 1e9; nsec := nano % 1e9,再调time.Unix(sec, nsec) -
time.UnixMilli()同理:先除 1000 得秒,余数乘 1e6 得纳秒 - 注意:负时间戳下取模行为和 Go 的
%运算符一致(向零取整),所以-1234 % 1000 == -234,需额外调整
最常被忽略的是:所有 time.Unix* 系列方法返回的都是 UTC 时间基准,但 time.Unix(sec, nsec) 构造出的 time.Time 默认显示为本地时区 —— 这不是 bug,是设计,但容易让人误判日期。调试时多打一句 t.UTC().String() 能省半小时。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











