Unix 时间戳换算日期时间(10 位秒 · 13 位毫秒 · 本地与 UTC)
粘进 10 位秒或 13 位毫秒时间戳,立刻看到本地时间、UTC 时间和 ISO 8601 两种写法;也可以选一个日期时间,反查它的秒级和毫秒级时间戳。位数怎么判断、为什么会差 8 小时,正文一次讲清。全部在本机换算。
—
四组算好的时间戳
| 填进去 | 秒级时间戳 | 毫秒级时间戳 | UTC 时间 |
|---|---|---|---|
| 1735689600 | 1735689600 | 1735689600000 | 2025-01-01 00:00:00 |
| 1735689600000 | 1735689600 | 1735689600000 | 2025-01-01 00:00:00 |
| 1700000000 | 1700000000 | 1700000000000 | 2023-11-14 22:13:20 |
| 0 | 0 | 0 | 1970-01-01 00:00:00 |
位数决定单位
Unix 时间戳是什么
它是从 1970-01-01T00:00:00 UTC(所谓 epoch)起走过的时间量,起点是一个绝对瞬间,定义里不含时区。同一串 1735689600 在北京和纽约指的是同一个时刻,只是显示的墙上时间不同。正因如此它才适合放进数据库和日志:排序天然正确,跨系统同步没有歧义,也不必额外记录"几点、哪个时区、有没有夏令时"。它不含闰秒,跨闰秒的间隔可能差 1 秒。
10 位是秒,13 位是毫秒
位数几乎总能直接暴露单位:
| 位数 | 通常含义 | 例子 | 说明 |
|---|---|---|---|
| 10 | 秒 | 1735689600 |
一直到 2286 年都是 10 位 |
| 13 | 毫秒 | 1735689600000 |
固定宽度 |
| 16 | 微秒 | — | Date 装不下,这个位数直接报错 |
各家默认口径并不统一:JavaScript 的 Date.now()、Java 的 System.currentTimeMillis()、Go 的 time.Now().UnixMilli() 给毫秒;PHP 的 time()、Linux 的 date +%s、Go 的 Unix()、MySQL 的 TIMESTAMP 给秒;PostgreSQL 内部按微秒存。按位数判断只是启发式,它覆盖绝大多数真实数据,却没法替你确认来源到底想给什么,所以 8 位、11 位这种"两边都不像"的长度直接报错,而不是猜一个看着合理的值——静默猜错单位比一条错误信息难查得多。
为什么你和同事看到的不一样
时间戳相同、显示不同,差别一定在时区。左边那格填进去的是本地墙上时间,按这台电脑当前的时区规则(含夏令时)解释它,才得到对应的 UTC 瞬间;那台机器如果被设成 TZ=UTC,同一个输入就会得到另一个时间戳。团队里稳妥的约定是:存 UTC、传 UTC,只在展示层转成本地时区,服务器和容器显式设 TZ=UTC,别依赖宿主机默认时区。
ISO 8601 末尾的 Z 和 +08:00
Z 是与 UTC 的零偏移标记,+08:00 表示这段墙上时间比 UTC 早 8 小时。所以 2026-01-01T16:00:00Z 和 2026-01-02T00:00:00+08:00 是同一个瞬间,日期数字却差了 1 天。什么偏移都不带的 2026-01-02T00:00:00 由读的人决定含义,最容易出事:按规范 JavaScript 把带 T 的日期时间当本地时间解析,但只写日期的 new Date("2026-01-02") 按 UTC 解析,老 Safari 还会把带 T 的也当成 UTC。所以解析时不把输入交给 new Date() 去猜,而是拆成字段再用本地 setter 组装,解释只有一种:这台电脑的时区。
常见问题
Q:结果比预期差 8 小时怎么办?
先确认那串数字是哪个口径。1735689600 是 UTC 零点,东八区显示成早上 8 点——这不是算错,是同一瞬间的两种写法。如果数据其实是"本地时间被当成 UTC 存进去了",那就按 UTC 读、按 UTC 显示,别再套一层时区,否则偏移会被加两次。
Q:2 月 30 日为什么不报错?
多数语言会静默进位:new Date(2026, 1, 30) 得到 3 月 2 日,往往很晚才发现对不上。这里会报错——组装完把字段回读比对一次,不一致就说明那个本地时间不存在(2 月 30 日、以及夏令时拨快跳过的那一小时都算)。补充一句现实情况:浏览器自带的日期控件通常根本不让你填出 2 月 30 日,它会把值直接清空,所以你更多是遇到「什么都不显示」而不是错误提示;这段校验是为了值真的传进来时(手动键入、某些浏览器、程序写入)不再静默进位。
Q:数据库里存时间戳还是存 datetime?
优先存时间戳,或用带时区语义的类型(PostgreSQL 的 timestamptz),排序、算差值、跨系统同步都简单;datetime 只记墙上时间不记时区,一跨时区就丢信息。MySQL 的 TIMESTAMP 只到 2038 年,长期数据用 BIGINT 存秒或毫秒。
输入去哪了
换算只用语言自带的日期能力,全在这台设备的浏览器里完成;输入的时间戳和日期不会离开这台设备。