Unix 时间戳转换器

时间戳与日期双向转换,自动判断并标明单位。

留空可查看当前时间。纯数字会按 Unix 时间戳读取。

数一数位数

读一个时间戳,唯一真正棘手的地方是判断它的单位,而数量级就能定下来。实践中没有歧义,因为对于任何人真正会用到的日期,各个区间并不重叠。

位数单位示例来自哪里
101787788800Unix、PHP、多数 API、JWT 声明
13毫秒1787788800000JavaScript、Java、Kafka
16微秒1787788800000000Python 的 time_ns()/1000、Postgres 内部
19纳秒1787788800000000000Go、InfluxDB、Prometheus

搞错了就是差一千倍,于是结果要么落在 1970 年代初,要么落在几万年之后。你盯着看的时候一目了然;可当它只是日志表里的一列时,就完全看不见了——而那正是它真正咬人的地方。

Unix 时间实际在数什么

1970 年 1 月 1 日 00:00:00 UTC 以来的秒数,并假定每一天恰好是 86,400 秒。

这个假定是错的。每隔几年就会插入一个闰秒,好让原子时与地球自转保持对齐——而地球自转正在逐渐变慢。Unix 时间并不表示闰秒——系统要么把某一秒重复一遍,要么把它抹平摊到一整天里,好让计数保持均匀。

后果是:Unix 时间并不是自 1970 年以来真正流逝秒数的计数;它少了大约二十七秒。对于排程、日志和过期判断来说,这恰恰是对的取舍,因为均匀的算术比天文精度更重要。而对于任何要度量真实流逝时长的场合,请改用单调时钟——挂钟时间在 NTP 校正时还可能往回跳。

2038 年问题

一个有符号 32 位整数最大装到 2,147,483,647,作为 Unix 时间戳就是 2038 年 1 月 19 日 03:14:07 UTC。再过一秒它就溢出成负数,日期变成 1901 年 12 月。

任何现代系统都用 64 位,还能撑大约 2920 亿年。不现代的是:嵌入式固件、工业控制器、某些老式数据库列类型,以及仍假定 time_t 是 32 位的 C 代码。风险最高的系统,恰恰是没人在看的那些——千年虫之所以那么烧钱,也是同一个道理。

实际上该用哪种格式

UTC 的 ISO 8601,用于任何跨系统边界、或者要被人读的场合:

2026-08-27T14:30:00Z

它没有歧义,作为纯字符串排序也正确,凌晨两点在日志里也读得懂。那个 Z 很要紧:没有它,多数解析器会假定这是本地时间,于是你就发明了一个只有别国用户才会遇到的 bug。

Unix 秒在内部使用没问题——JWT 的 expiat 声明用的就是它,而整数比较很便宜。代价是它读不懂,而且会招来上面那种单位混淆。

值得避开的是:任何带偏移量却没有时区标识的格式(+01:00 并不能告诉你那是 BST 还是 CET,而这对未来的日期很要紧),以及一切属于 03/04/2026 这类的写法——它在大西洋两岸读出来是两个不同的日子。

存储未来的事件

有个微妙之处会让人栽跟头。对于明年三月九点的一场会议,存 UTC 是错的——如果从现在到那时时区规则发生了变化(而各国政府确实会改),会议就会挪位。未来的本地事件应当存成「本地时间 + 时区标识」(Europe/London),并在显示时按当时现行的规则换算。过去的事件正相反:存 UTC,因为已经发生的事是固定的。

相关

JWT 的 expiat 声明就是 Unix 秒——JWT 解码器会替你换算并标出是否过期。如果你要的是排程而不是换算,cron 解析器会告诉你一个排程下一次什么时候触发。

时间戳相关问题

我的时间戳是秒还是毫秒?

数一数位数。当前的秒级时间戳是 10 位,而且会一直是 10 位直到 2286 年 11 月;毫秒是 13 位。16 位是微秒,19 位是纳秒。搞错了会让答案偏差一千倍,于是你要么落在 1970 年刚过一点的地方,要么落在公元 56000 年附近——一眼就能看出来,可埋在日志里就毫无痕迹。转换器会说明它假定了哪个单位,你也可以手动覆盖。

什么是 2038 年问题?

把 Unix 时间存进有符号 32 位整数的系统,会在 2038 年 1 月 19 日溢出,绕回到 1901 年 12 月。现代系统用的是 64 位,大约还能撑 2920 亿年。真正麻烦的是嵌入式固件、老旧数据库、某些文件系统格式,以及任何仍在使用 32 位 time_t 的 C 代码。它和千年虫是同一类问题,而且和千年虫一样,多半会被一些你永远不会听说的人提前悄悄处理掉。

为什么时间戳不理会闰秒?

因为 Unix 时间的定义,是自纪元以来经过的秒数,且假定每一天都恰好是 86,400 秒——而这并不成立,因为人们会偶尔插入闰秒,好让时钟与地球自转对齐。多数系统不去表示闰秒,而是让某一秒重复或者被「抹平」,好让计数保持整齐。这意味着 Unix 时间并不是真正流逝秒数的计数,而对几乎所有用途来说,这个取舍都是对的。

在 API 里我该用哪种格式?

用 UTC 的 ISO 8601,带 Z 后缀:2026-08-27T14:30:00Z。它没有歧义,作为字符串排序也正确,凌晨两点在查日志的人还看得懂。Unix 秒在内部使用没问题,JWT 的声明用的也是它,但它读起来不透明,而且会招来上面那个「秒还是毫秒」的混淆。要避开的,是任何带本地偏移却不带时区的格式,以及一切分不清 DD/MM 还是 MM/DD 的写法。

为什么我的日期显示的天数和预期不一样?

几乎总是时区边界的问题。不带时区的 ISO 字符串,多数解析器会当作本地时间;而以 Z 结尾的则是 UTC——所以伦敦深夜的一个时间戳,按 UTC 已经是第二天,而洛杉矶清晨的一个时间戳,按 UTC 还停在前一天。存储和传输一律用 UTC,只在显示的时候才转换。

最后审校于 。发现有内容过时了? 告诉我们.