你有没有遇到过这种事:前端传过来一个时间戳,一解析直接差8小时,或者差整整一天。
不夸张,我上周排查一个报表问题就栽在这上面。花了一小时才发现,问题出在毫秒位。
今天把时间戳排查的方法讲透,全文读完,下次遇到直接照做。
为什么时间戳这么容易出错
时间戳出错基本就3类原因:
- 10位和13位混用:秒级是10位,毫秒级是13位,混用直接差1000倍
- 时区错位:东八区和UTC差8小时,这是最常见的"差8小时"
- 跨日边界:日志按UTC切分,按本地时间看就"差了一天"
三类里,第2类占一半以上。
3步定位法,10秒出结果
第1步:先数位数
拿到时间戳先数数字长度。
- 10位 → 秒级,比如
1762944000 - 13位 → 毫秒级,比如
1762944000000
直接丢进浏览器控制台跑一句:
new Date(1762944000) // 秒级
new Date(1762944000000) // 毫秒级
浏览器会直接告诉你解析出来是几点,对一下业务时间。
第2步:核对时区
如果数值看着对,就是时区问题。统一转成UTC看:
new Date(1762944000).toUTCString()
UTC时间和你本地时间差几小时,差几小时就是时区差几小时。
东八区就是 +8 小时,反推一下就能定位。
第3步:确认是"存错"还是"展示错"
最后一步最关键。
存错:数据库里就存了错的时间戳,往上游查。 展示错:数据是对的,前端格式化时用了错误的时区,改前端。
一个SQL就能验证:
SELECT created_at, FROM_UNIXTIME(created_at/1000) FROM logs LIMIT 5;
FROM_UNIXTIME 默认按服务器时区转,如果结果和预期差8小时,基本可以断定是时区展示问题。
顺手用工具核对
排查到一半想双保险,直接打开 navbox 的时间戳转换工具:
把可疑的时间戳贴进去,秒转成可读时间。再贴个本地时间转成时间戳,两个对着看,差多少一目了然。
不用开IDE,不写脚本,贴一下就行。
3个防坑细节
- 微服务之间的时间戳约定要写在文档里,是秒还是毫秒,写死
- 日志统一存UTC,展示层再转本地时区,这是最稳的方案
- 报表跨日场景,明确用哪个时区切分,别用"自然日"这种模糊词
写在最后
时间戳bug看着烦,其实套路就那3种。
记住:先数位数,再核对时区,最后分清是存错还是展示错。
下次再遇到"差8小时",评论区回来打个卡,你中了哪一类?