如何读懂和转换 Unix 时间戳(以及把 cron 写对)
1719849600 是一个日期。1719849600000 也是。它们是同一个时刻,只是单位不同——而分清这两者,比软件里几乎任何其他事情都更能解释“日志对不上”“差了一千倍”“为什么这个事件在 1970 年”这类事故。
Unix 时间戳(也叫 epoch 时间、POSIX 时间)数的是从 1970 年 1 月 1 日 00:00:00 UTC 起经过的秒数。概念就这么多。所有让人困惑的地方,都来自两个细节:单位和时区。
为什么用秒数而不是日期
因为日期有歧义,数字没有。
“2026 年 3 月 15 日下午 2:30”在你站的位置不同就指向不同的时刻,而且跨过夏令时切换点之后它就没意义了。存下来的时间戳没有这个问题:它是一个整数,在每台机器、每个时区、任何时刻都完全相同。存数字,展示时再格式化——这就是规则。破坏它(存一个格式化好的本地日期字符串),就是数据库里那些“一年挪两次一小时”的事件的来源。
秒还是毫秒:反复发生的那个 bug
同一个时刻,两种单位:
- 秒:
1719849600—— 10 位 - 毫秒:
1719849600000—— 13 位
JavaScript 的 Date.now() 返回的是毫秒。Unix 和多数命令行工具用的是秒。一旦你把两者混起来,就会出现两种失败之一:
- 把秒当成毫秒传进去,所有日期都会塌回 1970 年 1 月——因为 17 亿毫秒只是 epoch 之后大约 20 天。
- 把毫秒当成秒传进去,你的事件会落到五万多年后。
数位数是最快的区分办法:10 位是秒,13 位是毫秒,其他长度就得仔细看。本站的时间戳转换工具会自动套用这条规则,而当长度有歧义时,它会把两种解释并排显示,让你不会悄悄选错。
时区:时间戳根本没有时区
这一条事实能解开大部分困惑:Unix 时间戳永远是 UTC。 它不带时区,因为它不需要——它是一个计数,而计数在哪里都一样。
只有当你把时间戳渲染成人能读的日期时,时区才登场。1719849600 同时是:
- 纽约 2026-07-01 16:00(EDT,UTC−4)
- 伦敦 2026-07-01 21:00(BST,UTC+1)
- 东京 2026-07-02 05:00(JST,UTC+9)
同一个数字,三个正确答案。这就是为什么一条只写“16:00”的日志在没有时区的情况下毫无用处,也是为什么所有正经的日志系统都存 UTC、只在边界处才转换。转换工具把你的本地时间和 UTC 并排显示,正是为了这个——让你不再猜自己在看哪一个。
顺带说 2038 问题
以有符号 32 位整数存储的时间戳,会在 2038 年 1 月 19 日 03:14:07 UTC 溢出。那一刻它会翻成一个很大的负数,日期跳到 1901 年。
这不是危机,因为现代系统用 64 位整数或浮点,而 64 位的秒数大约 2920 亿年才溢出。但你还是会在老数据库字段、嵌入式设备和 1990 年代的文件格式里遇到 32 位时间戳。如果你今天在定 schema,就存 64 位——不花任何代价,还永久地把这个问题消掉。
转换时间戳
- 打开 Unix 时间戳转换工具。
- 粘贴一个时间戳,或者用实时时钟取“现在”。
- 读结果——你的本地时区和 UTC 并排。
- 反方向:选一个日期时间,读回对应的 epoch 值。
所有计算都在页面本地完成。这一点值得一提,理由只有一个:日志里的时间戳旁边,往往就是令牌、会话 ID 和用户标识。把这样一整块粘进一个随机网站,是个值得改掉的习惯。
写出真正符合你本意的 cron
cron 表达式是五个字段,顺序如下:
分钟 小时 日 月 星期
* * * * *
所以 0 */6 * * 1-5 读作:在第 0 分钟,每隔 6 小时,任意日、任意月、且星期为周一到周五时执行。cron 解析工具会把它翻译成人话,并列出接下来 10 次运行时间——这是确认你写的就是你想的唯一可靠办法。
四个最容易踩的点:
时区是服务器的,不是你的。 cron 按机器设定的时区跑。你写的“早上 9 点”,在一台 UTC 服务器上就是 UTC 9 点——也就是纽约的凌晨 4 点。这个误解解释了相当大一部分“为什么我的任务在错误时间跑”。信任小时字段之前,先确认服务器的时区。
“日”和“星期”是“或”,不是“与”。 这是 cron 最有名的坑。当两个字段都被限定(比如 0 0 13 * 5),任务会在每月 13 号或者任意一个周五跑,而不是“13 号且是周五”。想要交集,单个表达式表达不了。
*/15 不是“每小时过 15 分”的那个意思。 它是每 15 分钟一次,整个小时都跑::00、:15、:30、:45。这通常正是人们想要的,但值得说清楚。
星期字段里 0 和 7 都表示周日。 标准 cron 两个都接受。选一个,保持一致。
常见问题
怎么区分秒级和毫秒级时间戳? 数位数。10 位是秒,13 位是毫秒。17 亿是合理的秒值,1.7 万亿是合理的毫秒值。
为什么我的时间戳显示 1970 年? 几乎总是单位不匹配。秒被当成了毫秒,于是这个值对应的是 epoch 之后几天,而不是现在。
Unix 时间戳是什么时区的? 没有时区——按定义就是 UTC。时区只在你要格式化展示它的时候才出现。
为什么我的 cron 任务在错误的小时跑了? 因为 cron 用的是服务器的时区。把你想要的本地时间换算到服务器时区,或者显式设置服务器的 TZ。
0 0 13 * 5 到底做什么?
它会在每月 13 号零点,或者任意一个周五运行。当日和星期都被限定时,两者是“或”的关系。