"接口传的时间怎么差了 8 小时?""数据库里的时间为什么是 17 位数?"——时间处理是编程里最经典的坑区,这篇文章把高频问题一次排干净。
1. Unix 时间戳的本质
时间戳 = 自 1970-01-01 00:00:00 UTC 起经过的秒数。它是一个与时区无关的绝对时刻:同一个时间戳,北京显示 08:00,伦敦显示 01:00,但它们是同一瞬间。程序内部存时间用时间戳,只在展示层转本地时区——这是全行业的标准做法,也是"时区错乱"问题的唯一解药。
2. 10 位、13 位、17 位:先看位数
- 10 位:秒(1700000000 ≈ 2023-11);
- 13 位:毫秒(JS 的 Date.now() 默认毫秒);
- 16-17 位:微秒/纳秒(部分语言和监控系统)。
对接接口时先确认对方单位——差 1000 倍的时间戳 bug 每天都在发生。用 时间戳转换 粘贴进去自动识别,十秒验证。
3. 日志时间对不上 8 小时:经典三连
服务器上看到的时间和自己预期差 8 小时(UTC 与北京时间之差),几乎总是以下之一:
- 服务器系统时区是 UTC,而应用用本地时间打日志;
- 数据库连接串没配 serverTimezone,驱动按默认 UTC 解释;
- 代码里混用了 new Date()(本地)和 UTC 方法。
根治方案:服务器、数据库、应用全部统一 UTC 存储,展示层再转本地。临时排查则先对齐三方时区配置再比对时间戳数值。
4. 时间戳与字符串互转的坑
"2026-10-08" 这种字符串没有时区信息,不同环境会按不同时区解释(JS 老引擎把纯日期按 UTC、带时刻的按本地)。跨系统传时间,要么传时间戳,要么字符串带完整偏移(ISO 8601:2026-10-08T08:00:00+08:00)。裸字符串是时区 bug 的最大源头。
5. 2038 年问题还有吗?
32 位有符号整数的秒级时间戳上限是 2147483647(2038-01-19 03:14:07 UTC),溢出后变负数。现代 64 位系统和主流语言早已用 64 位存储,问题基本成为历史;但物联网设备、老式嵌入式系统仍可能中招,采购硬件时值得问一句。
6. 实用换算心法
快速估算时间戳:2026-01-01 00:00 UTC ≈ 1767225600。拿到一个 10 位数,先除以 31536000(一年的秒数)约等于 56,说明是 2026 年附近——数字对不对量级,一眼便知。精确转换交给 时间戳转换,涉及日期间隔用 日期计算器。
结论
时间处理的黄金法则就一条:存储与传输用时间戳或带偏移的 ISO 8601,时区只在展示层处理,且全系统统一。守住这条,90% 的时间 bug 与你无缘。