Unix 时间戳转换器
时间戳与日期双向转换,自动判断并标明单位。
留空可查看当前时间。纯数字会按 Unix 时间戳读取。
数一数位数
读一个时间戳,唯一真正棘手的地方是判断它的单位,而数量级就能定下来。实践中没有歧义,因为对于任何人真正会用到的日期,各个区间并不重叠。
| 位数 | 单位 | 示例 | 来自哪里 |
|---|---|---|---|
| 10 | 秒 | 1787788800 | Unix、PHP、多数 API、JWT 声明 |
| 13 | 毫秒 | 1787788800000 | JavaScript、Java、Kafka |
| 16 | 微秒 | 1787788800000000 | Python 的 time_ns()/1000、Postgres 内部 |
| 19 | 纳秒 | 1787788800000000000 | Go、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 的 exp 和 iat 声明用的就是它,而整数比较很便宜。代价是它读不懂,而且会招来上面那种单位混淆。
值得避开的是:任何带偏移量却没有时区标识的格式(+01:00 并不能告诉你那是 BST 还是 CET,而这对未来的日期很要紧),以及一切属于 03/04/2026 这类的写法——它在大西洋两岸读出来是两个不同的日子。
存储未来的事件
有个微妙之处会让人栽跟头。对于明年三月九点的一场会议,存 UTC 是错的——如果从现在到那时时区规则发生了变化(而各国政府确实会改),会议就会挪位。未来的本地事件应当存成「本地时间 + 时区标识」(Europe/London),并在显示时按当时现行的规则换算。过去的事件正相反:存 UTC,因为已经发生的事是固定的。
相关
JWT 的 exp 和 iat 声明就是 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,只在显示的时候才转换。
最后审校于 。发现有内容过时了? 告诉我们.
