当前常见的 10 位时间戳通常以秒为单位,13 位时间戳通常以毫秒为单位。两者相差 1000 倍,转换时选错单位会得到远离预期的日期。
核心区别是时间单位
Unix 时间戳表示从 1970 年 1 月 1 日 00:00:00 UTC 开始经过的时间。10 位值通常记录秒数,13 位值通常记录毫秒数。
从秒转换为毫秒需要乘以 1000,从毫秒转换为秒需要除以 1000。位数只是快速判断方式,最终仍应以接口文档为准。
- 秒级:常见于后端接口和传统系统
- 毫秒级:常见于 JavaScript 和前端日志
- 微秒、纳秒时间戳可能更长
时间戳本身不包含时区
同一个时间戳代表同一个绝对时刻。页面显示为北京时间、UTC 或其他地区时间,是格式化阶段应用时区后的结果。
遇到固定相差 8 小时的情况,通常不是时间戳错误,而是把 UTC 当成本地时间,或重复执行了时区换算。
接口联调时如何避免单位错误
在字段名中明确使用 createdAtSeconds、createdAtMs 等单位信息;写入数据库前统一单位;在边界位置使用固定样例做自动化测试。
转换异常时先检查数量级,再检查时区,最后检查日期字符串是否被浏览器按本地时间自动解释。
如何判断一个数字是不是时间戳
位数只能作为第一步判断。当前日期附近的秒级时间戳通常是 10 位,毫秒级通常是 13 位,但历史时间、未来时间以及前导零都可能改变位数。更可靠的方法是分别按秒和毫秒转换,观察哪个结果落在合理时间范围。
还要排除业务流水号、递增主键和随机数字。时间戳通常随事件发生时间递增,并能对应到明确日期;如果数字长度相似但转换结果毫无业务意义,就不应强行把它解释为时间。
- 检查数量级是否接近当前时间
- 分别尝试秒和毫秒单位
- 结合字段名和接口文档判断
- 确认数值是否随事件时间变化
不同语言和数据库的默认单位
JavaScript 的 Date.now() 返回毫秒,而许多 Unix 命令和后端语言的时间函数默认返回秒。把前端值直接传给只接受秒的接口,会把日期推到遥远未来;把秒值直接交给 JavaScript Date,则常常落在 1970 年附近。
数据库字段可能保存整数时间戳,也可能保存带时区或不带时区的日期类型。数据在接口、数据库和前端之间传递时,应在边界处明确转换一次,避免每一层都猜测单位并重复处理。
- JavaScript Date 常用毫秒
- Unix 和部分后端函数常用秒
- 数据库日期类型不等于 Unix 时间戳
- 接口字段名应直接注明 seconds 或 milliseconds
时间问题的系统排查顺序
首先确认原始值和单位,其次确认转换函数期望的单位,然后检查时区,最后再检查字符串解析规则。按照这个顺序可以避免把单位错误误判为时区错误,也能减少无意义的加减八小时操作。
在日志中同时记录原始时间戳、ISO 8601 时间和业务时区时间,能显著降低跨系统排查成本。关键任务还应监控服务器时间同步,时钟漂移会影响签名有效期、定时任务和事件排序。
- 确认原始单位
- 确认转换函数输入单位
- 明确显示时区
- 使用 ISO 8601 作为跨系统可读格式
- 检查服务器时钟同步
立即处理
使用相关工具
常见问题
关于这个问题
为什么转换结果是 1970 年?
通常是把毫秒值当成秒值处理,或传入了过小的数字。
北京时间时间戳需要额外加 8 小时吗?
不需要。时间戳表示绝对时刻,显示时选择 Asia/Shanghai 时区即可。
