是秒还是毫秒
Unix 时间戳记的是从 1970 年 1 月 1 日 0 点 UTC 起流逝的时间。麻烦在于,有的系统按秒计,有的按毫秒计。
- 秒 — Unix 命令、PostgreSQL 和 MySQL 的时间函数、JWT 里的
exp与iat、多数 REST API - 毫秒 — JavaScript 的
Date.now()、Java 的System.currentTimeMillis()、不少日志采集链路
单位弄反,结果不是落在 1970 年 1 月(把毫秒当秒读),就是飞到公元五万年(把秒当毫秒读)。这个工具会按数值大小猜测单位,并把按哪种读的写出来,日期看着不对时先看那一行。
时区陷阱
时间戳本身没有时区。它只是指向某一瞬间的一个数字,时区是在把这个数字变成人看的文字时才加上去的。所以同一个值在北京显示为下午 4 点,在伦敦显示为上午 7 点。
因此,缺陷报告里只写“下午 3 点失败”是缺了一半信息。日志里请留时间戳,或者带偏移量的 ISO 8601 字符串,人读的时刻只在展示时才拼出来。
2038 年问题
时间戳如果存进 32 位有符号整数,会在 2038 年 1 月 19 日溢出。那一刻数值绕成负数,日期变成 1901 年。现在的语言和数据库大多用 64 位,但如果你在维护老的嵌入式固件或旧 C 代码,值得确认一下这个字段的宽度。
负数和 0
负数指向 1970 年以前。把生日这类较早的日期存成时间戳时就会出现,而有些库对负值处理得并不好。
0 是 1970 年 1 月 1 日 0 点 UTC。真实数据里出现这个值,多半不是真的时刻,而是一个没被初始化的字段。