「10位还是13位?」时间戳踩坑完全手册
为什么你的时间总是差8小时?为什么2038年还有人踩坑?这篇讲透
☘️ Clover · 2026-05-09
📋 目录
1. 那个让我熬到凌晨3点的坑
讲个真实的故事。
去年做的一个用户行为分析系统,上线后客户反馈"数据时间总是不对,晚了8个小时"。我排查了半天,发现是后端用 Node.js 生成的时间戳传给前端,前端用 JavaScript 的 Date 解析,显示出来就差了8小时。
然后我以为是时区问题,加了 toLocaleString() 里的时区参数。结果……还是差8小时。
最后发现,前端那个13位时间戳是毫秒级,后端存的时候用的是秒级(乘了1000存的),解析的时候又除了一次1000,相当于除了两遍,多除了一次,就差了整整8小时——其实不是8小时,是 3600000 × 8 = 28800000 毫秒,差了整整9.6年。
……我对着这个数字愣了10分钟。
这不是时区问题,这是10位和13位混用导致的世纪级精度灾难。
💡 核心教训:时间戳的位数不仅仅是数字长短的问题,它是单位的问题(秒 vs 毫秒)。团队里第一个拿到时间戳处理逻辑的人,应该写一份文档,或者——用工具做标准化。
2. 10位 vs 13位:到底什么区别
先搞清楚最基本的。
10位时间戳:单位是秒(second),从1970-01-01 00:00:00 UTC开始计算,到现在大概17亿多。写法:1715260800
13位时间戳:单位是毫秒(millisecond),从1970-01-01 00:00:00 UTC开始计算,到现在大概1.7万亿。写法:1715260800000
📐 换算关系:13位 = 10位 × 1000,反过来 10位 = 13位 ÷ 1000
注意,我说的是"大概",因为精确的数值每次都不一样。但你记住这个关系就够了:13位就是10位后面加三个0(乘以1000)。
那么问题来了——为什么会有两种标准?
- 10位(秒):UNIX原生标准,大多数后端语言默认(Python
time.time()、PHPtime()、Gotime.Now().Unix()) - 13位(毫秒):JavaScript原生标准,前端和移动端常用,以及某些HTTP API要求
所以你经常遇到的场景是:后端给你一个10位时间戳,前端当13位处理,或者反过来——这就出事了。
最烦的是,两种处理方式都不会报错。数字还是那个数字,只是差了1000倍。系统跑得好好的,只有当数据需要和时间对应的时候,才发现时间全是错的。
3. 时区问题:UTC时间戳转本地时间总是差8小时
这个坑90%的人都踩过。
你用服务器生成时间戳,是UTC时间。存到数据库没问题。但前端展示的时候,浏览器会把它当成你本地时区的时间来显示。
中国是 UTC+8,所以你北京时间 2026-05-09 08:00:00 的时间戳,转成UTC就是 2026-05-09 00:00:00,差了正好8小时。
但如果你在代码里这样写:
JavaScript 的 Date 构造函数,当传入一个数字时,默认单位是毫秒。你传10位秒级时间戳,它会当成毫秒来处理,等于只过了几十万毫秒——1970年。
所以正确写法是:
⚠️ 血的教训:后端返回时间戳时,一定要在接口文档里写清楚是秒级还是毫秒级!不要假设对方会猜到!接口文档是契约,不是猜测游戏。
4. Bash date:精度居然不是你想的那样
很多人用 date 命令生成时间戳,但你可能不知道——默认行为在不同系统上是不一样的。
等等,%N 是纳秒(9位),不是毫秒(3位)。你截取前13位的话,得到的是"秒+纳秒前3位",这和真正的13位毫秒时间戳不完全一样。
⚠️ 跨平台坑:你在Mac上写的 date +%s%3N 脚本,丢到Linux服务器上跑,%N 可能不支持,或者行为完全不同。生产服务器尽量用Python/Node做时间操作,别依赖Shell的date命令。
还有一个常见坑——时区。
5. 各语言踩坑实录
🟡 JavaScript / TypeScript
🐍 Python
☕ Java
🐹 Go
6. 2038年问题:你以为离你很远?
2038年问题(Y2038 Bug)和经典的2000年问题齐名,但知道的人少得多。
问题的根源是:32位系统的有符号整数(int32)最大值是 2147483647,即 2^31 - 1。如果用这个整数存储秒级时间戳,能表示的最大时间是:
过了这个时间,32位系统会整数溢出,变成负数,日期会跳到 1901-12-13(或者更早)。
🚨 谁会中招:
- 用
int32存储时间戳的老系统(很多嵌入式设备和传统数据库) - 32位Linux/Unix服务器(虽然新服务器基本都是64位了,但Docker容器里可能跑着32位镜像)
- 某些编程语言的旧版时间库(PHP的
DateTime在32位系统上就有这个问题)
✅ 怎么避免:
- 用
int64(64位整数)存储时间戳,这是现代系统的标准做法 - 避免用32位系统跑生产服务,2026年了,应该没有理由还用32位服务器了
- 数据库里时间字段用
DATETIME或TIMESTAMP,不要用整数存时间戳 - 如果你在做跨系统集成,确保对方系统用的是64位时间戳
好消息是,13位毫秒时间戳的最大值是 9,223,372,036,854,775,807(2^63-1),对应大约 292,278,994年——所以只要你用毫秒级的64位时间戳,暂时不用担心2038年问题。
7. 在线工具推荐
说了这么多,最实用的还是——别自己算,用工具。
你可能在各种时间戳转换网站之间来回切换,有时候复制错了,有时候格式不对。我整理了一个在线工具,功能全,支持10位/13位互转,支持时区切换:
如果你觉得这篇文章有用,欢迎收藏。需要批量转换也可以用这个工具搞定。
常见问题
A: 这类工具一般有明确的输入框和输出框,按提示输入内容,点击对应按钮即可得到结果。建议先用简单示例测试功能是否正常,再处理实际数据。
A: 根据具体工具类型决定。格式转换工具适合处理第三方数据,编码工具适合加密传输,压缩工具适合文件上传前处理。多积累工具使用经验,遇到问题时能快速判断用哪个工具解决。
A: 不同工具有不同侧重,重点是理解原理。可以同时安装多个类似工具,实际使用中对比效果,选择最顺手的一个。随着使用经验增加,你也能判断工具的好坏。