不再头疼的 Unix 时间戳
问三个开发者现在几点,你可能会得到三个答案,取决于他们身处何地。问一个 Unix 时间戳,你得到的是确切的一个数字,对地球上每个人都一样。正是这个单一的整数,让纪元时间(epoch time)悄然支撑起你将会接触的几乎每一个日志文件、数据库行和 API 响应。本页解释这个数字意味着什么、如何双向读取它,以及它在哪里容易绊倒人。

Unix 时间到底是什么
一个 Unix 时间戳是自 1970 年 1 月 1 日 UTC 00:00:00 起所经过的秒数,不计闰秒。那个时刻被称为纪元(epoch),早期的 Unix 工程师选它,仅仅因为它是一个便于起算的整齐日期。在纪元时刻,这个值恰好是 0。此后每过一秒就加一,所以这个数字只会增长。1970 年之前的日期也完全有效,用负整数来表示。
你也会看到这个概念被称为 POSIX 时间,或者笼统地叫纪元时间。无论标签是什么,其机制都一样:一个不断递增的秒数计数器。由于它是一个普通整数,而非格式化的字符串,计算机可以用几个字节存储它,并用一次减法就比较出两者。
秒、毫秒及其同类
经典的 Unix 时间计的是整秒,这给出了你今天看到的那个熟悉的十位数字。但许多环境需要更精细的分辨率。比如 JavaScript 以毫秒为单位工作,产生一个十三位的值,而有些系统进一步深入到微秒或纳秒。一条可靠的经验法则:十位数字是秒,十三位数字是毫秒。如果你转换出来的日期落在 1970 年附近、而你本以为会是当下,那你几乎肯定是把毫秒喂进了一个以秒为单位的字段,或者反过来。我们的转换器会自动检测数量级,所以你很少需要去猜。
开发者为何依赖它
最大的好处是时间戳与时区无关。整数 1735689600 在东京、柏林和圣保罗指的是同一瞬间。存储这个数字而非一个格式化的本地字符串,意味着你永远不必纳闷一个值属于哪个时钟。排序同样轻而易举,因为时间顺序就是数值顺序,所以一个建在时间戳列上的数据库索引无需解析就能正确排序事件。算术也同样干净:两个事件之间的间隔就是一次减法,加一天就是加 86400。正是这些特性,让日志、令牌、缓存和消息队列全都采用纪元时间。
双向转换
从时间戳转到人类可读的日期,意味着取这个秒数,把它投射到日历上,然后按你关心的任何时区格式化它。反方向,你取一个年、月、日和时间,确定它是以哪个时区表达的,再把它折回成自纪元起的秒数。我们的工具瞬间完成两个方向,且完全在你的浏览器中进行,所以你粘贴的任何内容都不会离开你的机器。粘贴一个数字来解码它,或选一个日期来编码它,并在同一时刻以 UTC 和你的本地时间两种形式读取结果。

UTC 对比本地时间,这个经典陷阱
时间戳本身没有时区;它始终锚定在 UTC。混乱只在你显示它时才出现。如果你转换 1700000000,你的屏幕显示某个傍晚时分,而另一个国家的同事看到的是下午,没有任何东西坏了,你们俩看的是同一瞬间,只是渲染成了不同的本地时钟。当代码把一个本地日期当作 UTC 来读取,或者打上一个挂钟时间却不记录偏移量时,bug 就悄悄溜了进来。安全的习惯是存储和传输 UTC,只在最后一刻、当你把值展示给一个人看时,才应用本地偏移。拿不准时,去对照转换器里的 UTC 那行,而不是你的本地那行。
2038 年问题
许多较老的系统把 Unix 时间存在一个有符号的 32 位整数里。这个字段会在 2038 年 1 月 19 日 UTC 03:14:07 之后一秒用尽空间,届时计数器溢出并回绕成一个负数,可能把日期甩回 1901 年。它和 Y2K 是同一类问题。好消息是,现代操作系统和编程语言大多已转向 64 位时间戳,它们在大约 2920 亿年内都不会溢出,所以对于新代码而言,这大多只是一个值得知道的历史趣闻,而非一桩急事。
想要更多基于浏览器的小帮手,请看我们的开发者工具;如果你需要对这些数字本身做运算,计算器触手可及。
常见问题
什么是 Unix 时间戳?
它是自 1970 年 1 月 1 日 UTC 00:00:00 起的秒数,不计闰秒。那个起始时刻被称为纪元,这个计数只随时间增长。
为什么我的数字转换出来的日期接近 1970 年?
你大概混淆了秒和毫秒。十位数字是秒,十三位数字是毫秒。把毫秒喂进一个以秒为单位的字段,会把表面上的时间除以大约一千,让你落在纪元附近。
Unix 时间戳有时区吗?
没有。这个值始终锚定在 UTC。只有当你把时间戳显示成人类可读的日期时,时区才进入画面,这也是为什么同一个数字会为不同的人显示不同的挂钟时间。
我该如何把一个日期转换回时间戳?
提供年、月、日和时间,确定那个日期是以哪个时区表达的,工具就会把它折成自纪元起的秒数。你可以在本页瞬间、在浏览器中完成两个方向的转换。
什么是 2038 年问题?
把 Unix 时间存在有符号 32 位整数里的系统,会在 2038 年 1 月 19 日 UTC 03:14:07 之后一秒溢出。现代的 64 位时间戳能在数十亿年内避免这个问题,所以当前大多数软件都不受影响。
我的数据会被发送到服务器吗?
不会。转换完全在你的浏览器中运行,所以你粘贴的任何时间戳或日期都留在你自己的设备上。
