Unix 时间戳是什么?10 位与 13 位怎么分
一、定义与一个例子
Unix 时间戳定义为「从 1970-01-01 00:00:00 UTC 起经过的秒数」(这个起点通常叫 epoch),且不计闰秒。因为基准是 UTC,同一时刻在地球上任何地方算出的时间戳都相同。
以 1789056000 为例:
| 口径 | 显示结果 |
|---|---|
| UTC | 2026-09-10 16:00:00 |
| 北京时间(UTC+8) | 2026-09-11 00:00:00 |
同一个整数,换时区显示就差了 8 小时。时间戳本身没有时区,时区只影响「显示成什么样的日期时间」——这就是所有时区问题的根源。
二、10 位、13 位、16 位、19 位
位数不同是单位不同,不是精度「更精细」就一定更好用:
| 位数 | 单位 | 常见来源 |
|---|---|---|
| 10 位 | 秒 | Linux date +%s、MySQL UNIX_TIMESTAMP() |
| 13 位 | 毫秒 | JavaScript Date.now()、Java System.currentTimeMillis() |
| 16 位 | 微秒 | 部分监控、日志接口 |
| 19 位 | 纳秒 | 高精度计时、内核接口 |
识别办法:数位数,或判断是否大于 1e12(大于就是毫秒级)。前端项目最容易踩的坑是后端给秒、前端按毫秒用,日期会直接偏到 1970 年附近;反之毫秒当秒用,日期会飞到几万年之后。
三、时区怎么换
换算只做两件事:先定口径,再定单位。
- 日期 → 时间戳:必须说明这个日期是 UTC 还是本地时间,两者相差 8 小时;
- 时间戳 → 日期:说明要显示成 UTC 还是本地时间,数值不变。
数据库存时间戳的好处正在于此:整数比较排序快、无时区歧义;缺点是可读性差、不好按「日期」分组统计,所以多数系统的做法是存时间戳或 UTC 时间,展示时再按用户时区格式化。
四、2038 年问题
很多老系统用 32 位有符号整数存秒级时间戳,它能表示的最大值是 2147483647,对应 2038-01-19 03:14:07 UTC;再加一秒就溢出成负数(−2147483648),日期会跳回 1901 年。
- 边界要精确:2147483647 仍未越界,2147483648 才开始越界,判断时别用
>=; - 受影响的主要是老数据库字段、嵌入式设备、32 位系统;
- 现代 64 位系统不受影响,JavaScript 的 Date 上限是 8640000000000000 毫秒(约 ±2.77 亿年)。
五、换算写法速查
| 场景 | 写法 |
|---|---|
| JavaScript | new Date(ts * 1000);取秒 Math.floor(Date.now() / 1000) |
| PHP | date('Y-m-d H:i:s', $ts);strtotime() 反向 |
| Python | datetime.fromtimestamp(ts)(本地)/ fromtimestamp(ts, timezone.utc) |
| MySQL | FROM_UNIXTIME(ts) / UNIX_TIMESTAMP(dt) |
| Shell | date -d @1789056000;date +%s |
六、三个常见错误
- 秒和毫秒混用:差 1000 倍,2038 的溢出判断也会一起错。
- 忘了时区:服务器按 UTC 存、前端按本地显示,跨时区用户看到的日期可能差一天。
- 把时间戳当字符串排序:位数不同的时间戳(秒与毫秒混在一列)按字典序排会乱序,统一单位后再排序。
七、直接算
→ 时间戳转换:秒/毫秒/微秒/纳秒自动识别,UTC 与本地双显示,含 2038 提示
→ 时区转换:全球主要城市时间对照,一次看清跨时区同一时刻
→ 日期计算器:两个时刻相差多少天,N 天后是哪一天
→ Cron 表达式解析:定时任务的时间写法,常和时间戳一起用
本站文章为个人使用经验的原创整理,除已注明来源的引用外均为本人撰写。文中涉及的软件名称、商标、截图等归各自权利人所有,引用仅用于说明与交流。如认为本站内容侵犯了你的合法权益,请通过「关于本站」页面的联系方式告知,核实后将及时更正或删除。