如何使用 Unix 时间戳转换器
- 粘贴一个 Unix 时间戳。转换器会自动识别它是以秒还是毫秒为单位。
- 查看以 UTC、您的本地时区和 ISO 8601 格式显示的日期。
- 如需反向转换,选择一个日期和时间,然后复制生成的时间戳。
转换在您的浏览器中计算,使用的是您设备的时钟和时区设置;不会向服务器发送或在服务器上存储任何数据。
什么是 Unix 时间戳?
Unix 时间戳(也称为纪元时间或 POSIX 时间)是自 Unix 纪元 1970-01-01T00:00:00Z,即 1970 年 1 月 1 日 UTC 午夜以来经过的秒数。纪元之前的日期用负数表示。
时间戳之所以流行,是因为它只是一个整数,不受时区和夏令时影响,易于比较和排序,存储也很紧凑。转换为本地时间属于显示层面的事,留到最后显示时再处理即可。
1700000000 → 2023-11-14T22:13:20Z
0 → 1970-01-01T00:00:00Z
-86400 → 1969-12-31T00:00:00Z
秒与毫秒
Unix 工具、PHP、Python 的 time.time() 以及大多数数据库使用秒。JavaScript 的 Date.now()、Java 的 System.currentTimeMillis() 以及许多 JSON API 使用毫秒。对于当前的日期,以秒为单位的值有 10 位数字,以毫秒为单位的值有 13 位。把两者搞混是最常见的时间戳错误:
new Date(1700000000) // Tue Jan 20 1970(被当作毫秒!)
new Date(1700000000 * 1000) // Tue Nov 14 2023
闰秒会被忽略
Unix 时间假定每天恰好有 86,400 秒。当 UTC 插入闰秒时,Unix 时间不会计入它,所以时间戳并不等于自 1970 年以来实际经过的国际单位制秒数。对几乎所有应用来说这都无关紧要,而且能让日期运算保持简单。
常见误区
2038 年问题
以有符号 32 位整数存储时间戳的系统最多只能计到 2,147,483,647,即 2038-01-19T03:14:07Z。再过一秒,数值就会溢出并回绕成负数,表示 1901 年 12 月的某个日期。现代操作系统和编程语言都使用 64 位时间,但嵌入式设备、旧的文件格式以及声明为 32 位整数的数据库列仍然存在风险。凡是可能存储未来日期的地方,都请使用 64 位整数或原生的日期/时间类型。
本地时间悄悄混入
解析不带时区的日期字符串(例如 2024-03-10 02:30)时,会使用机器的本地时区,因此在不同服务器上可能得到不同的时间戳,或者在夏令时切换期间得到一个无效的时间。请始终带上时区偏移或 Z。
ISO 8601
在需要人类可读的数据交换时,ISO 8601(及其互联网规范 RFC 3339)是标准格式:2023-11-14T22:13:20Z 或 2023-11-14T23:13:20+01:00。与时间戳一样,UTC 下的 ISO 8601 字符串按纯文本排序也是正确的。
在代码中获取当前时间戳
| 环境 | 自纪元以来的秒数 |
|---|---|
| Shell(Linux、macOS) | date +%s |
| Python | import time; int(time.time()) |
| JavaScript | Math.floor(Date.now() / 1000) |
| PHP | time() |
| MySQL | SELECT UNIX_TIMESTAMP(); |
| PostgreSQL | SELECT EXTRACT(EPOCH FROM now()); |
要在命令行中把时间戳转换回日期,在 Linux(GNU date)上使用 date -u -d @1700000000,在 macOS 上使用 date -u -r 1700000000。
常见问题
Unix 时间戳在每个时区都一样吗?
是的。它计算的是自 UTC 某个固定时刻以来的秒数,所以在任一时刻,它在世界各地都是相同的。只有转换成当地时钟时间时才会有所不同。
如何区分秒和毫秒?
数一数位数。当前日期以秒为单位是 10 位,以毫秒为单位是 13 位。如果得到的“日期”在 1970 年 1 月,通常是把秒值当成了毫秒;如果日期在几万年之后,则正好相反。
2038 年会发生什么?
只有用有符号 32 位整数存储时间的软件会出问题。64 位时间戳在数十亿年内都不会溢出。
Unix 时间戳可以是负数吗?
可以。负值表示 1970 年 1 月 1 日之前的时刻,不过一些较旧的系统和 API 不接受负值。
更新于