Unix 时间戳 10 位和 13 位的区别:程序员必知的 5 个坑
10 位和 13 位的本质:秒 vs 毫秒
Unix 时间戳是从 1970-01-01 00:00:00 UTC 起经过的秒数(10 位)或毫秒数(13 位)。同样一个时刻,秒级约 17 亿(10 位),毫秒级约 17 万亿(13 位),识别方法很简单:位数不同。
坑 1:前后端单位不一致
这是最经典的线上事故:后端 Java 用 System.currentTimeMillis() 返回 13 位,前端 JS new Date(timestamp) 却按毫秒解析;或者后端返回 10 位,前端误乘了 1000。统一规范:API 契约里明确标注 sec/ms 单位。
坑 2:2038 年问题
32 位有符号整数最大值 2147483647,对应 2038-01-19 03:14:07 UTC。之后 32 位系统的时间戳会溢出回绕。虽然现代系统多为 64 位,但嵌入式、老数据库、部分语言默认 int32 仍需警惕。
坑 3:时区错位
时间戳本身是 UTC 的,不带时区。显示时必须做本地化:JS 的 new Date() 会自动转本地时区,但 Java SimpleDateFormat 默认用服务器时区,如果服务器是 UTC 而用户在东八区,展示就偏 8 小时。存库用 UTC 时间戳、展示用本地化格式化,是最稳妥的约定。
坑 4:毫秒被误当秒
13 位毫秒值若被当作秒处理(如直接塞进只认秒的接口),日期会错乱到公元 50000 年附近;10 位秒值若被当毫秒,则退回 1970 年。可用 时间戳转换工具 快速核对当前时刻是否正确。
坑 5:JS 的 Date 边界与日期字符串
// 秒 → 毫秒(关键转换)
new Date(seconds * 1000)
// 毫秒直接用
new Date(milliseconds)
// 不要用字符串拼接时间!new Date("2026-08-17 20:00") 在部分浏览器解析为本地时区,new Date("2026-08-17T20:00:00Z") 才是 UTC
常见问题
Q:如何快速判断一个 13 位数字是毫秒时间戳而不是别的 ID? 转成日期后落在 1970~2286 年范围内,基本可以确定是毫秒级时间戳。
Q:2038 年真的会发生吗? 64 位系统不会,但如果你还在维护 32 位二进制、老 PHP 版本或某些数据库类型,需要提前改造。
Q:时间戳会受闰秒影响吗? Unix 时间戳按 POSIX 约定忽略闰秒,一天永远是 86400 秒,因此跨闰秒时刻可能存在 ±1 秒偏差。
