什么是 Unix 时间戳(以及开发者为什么要用它)?
Unix 时间戳是一个单一整数:从 1970 年 1 月 1 日 00:00:00 UTC 起经过的秒数。这个时间点被称为 Unix 纪元(Unix epoch),从那时起每一秒都连续计数。
现在此刻的时间戳大概在 1,750,000,000 左右。仅凭这个数字,任何计算机、数据库或 API 都能明确知道你指的是哪个时间点——没有歧义。
为什么是 1970?
Unix 诞生于 20 世纪 60 年代末的贝尔实验室。工程师需要一个固定的时间参考点时,选择了 1970 年 1 月 1 日:新十年的开始,容易理解,而且离当时并不久远,这样在当时存储日期时就不需要为实际用途引入负数。
这是一个务实的选择,而不是基于某种原则。它就这样延续下来。
Unix 时间戳解决了什么问题?
把日期表示成人类可读的字符串,会在每一层都产生歧义:
- 格式分歧:
03/04/25是 3 月 4 日还是 4 月 3 日?是 1925 年还是 2025 年? - 时区混乱:“周五下午 3 点”在伦敦和东京代表的是不同的瞬间
- 地区差异:有的国家写“日-月-年”,有的写“月-日-年”
Unix 时间戳绕开了这些问题。1711929600 无论你在哪、偏好什么格式,都是一个明确的时间点。机器能一致理解;人类再去转换显示即可。
秒、毫秒与微秒
原始的 Unix 时间戳单位是 秒。但不同系统使用不同的分辨率:
| 格式 | 单位 | 示例 |
|---|---|---|
| Unix(POSIX) | 秒 | 1711929600 |
JavaScript Date.now() | 毫秒 | 1711929600000 |
Python time.time() | 秒(浮点) | 1711929600.123 |
| 数据库时间戳 | 常见为微秒 | 1711929600000000 |
这也是跨系统工作时最常见的 bug 来源之一:把 JavaScript 的时间戳直接传给 Python 或 Go 的函数会变成大 1,000 倍。跨系统边界时务必确认分辨率。
读取与写入 Unix 时间戳
在 JavaScript / TypeScript 中
// 当前时间戳(秒)
Math.floor(Date.now() / 1000)
// 当前时间戳(毫秒)
Date.now()
// 时间戳(秒)转 Date 对象
new Date(timestamp * 1000)
// Date 转时间戳(秒)
Math.floor(new Date('2024-04-01').getTime() / 1000)
在 Python 中
import time, datetime
# 当前时间戳(浮点)
time.time()
# 转为 datetime
datetime.datetime.fromtimestamp(1711929600)
# datetime 转时间戳
datetime.datetime(2024, 4, 1).timestamp()
在 SQL(PostgreSQL)中
-- 当前时间戳
EXTRACT(EPOCH FROM NOW())::int
-- 转为 timestamp
TO_TIMESTAMP(1711929600)
时区不会影响时间戳本身
这一点很重要,也经常被误解。
Unix 时间戳始终表示一个 UTC 时刻。你在 显示 时把它转换为本地时区;在 存储 时存 UTC 值。时间戳本身与时区无关。
这意味着:
- 不同时区的两位用户都存储“现在”,得到的时间戳相同
- 显示时,各自会看到本地时间
- 数据库层不需要做偏移调整——只在展示层处理
2038 年问题
如果 Unix 时间戳以 32 位有符号整数存储,最多只能计数到 2,147,483,647 秒——对应 2038 年 1 月 19 日 03:14:07 UTC。超过这一刻,32 位计数会回绕成很大的负数。
仍使用 32 位整数存储时间戳的系统会在那天出问题。大多数现代系统用 64 位整数,把溢出推到约 2920 亿年之后——对现实用途而言可以忽略。
如果你在处理嵌入式系统、遗留数据库或旧的 C 代码,值得检查时间戳的存储方式。
什么时候该用 Unix 时间戳?
适合使用 Unix 时间戳的场景:
- 在数据库中存储日期,并希望用一个简单、可排序的整数表示
- 在系统或 API 之间传递日期
- 按时间顺序比较或排序事件
- 计算持续时间(直接相减两个时间戳)
- 缓存或过期逻辑(
expires_at = now + 3600)
适合使用格式化日期字符串的场景:
- 向用户展示日期
- 记录需要人类可读的日志
- 在表格或 CSV 导出中处理
快速换算
| 内容 | 秒数 |
|---|---|
| 1 分钟 | 60 |
| 1 小时 | 3,600 |
| 1 天 | 86,400 |
| 1 周 | 604,800 |
| 30 天 | 2,592,000 |
| 1 年(约) | 31,536,000 |
Unix 时间戳转换器 可以把任意时间戳转换成可读日期,或把日期即时转换成 Unix 时间戳。


