时间戳转换:Unix 时间戳 ↔ 日期时间
把 Unix 时间戳换算成日期,也能反过来把日期时间换算成时间戳。UTC、你本机的时区、以及你自己挑的时区 会同时列出来。秒和毫秒是分开处理的:这一页会说明它按哪个单位读的、另一个读数会是什么,所以你不会拿到一个 「格式很漂亮但其实错了」的日期。所有换算都在你的浏览器里完成,输入的内容不会上传。
————————————
秒 · — 毫秒
—
—
你在上面输入的内容不会发给我们:换算全部在这个页面里完成。详见 隐私说明。
日期时间 → 时间戳
—————————示例会载入 America/New_York 的 2026-03-08 02:30:00 ——
那是一个不存在的墙上时间,因为那天凌晨钟往前跳了一小时。用它最容易看清:当一个本地时间不唯一时,本工具做了什么。
怎么用
- 把数字粘进去,点「换算」。你不需要先知道它是秒还是毫秒。如果确实知道,就在单位里选定,本工具不再推断任何东西。
- 先读"单位"那一行,再读日期。它会说清单位是你选的还是它判定的,以及另一个读数会是什么。 这一行才是这一页存在的理由 —— 只给一个日期的时间戳工具,你没有办法核对它。
- 对照三个时区。UTC 放第一位,因为日志、数据库和接口都用它;本机时区第二位,因为那是你脑子里真正在想的那个时间; 所选时区留给最要紧的场景 —— 一台在外地的服务器,或者对方用他的时区说的那个截止时间。
秒还是毫秒:单位是怎么定下来的
这就是这个类别的工具最不可信的地方。1757000000 按秒读是 2025-09-04,按毫秒读是 1970-01-21。
两个都是真实日期,格式都完全正确,而这个数字本身并没有说明发送方用的是哪一种。所以"默默替你选一个"的工具是在猜 ——
猜错的时候它给出来的仍然是一个日期,这才是事故能活过评审的原因。
本工具只有一条写在明面上的规则,而且用的是窗口,不是感觉:
| 位数 | 更可能的单位 | 这个读数覆盖的年份 | 例子 |
|---|---|---|---|
| 1–10 位 | 秒 | 1970 年 9 月 到 2286 年 11 月 | 1757000000 → 2025-09-04 |
| 11–13 位 | 毫秒 | 1970 年 4 月 到 2286 年 11 月 | 1757000000123 → 2025-09-04 |
| 14 位以上 | 一般都不成立 | 按毫秒已超过 2286 年,按秒更远 | 100000000000000 |
完整的规则是这样的:
- 先把两种读数都算出来,一个按秒、一个按毫秒。
- 只有一个落在 1900-01-01 到 2100-12-31 之间,就取它。这个窗口是本工具明说的假设(一个真实时间戳大概长什么样), 不是关于你数据的结论。
- 两个都落在窗口内、或者都不在,本工具会直接说出来。两个都合理时按上面的位数规则取一个,并把另一个日期 放在旁边让你自己核对;两个都不合理时它不给单一答案,而是把两种读数都列出来。
除此之外的任何做法,都是在制造"确定"的假象。想彻底关掉推断也有办法:在单位里选「秒」或「毫秒」, 本工具就完全按你说的算,包括那种"这么读明显不合理"的情况。
UTC、本机时区,和你自己挑的时区
时间戳不是日期,它只是"从 1970-01-01 00:00:00 UTC 起算了多少秒"这个带符号的计数。只有在你说明按哪个时区读之后, 它才变成一个日历时间。这就是同一个数字在这一页上显示成三种墙上时间的原因,也是它们之间的差不是错误的原因: 1757000000 秒在 UTC 是 15:33,在东京是当天 23:33,在洛杉矶是当天早上 08:33。
有三件事值得记住:
- 日期可能差一天。UTC 时间 16:00 之后,东八区已经是第二天了。库里存的、日志里写的都是 UTC, 而你看到告警时按本地时间理解 —— 如果不在心里把这一步转过来,就会得出"这条日志是昨天的"这种错误结论。
- 偏移和时区不是一回事。
+08:00是一个固定偏移,永远不变;Asia/Shanghai是一个时区, 它的偏移由规则决定,而规则可以由政府改。存偏移保住的是"哪一刻",存时区名保住的是"哪一刻 + 当初的意图"。 - 时区清单和每一个偏移都来自你的浏览器。页面向
Intl要这些数据,用的就是你系统里同一份时区数据库。 本页不打包任何表,本站也不维护这样的表 —— 抄一份偏移表进来,某个国家改规则的那天它就开始错,而且是静默地错。
结果里同时给出四种格式,因为它们回答的是不同问题:ISO 8601 的 UTC 写法是写进数据库或 JSON 字段的那种; 带偏移的 ISO 8601 同时保留了本地墙上时间并消除了歧义;RFC 2822 是邮件头这类老协议要的格式; 而可读的那一行,是你能念给别人听的那一行。
夏令时:本地时间不等于某一刻的两种情况
把时间戳换成日期是纯算术;反过来不是。因为钟面上的 02:30 并不总是对应某一个确定的时刻。
在实行夏令时的时区里,每年有两次映射会断掉,而且两种情况都能"问"出来。
不存在的本地时间
钟往前拨的那天,有一小时的墙上时间根本不会出现。America/New_York 的 2026-03-08,
钟从 01:59:59 直接跳到 03:00:00,所以那天没有 02:30。落在这一小时里的时间,只能是人手写的,或者按一个没考虑夏令时的公式算出来的。
点一下「载入夏令时示例」就能看到:本工具把缺口两侧都列出来 —— 偏移 −05:00 的 01:30 和偏移 −04:00 的 03:30 ——
并说明它用的是哪一个。一个悄悄返回其中一个、却完全不提缺口存在的转换器,等于替你回答了一个你没问的问题。
出现两次的本地时间
钟往回拨的那天,有一小时的墙上时间会出现两次:2026-11-01 纽约的 01:30,一次在偏移 −04:00,另一次在偏移 −05:00, 真实时间上差一小时。这两个时刻对应着两个不同的 Unix 时间戳。本工具把两次都显示出来,并取较早的那一次, 这样你手上那个值是可以核对的,而不是只能相信。
注意这一页里没有什么:没有任何切换日期的清单。切换点是在你用页面的那一刻从浏览器的时区数据里读出来的, 包括从哪个偏移变成哪个偏移。也正因为如此,缺口那一段的说明写的是两个具体偏移,而不是一句笼统的"夏令时前后要注意"。
负时间戳,以及 0 为什么不是"空值"
0 是 1970-01-01 00:00:00 UTC —— 一个真实时刻,同时也是很多系统在"日期字段从没被赋值"时返回的东西。
本工具照常换算,并说明 0 的两种读法指向同一个时刻,因为在它身上单位确实不影响结果。
负值是 1970 年之前的日期,属于正常的 Unix 时间,不是某种特殊格式。它出现的场景包括:服务器时钟曾经走错后来被校正; 某个值被按有符号读、又被重新解释;或者数据本身就要表达 1970 年之前的日期。读法和平常完全一样, 只是本工具会明说"这个结果在 1970 年之前",因为一个 1969 年的日期太容易被当成格式错误了。
2038 边界
在把 Unix 时间存成 32 位有符号整数的系统上,能表示的最大值是 2147483647,也就是 2038-01-19 03:14:07 UTC。
再过一秒,它不会变成 2038-01-19 03:14:08,而是回绕到负数那一端,读出来是 1901-12-13 20:45:52。
由此有两点,也正是它值得单独占一节的原因:
- 这是算术,不是预测。2 的 31 次方减一是 2147483647;回绕后的值就是它在补码下的读法。上面两个日期都是本页 用这两个数当场算出来的,你可以自己手算核对。
- 会出问题的是那些安静的角落。桌面与服务器软件几十年前就换成了 64 位计数器,但 32 位字段仍然留在文件格式、 嵌入式设备、协议头和旧二进制里。你粘进来的值靠近这条线时,本页会提示;越过去的值,本页会把回绕后的日期算给你 —— 那正是受影响的系统会读出来的结果。
毫秒没有这个问题:毫秒计数从一开始就需要超过 32 位,所以从来没有人把毫秒时间戳存成 32 位。 因此这条提示只在按秒读的时候出现 —— 这也是"单位那一行"比看起来更重要的原因。
哪些输入会被拒绝,为什么
下面每一条其实都能算出数来。但每一条都需要先替你做决定,而这些决定不在输入里 —— 所以本工具宁可说清它做不到什么,也不给你一个悄悄变了意思的数字。
| 输入 | 为什么拒绝 | 可以怎么写 |
|---|---|---|
1.5 | 是 1.5 秒,还是 1500 毫秒打错了?四舍五入就等于替你选了,而选错就换了时刻。 | 写整数,或者改单位 |
1e9 | 在一种语境里是简写,在另一种语境里是打错。 | 写成 1000000000 |
0x5F5E100 | 十六进制是一种写法,不是另一个时间戳。 | 先换成十进制 |
1,757,000,000 | 千分位写法随地区而变,而且在不少地方逗号是小数点。 | 粘原始数字 |
+1757000000 | 编程语言接受它,日志里从来没人这么写;本工具拒绝,而不是默默归一化。 | 去掉前面的加号 |
04/09/2025 | 在英国是 9 月 4 日,在美国是 4 月 9 日。同一个字符串,两个日期。 | 写成 2025-09-04 |
25-09-04 | 两位年份没有说明是哪个世纪。 | 写完整年份 |
2026-02-29 | 2026 不是闰年,这一天不存在。 | 核对日期,或用 2024、2028 |
23:59:60 | 闰秒在纸面上存在,但没有对应的 Unix 时间戳;Unix 时间不数它。 | 用 23:59:59 或下一秒 |
最后两条属于历法算术,不是规矩:能被 4 整除的年份 2 月有 29 天,整百年没有,但能被 400 整除的整百年又有 —— 所以 2000 年有 2 月 29 日,1900 年没有。闰秒大体上一两年加一次,而 Unix 时间忽略它, 因此任何转换在闰秒前后那一小时看起来都可能有点不对。知道这件事,比一个把 60 静默变成别的东西的工具更有用。
有什么东西离开了这个页面
没有。这一页只引用了一个纯函数模块,时区数据向浏览器要;不请求我们的服务器、不给你的数据挂任何统计事件、不做任何存储。 关掉标签页,你输入的数字就没了。
但这不等于任何时间戳都可以随便粘。日志里的时间戳旁边往往还有主机名、账号或者令牌,而浏览器的内存、剪贴板和屏幕都不在这个页面 能管的范围内。这个工具负责告诉你它做了什么,留在你屏幕上的东西还得你自己负责。
常见问题
- 我这个数字是秒还是毫秒,怎么判断?
- 你不需要先知道,本工具两种都会读,并且会告诉你它用了哪一种。判据写在明面上:先看哪个读数落在一个真实存在的日期(1900-01-01 到 2100-12-31)。只有一个合理就取它;两个都合理 —— 10 位数永远属于这种情况,因为它按毫秒读只能落在 1970 年 1 月 —— 就按位数规则(10 位及以下按秒)取一个,并且把另一个读数一起显示出来给你对照。如果你知道数据源的写法,直接把单位改成秒或毫秒,本工具就不再推断。
- 为什么换一个时区,日期就变了?
- 因为时间戳本身不包含日期。它是"从 1970-01-01 00:00:00 UTC 起算了多少秒",只有在你指定了时区之后,它才会变成一个日历上的时间。1757000000 秒在 UTC 是 2025-09-04 15:33,在东京是当天 23:33,在洛杉矶是当天早上 08:33 —— 它们没有哪个"更正确",所以这一页把三个并排给你看,而不是替你挑一个。对中文用户最实际的一条是:服务器日志大多按 UTC 写,而 UTC 16:00 之后东八区已经是第二天,跨过去看日志时日期会差一天。
- 时区数据是从哪来的?
- 来自你的浏览器。页面通过 Intl.DateTimeFormat 读偏移、通过 Intl.supportedValuesOf 取时区清单,所以每一个偏移和每一次夏令时切换,用的都和你系统里其他程序同一份时区数据库。页面本身不打包任何时区表,本站也不维护这样的表:把一个偏移表抄进代码,等于发布一份在某个国家改规则那天就会过期的数据,而且过期时不会有任何提示。
- 2038 问题到底是什么?
- 在把 Unix 时间存成 32 位有符号整数的系统上,能表示的最大值是 2147483647,也就是 2038-01-19 03:14:07 UTC。再过一秒,这个值会回绕到负数那一端,日期读出来变成 1901 年。这是算术,不是预测:2 的 31 次方减一是 2147483647,回绕后的值就是它在补码下的读法。本页把两个日期都当场算给你看,而不是复述一句结论。现在的 64 位系统不受影响,而这恰恰是它难被发现的原因 —— 会出问题的,是文件格式、嵌入式设备、协议头里那些还在用 32 位字段的地方。
- 时间戳可以是负数吗?
- 可以,负值表示 1970-01-01 之前的时刻。常见的来源有三种:服务器时钟曾经走错、后来被校正;一个字段被按无符号读之后再解释;数据本身就要表示 1970 年之前的日期(例如把生日存成相对偏移)。本工具照常换算,并明确告诉你结果在 1970 年之前 —— 因为一个 1969 年的日期很容易被当成格式错误,然后在上面白花一个下午。
- 为什么 1.5 和 1e9 会被拒绝,不帮我四舍五入?
- 因为这些写法里的意图不在数字里。1.5 可能是 1.5 秒,也可能是 1500 毫秒打错了;把它静默取整,得到的是一个看起来正常、实际指向另一个时刻的答案。千分位逗号、十六进制、科学计数法同理:它们都能算出数来,但没有一个能告诉本工具你原本要的是什么。写成纯整数,或者把单位改成秒或毫秒,你拿到的是精确结果而不是一个"看着像"的结果。
不含任何数据。这一页没有时区表、没有夏令时日期清单、也没有示例数据集 —— 它显示的每一个日期,都是用它自己的时区规则和公历算术,从你输入的那个值当场算出来的。