时间戳与时区:本地时间、UTC 和 Unix 时间戳怎么对齐
时间戳调试的常见误区:本地时间与 UTC 差8 小时、秒毫秒混用、跨时区显示错乱。本文讲清 Unix 时间戳的时区无关性,以及前后端时间对齐的实际做法。
Unix 时间戳本质上是 UTC
Unix 时间戳定义为「从 1970-01-01 00:00:00 UTC 起经过的秒数」。关键性质是:它与时区无关。同一个时间戳在任何时区解析都指向同一个绝对时刻,变的只是显示出来的本地时间字符串。
最常见的坑:差 8 小时
中国大陆是 UTC+8。当服务器返回 1728000000,JavaScript 用 new Date(timestamp * 1000) 转出来的时间会比预期少8 小时——原因通常是把 UTC 字符串当成本地时间解析了。
正确做法:服务端传时间戳或标准格式,接收端统一用 UTC 解释,展示时再转本地时区。
秒还是毫秒?
这是另一个高频坑。JS 的 Date.now() 返回毫秒,而 JWT 的 exp、很多后端接口的时间戳用秒。混用会导致时间差出 1000 倍。
快速判断方法:如果数值是 1.7e12 量级(约等于 13 位),多半是毫秒;如果是 1.7e9 量级(10 位),多半是秒。
三种时间表示的对应关系
- 本地时间:人类日常使用,格式如
2026-10-07 14:30:00,带时区语义。 - UTC 时间:全球统一的绝对时刻,格式如
2026-10-07T06:30:00Z,末尾 Z 表示 UTC。 - 时间戳:数字形式,存储和传输最方便,不受时区影响。
接口通信建议统一用时间戳或UTC 格式,避免字符串格式导致的解析歧义。
跨时区显示的正确做法
前端拿到时间戳后,用 JavaScript 的 toLocaleString() 或 Intl.DateTimeFormat 按用户时区渲染,不要手工加减小时数——夏令时会让手工计算出错。服务端存储一律用UTC 或时间戳,展示层才做时区转换。
调试时可以用 DevKit 的时间戳转换工具双向核对:把接口返回的时间戳转成 UTC 和本地时间各一次,与服务端日志比对,一眼就能看出偏差出在哪一层。
常见问题
- 时间戳为什么与时区无关?
- 因为 Unix 时间戳定义的是从 1970-01-01 00:00:00 UTC 起经过的绝对秒数,本身就是一个绝对时刻,不带任何时区信息。时区只影响把它转成可读文本时的显示结果。
- 毫秒和秒怎么快速区分?
- 看位数。13 位(1.7e12 量级)通常是毫秒,10 位(1.7e9 量级)是秒。当前时间戳的毫秒值大约是 17xxxxxxxxxxx。
- 跨时区展示应该在前端还是后端处理?
- 建议后端统一存时间戳或 UTC,前端按用户本地时区渲染。前端用 Intl.DateTimeFormat 或 toLocaleString,不要手工加减小时数,避免夏令时出错。