Unix 时间戳转换器,免费
在 Unix 时间戳(秒 / 毫秒)与可读日期之间互相转换。显示本地时间、UTC、ISO 8601 和相对时间。自动检测时间戳格式。
时间戳 → 日期
日期 → 时间戳
Unix epoch 时间到底是什么
Unix epoch 时间(也称作 POSIX 时间、Unix 时间,或者直接叫「epoch」)是一种把时间瞬间表示为单个整数的系统:从 Unix epoch(即 1970 年 1 月 1 日 00:00:00 UTC)起经过的秒数(在 JavaScript 和许多现代系统中是毫秒数)。负数代表 epoch 之前的时间;正数代表之后的时间。这种用单个整数表示的方式具有非常吸引人的性质:与时区无关(同一时刻在地球上任何地方这个数字都相同)、易于比较(更晚的时间是更大的数)、计算时长非常简单(直接相减)。Unix 时间是几乎所有操作系统、所有数据库引擎、所有 API 协议、所有编程语言标准库内部的时间表示方式,即便是那些用户界面里展示日历日期的系统,底层值也都以 epoch 整数形式存储。
为什么选 1970 年 1 月 1 日,以及其他 epoch
1970-01-01 这个 epoch 可以追溯到 Bell Labs 早期的 Unix 时代。Unix 的 time_t 类型最初是一个有符号 32 位整数,从某个选定的基准点开始计数秒;当时团队选择了开发开始之前最近的元旦(也就是 1970 年 1 月 1 日。这是一个务实而非哲学性的决定)Unix 在 1969-1971 年间开发,选用一个较新的 epoch 可以在有符号 32 位范围内最大化时间戳的可用区间。其他系统也根据自己的使用场景选择了不同的 epoch。NTP(网络时间协议,RFC 5905)使用 1900 年 1 月 1 日作为 epoch,重要原因是 NTP 需要覆盖更长的历史范围。Windows FILETIME 使用 1601 年 1 月 1 日作为 epoch、并以 100 纳秒为一个 tick(这是包含 1601 年的 400 年格里历周期的起点)。VAX/VMS 使用 1858 年 11 月 17 日(修正儒略日 epoch,在天文学中很流行)。Mac classic 使用 1904 年 1 月 1 日。JavaScript Date 用的是 Unix epoch,但计的是毫秒而非秒(一个 64 位浮点数,可用范围约 ±1 亿年)。结论:2026 年 Unix epoch 是主流,但历史上还有许多别的选择,每一种都各自留下了向后兼容的包袱。
Y2K38 问题,Unix 时间会用尽(差不多吧)
如果 time_t 是有符号 32 位整数(最早的 Unix 设计),那么可表示的最大时间戳是 2,147,483,647,对应于 2038 年 1 月 19 日(星期二)03:14:07 UTC。再过一秒,这个值就会溢出为负数,绕回到 1901 年 12 月 13 日。这就是 Y2K38 问题(也被称作 Epochalypse)。在现代 64 位系统上,time_t 是有符号 64 位整数,溢出日期是公元 292,277,026,596 年 12 月 4 日(稳稳超过太阳的寿命。但 32 位嵌入式系统目前依然在工业控制器、长任务期卫星、银行后端系统、油气行业的 SCADA 网络、汽车信息娱乐系统,以及设计寿命长达数十年的 IoT 传感器中活跃部署。从 2000 年代初开始,缓解工作就一直在进行)所有主要操作系统、数据库和编程语言现在在 64 位硬件上都默认使用 64 位时间(Linux 在 2020 年 3 月发布的内核 5.6 完成了这一切换;Windows 一直就用的 64 位;macOS Catalina 在 2019 年放弃了 32 位支持)。嵌入式系统才是真正的长尾。Y2K38 问题不会像 Y2K 那样集中爆发于某一天;它会是一系列在 2038 年前夕、在长尾系统中陆续出现的小故障,跟 Y2K 当年主要发生在那些没人去打补丁的冷门系统里完全是同一个套路。
ISO 8601,另一个标准的时间格式
如果说 Unix 时间是机器之间传输用的格式,那么 ISO 8601 就是供人阅读的格式。该标准最初以 ISO 8601:1988 发布,并在 2000、2004 年修订,最近的版本是 ISO 8601-1:2019 和 ISO 8601-2:2019,它定义了像 2026-05-03T14:30:00Z(其中 Z 表示 UTC)或 2026-05-03T14:30:00+01:00(带显式偏移)这样的表示法。「T」用来分隔日期和时间;末尾的偏移则消除时区的歧义。对于互联网协议,RFC 3339(Klyne 与 Newman,2002)定义了 ISO 8601 的一个更严格、也更易解析的子集,你在 JSON API 响应、日志时间戳、JWT 的 exp/iat 字段以及 OAuth 流程里看到的就是这种格式。它和 Unix 时间的关系:ISO 8601 是同一个时间瞬间的可读形式;Unix 时间是同一个瞬间的整数形式。本工具这样的转换器就是在两者之间双向转换。本地时间形式(不带偏移的 2026-05-03T14:30:00)是有歧义的,任何要跨时区的系统都应避免它,它常常是各种隐蔽 bug 的源头:JSON API 声称在返回时间戳,却没说明它们究竟是哪个时区的。
秒 vs 毫秒,常见的混淆
在操作系统层面,Unix 时间计的是秒,大约 2001 年到 2286 年之间的任意时刻都用 10 位整数表示(2001 年之前的时间戳只有 9 位或更少)。JavaScript 的 Date.now()、JVM 的 System.currentTimeMillis()、.NET 的 DateTimeOffset.ToUnixTimeMilliseconds() 和大多数 Web API 计的都是毫秒,同样范围里是一个 13 位整数。两种形式正好相差 1,000 倍,而在与多个系统打交道的代码里,最常见的时间戳相关 bug 就是把毫秒值喂给一个期望秒的函数(结果得到一个比预期晚 1,000 倍的日期),或反之(得到一个 epoch 之后只过去几分之一秒的日期)。本转换器根据位数自动判断:10 位或更少 = 秒;13 位或更多 = 毫秒。处于中间的值(11–12 位、有歧义)时,转换器会优先选择能给出合理日期的那种解释。微秒(16 位,被一些高精度系统和许多数据库的 TIMESTAMP 类型使用)和纳秒(19 位,被 Linux clock_gettime、Go 的 time.UnixNano()、OpenTelemetry 这类现代可观测性工具使用)也会出现,但在面向用户的数据里相对少见。
你真正需要这种转换的场合
- 读 API 响应。一个 REST 接口返回
"created_at": 1714665600,那是哪一天?粘贴一下,看到「2024 年 5 月 2 日 16:00:00 UTC」,继续往下排查。Stripe、GitHub、AWS 以及大多数企业 API 都用 Unix 时间整数作为日期字段,正是为了避免时区歧义。 - 解析日志时间戳。服务器日志为了紧凑和解析速度,常把时间记成 Unix 整数。要读懂「1714665600.234 ERROR connection refused」,就得把开头那个数字转换成日历时间,才能跟其他事件对应起来。
- 调试 JWT。JSON Web Token 中的
exp(过期)和iat(签发时间)声明按照 RFC 7519 都是 Unix 时间整数。要检查一个 token 是否已经过期,或者它是什么时候签发的,把那个数值粘贴到这里就行。 - 计算时间差。把两个 Unix 时间戳相减,就能得到它们之间的时长,单位是秒(或毫秒)。不用做时区运算,不用考虑夏令时调整,也没有任何日历算术上的边界情况。
- 带 epoch 列的数据库查询。许多老一些的数据库会把时间戳存为 Unix 整数。要查询「X 和 Y 之间的所有事件」,就得把可读的截止日期转换成 Unix 整数,再放进 WHERE 子句里。
- 定时任务和 cron。那些按绝对时间调度任务的系统(Kubernetes CronJobs、AWS EventBridge、Azure Logic Apps)在配置里通常希望用 Unix 时间作为目标时间。把人类友好的目标时间换算成 epoch 即可。
- 解读那些「有意思」的时间戳。一些著名的 epoch 值:0 = 1970 年 1 月 1 日 00:00:00 UTC(也就是 epoch 本身);1234567890 = 2009 年 2 月 13 日 23:31:30 UTC(曾被短暂地当作「Unix billion」时刻来庆祝);1500000000 = 2017 年 7 月 14 日 02:40:00 UTC;2000000000 = 2033 年 5 月 18 日 03:33:20 UTC;2147483647 = 2038 年 1 月 19 日 03:14:07 UTC(也就是 Y2K38 溢出点)。
关于闰秒和「真实」时间的一点说明
一个微妙的复杂之处:POSIX 定义的 Unix 时间不包含闰秒。协调世界时(UTC)会偶尔加入一个闰秒,让民用时间和地球的实际自转保持一致,自 1972 年这套体系开始至今,共加入了 27 个闰秒。Unix 时间则当作那些闰秒从未发生过:当某一天结束时插入一个闰秒时,时钟要么会重复最后一秒(Linux 传统的做法),要么把它「抹平」分散到一段更长的时间里(Google 的「leap smear」做法,AWS 和许多 CDN 也采用了这种方式)。对绝大多数应用层使用场景来说,这并不重要,亚秒级的时间精度在应用层面很少有实际意义。但对于高精度科学工作、金融交易系统的时间戳,或者具有法律证据力的时间戳,闰秒处理方式就是一个有名的边界情况来源。IERS(国际地球自转和参考系统服务)会提前六个月公告闰秒;最近一次是在 2016 年 12 月 31 日末插入的。国际社会一直在考虑彻底取消闰秒(2022 年的国际计量大会通过了一项决议,准备在 2035 年前完成这一步)。
隐私:转换只在浏览器里进行
你粘贴进来的时间戳本身通常并不敏感(一个 Unix 整数只透露了某个时间瞬间),但围绕它的上下文(一行同时含有真实用户标识符和这个时间戳的日志、一个包含真实用户声明的 JWT、一个带内部实体 ID 的 API 响应)往往才是敏感的。本转换器完全在你的浏览器里通过 JavaScript 内置的 Date API 运行,不上传,不记录,你可以一边输入时间戳,一边在 DevTools 的网络选项卡里验证(你会看到没有任何请求被发出),或者在页面加载完成后让它离线(飞行模式)。顶部那个不断刷新的「now」显示用的是你设备的本地时钟,而不是某个网络时间源。
常见问题
什么是 Unix 时间戳?
Unix 时间戳(也叫 Epoch 时间或 POSIX 时间)是从 1970 年 1 月 1 日 00:00:00 UTC 起经过的秒数,遵循的是 Unix 的 POSIX 抽象(这种抽象不计算闰秒)而不是真正经过的原子钟秒数。许多现代系统使用毫秒而非秒以获得亚秒级精度(JavaScript 的 Date.now()、Java 的 System.currentTimeMillis()、.NET 的 DateTimeOffset.ToUnixTimeMilliseconds())。Unix 时间是几乎所有操作系统、数据库和 Web API 中的标准时间表示方式。
秒与毫秒有何不同?
差一个 1,000 倍的因子。2026 年,秒级精度的 Unix 时间戳是 10 位(例如 1714665600);毫秒级精度的是 13 位(例如 1714665600234)。本转换器根据位数自动识别。混用两种形式时最常见的 bug,就是把毫秒喂给一个期望秒的函数(结果得到一个比预期晚 1,000 倍的日期),或者反过来。
为什么转换出的时间相差几小时?
Unix 时间本身和时区无关,但显示成可读形式时取决于你用哪个时区来显示它。本转换器同时显示三种格式:本地时间(你浏览器所在的时区)、UTC(格林尼治)和 ISO 8601(带显式偏移)。如果结果跟你的预期对不上,请检查一下时区,你「预期」的那个值,多半是另一个时区下的,而你读到的是另一种格式。
什么是 Y2K38 问题?
如果 Unix 时间存放在一个有符号 32 位整数里(最早的 Unix 设计),那么它会在 2038 年 1 月 19 日 03:14:07 UTC 溢出。现代 64 位系统不受影响,溢出日期被推到大约公元 2920 亿年。Y2K38 风险集中在那些仍然在使用的 32 位嵌入式系统里(工业控制器、卫星、汽车信息娱乐系统、银行后端、寿命长达几十年的 IoT 传感器)。和 Y2K 不一样的是,Y2K38 不会是某一天集中爆发的危机,而是 2038 年前后这些年里,长尾系统中接连发生的一系列小故障。
这个工具能离线工作吗?
可以,页面加载完成后,所有转换都是通过 JavaScript 内置的 Date API 在你的浏览器里完成的。使用过程中不会有任何网络调用。「Now」按钮使用的是你设备的本地时钟;顶部那个不断更新的时间戳是从你的系统时钟读取的,不会去联系任何时间服务器。