基础概念2026-11-01

Unix 时间戳为什么有 10 位和 13 位

一句话结论:10 位是秒级,13 位是毫秒级。两者指的是同一个时刻,只是精度不同。

为什么会有两种

Unix 时间戳的定义是「从 1970-01-01 00:00:00 UTC 到现在的秒数」。

  • 秒级:1700000000,10 位,C 语言和 Unix 系统的传统用法
  • 毫秒级:1700000000000,13 位,JavaScript 的 Date.now() 返回值就是毫秒

所以前端传给后端的常常是 13 位,后端数据库里存的可能是 10 位——两边不做转换就会出现「时间差了 1000 倍」或者「显示 1970 年」。

怎么快速判断

看位数就行:

位数 单位 典型来源
10 位 秒 PHP time()、Python time.time() 取整、Linux
13 位 毫秒 JavaScript Date.now()、Java System.currentTimeMillis()

两个都能用正负号表示 1970 年之前的时间,但实际项目里几乎不会遇到。

转换代码

// 13 位 → 10 位
const seconds = Math.floor(milliseconds / 1000)

// 10 位 → 13 位
const milliseconds = seconds * 1000

// 时间戳 → 日期
new Date(seconds * 1000)

// 日期 → 时间戳
Math.floor(Date.now() / 1000)

为什么转换结果会差 8 小时

这是最常被问到的问题,原因通常不是时间戳错了,而是显示时区理解错了。

时间戳本身是绝对时刻,不带时区。1700000000 对应:

  • UTC 时间:2023-11-15 06:13:20
  • 北京时间(UTC+8):2023-11-15 14:13:20

如果你按 UTC 存、按本地展示时又手动加了 8 小时,就会重复加一次。正确做法是:存时间戳或 UTC,展示时交给本地时区自动处理。

2038 问题

32 位有符号整数最大是 2147483647,对应 2038-01-19 03:14:07 UTC。用 32 位整形存秒级时间戳的老系统会在这个时刻溢出。新系统请用 64 位整型或毫秒级。

常见问题

13 位时间戳怎么转成 10 位?

除以 1000 并向下取整,例如 1700000000000 → 1700000000。

时间戳转换后差 8 小时是为什么?

大概率是把 UTC 当成了北京时间,或者本地时区又手动加了一次 8 小时。时间戳是绝对时刻,展示时交给时区处理即可。

时间戳有上限吗?

32 位有符号整数最大到 2038-01,新系统请用 64 位或毫秒级时间戳。

用工具试试