← 返回工具箱

Unix 时间戳完全指南:秒与毫秒、2038 问题与时区换算

开发者工具箱 · 使用教程

你从接口拿到的 1729843200 是什么?为什么用工具转出来总是差 8 小时?为什么有人给的是 10 位、有人给 13 位?这篇文章把时间戳这件事讲透。

一、时间戳是什么

Unix 时间戳(Unix timestamp)是从 1970 年 1 月 1 日 00:00:00 UTC 到某一时刻之间经过的秒数。这个起点有个专门的名字,叫 Unix 纪元(Unix Epoch)。

比如 1729843200 表示 2024 年 10 月 25 日 16:00:00 UTC。它不是什么特殊编码,就是一个普通的整数,一直在变大。

注意起点是 UTC,不是北京时间。这是后面所有“差 8 小时”问题的根源。

二、为什么用时间戳而不是日期字符串

对比项时间戳日期字符串
时区歧义无(天然 UTC)有(2024-10-25 16:00 是哪个时区?)
存储大小10 位数字19 字符以上
能比较大小吗能,直接比数字不能,得先解析
跨语言兼容所有语言都能处理整数格式五花八门
人能看懂吗不能能

结论很清楚:机器之间传时间戳,给人看的时候再转成日期字符串。这也是几乎所有 API 的做法。

三、10 位和 13 位的区别

这是最容易踩的坑。时间戳的单位有两种:

位数单位典型来源
10 位秒(second)PHP、Linux date +%s、多数后端接口
13 位毫秒(millisecond)JavaScript Date.now()、Java System.currentTimeMillis()、Android

把 13 位当成秒来解析,会得到一个五万多年后的日期:

1729843200000  当作秒解析 →  公元 56780 年
1729843200     当作秒解析 →  2024-10-25 16:00:00 UTC  ✓

反过来,把 10 位当毫秒,会得到一个 1970 年附近的日期。看到结果明显不对,先数位数。

四、2038 年问题

很多老系统用 32 位有符号整数存时间戳,它能表示的最大值是 2147483647。这个数字对应的时刻是:

2038-01-19 03:14:07 UTC
即 北京时间 2038-01-19 11:14:07

过了这一秒,数值就会溢出变成负数,时间跳回 1901 年。这和传说中的“千年虫”是同一类问题。

影响范围:老版本的 32 位 Linux、嵌入式设备、用 32 位 int 的数据库字段、部分老语言运行时。现在的新系统多数已改用 64 位,理论上够用几千亿年。

如果你在做物联网、工控、老系统维护,2038 是需要提前排期的。换 64 位存储是根本解法,改代码绕过只是拖延。

五、为什么转换结果差 8 小时

因为你所在时区是 UTC+8。同一个时间戳,在不同时区换算出来的“墙上时间”不同:

时间戳 1729843200
  UTC         →  2024-10-25 16:00:00
  北京时间     →  2024-10-26 00:00:00   (+8 小时)

时间戳本身没有问题,是“按哪个时区显示”的问题。判断方法:

六、怎么用本工具转换

  1. 打开开发者工具箱的时间戳标签页
  2. 粘贴时间戳(秒或毫秒都可以,工具会自动识别位数)
  3. 点「转为日期」,得到可读时间
  4. 反向操作:输入日期,点「转为时间戳」

全部在浏览器本地计算,不联网、不上传。

广告位 - 适合横幅广告

七、常见问题

时间戳可以是负数吗?
可以。负数表示 1970-01-01 之前的时刻。生日、历史事件日期经常是负数。不过有些系统不支持负时间戳,处理历史数据时要留意。
为什么后端返回的时间戳是字符串不是数字?
大概率是为了避开大整数精度问题。JavaScript 的数字类型是双精度浮点,能精确表示的整数上限是 2^53,毫秒时间戳虽然远没超,但一些后端会统一把长整型序列化成字符串,属于防御性做法。
本地时间和 UTC 时间该在数据库里存哪个?
存 UTC(或者存时间戳)。不要存“本地墙上时间”,否则一旦服务器迁移时区、或者用户跨国访问,历史数据的含义就糊了。
夏令时会影响到时间戳吗?
不会。时间戳是绝对时刻,和夏令时无关。夏令时只影响“本地墙上时间”的显示规则。中国目前不实行夏令时,但如果有海外业务就要注意。
时间戳 0 是什么时候?
1970-01-01 00:00:00 UTC,也就是北京时间 1970-01-01 08:00:00。看到 0 通常意味着“字段没赋值”或者“初始化默认值”,排查问题时值得留意。
怎么在命令行里拿到当前时间戳?
Linux/macOS:date +%s 得到秒,date +%s%3N 得到毫秒。Python:import time; int(time.time())。JavaScript:Date.now()。
广告位 - 适合横幅广告