🕐
← 返回教程列表

什么是 Unix 时间戳?完整指南

· 标签: unix-timestamp, epoch, linux-time, 2038-problem, utc, time-conversion

什么是 Unix 时间戳?

Unix 时间戳(也称为 POSIX 时间或 Epoch 时间)是一种跟踪时间的系统,它计算自 Unix epoch——1970 年 1 月 1 日 00:00:00 UTC——以来经过的秒数,不包含闰秒。

与因时区而异的人类可读日期(如 "July 19, 2026, 3:30 PM EST")不同,Unix 时间戳是一个单独的整数,在地球上的任何地方都代表同一个时刻。例如,时间戳 1785292800 对应一个特定的瞬间,无论你是在纽约、伦敦还是东京。

Unix 时间戳是现代计算中时间处理的支柱。操作系统、编程语言、数据库和文件系统在底层都依赖这种简单的整数表示。

Unix epoch:为什么是 1970 年 1 月 1 日?

选择 1970 年 1 月 1 日作为 "epoch"(起始点)并非随意之举。这一决定源于几个实际考虑:

  • 早期 Unix 开发:Unix 操作系统诞生于 20 世纪 60 年代末和 70 年代初的贝尔实验室。到 70 年代初时间系统被标准化时,1970 年 1 月 1 日是一个干净、近期的参考点。
  • 简单性:早期 Unix 系统上的时间以 32 位有符号整数按秒存储。使用较近的日期可以最大限度地扩大面向未来的可表示范围。
  • 先例:epoch 在第一个 POSIX 标准中被正式确定,使其成为所有 Unix 衍生系统的通用参照。

早期的类 Unix 系统曾使用过不同的 epoch 日期,但 1970 年 epoch 最终胜出,并从此成为所有符合 POSIX 标准的系统的标准。

时间戳值是如何运作的

核心思想很简单:

  • 时间戳 0 恰好表示 1970 年 1 月 1 日 00:00:00 UTC
  • 时间戳 86400(60 × 60 × 24)表示 1970 年 1 月 2 日 00:00:00 UTC
  • 时间戳 -3600 表示 1969 年 12 月 31 日 23:00:00 UTC(负数时间戳表示 epoch 之前的日期)

公式很简单:

timestamp = seconds since 1970-01-01 00:00:00 UTC

毫秒级时间戳

许多现代系统,尤其是 JavaScript 和 Web API,使用毫秒而不是秒。毫秒级时间戳只是将秒级值乘以 1000:

  • JavaScript Date.now() 返回毫秒
  • Python time.time() 返回带毫秒小数部分的浮点秒数

在转换之前,务必确认系统使用哪种分辨率,因为混用可能导致日期相差数十年。

2038 年问题

2038 年问题(也称为 "Unix 千年虫" 或 "Y2K38")是一个影响以 32 位有符号整数存储时间戳的系统的日期表示问题。

32 位有符号整数可以容纳约 -21 亿到 +21 亿之间的值。可表示的最大 Unix 时间戳是 2147483647,对应:

  • 2038 年 1 月 19 日 03:14:07 UTC

一秒钟后,该值会溢出为 -2147483648,表示 1901 年 12 月 13 日——导致系统将当前时间解释为 20 世纪初的日期。

哪些系统会受影响?

  • 采用 32 位处理器的嵌入式设备和 IoT 硬件
  • 较旧的嵌入式 Linux 内核
  • 使用 32 位整数时间列的旧版数据库
  • 以 32 位整数存储时间的文件系统和二进制格式

解决方案

现代系统大多已过渡到使用 64 位整数 进行时间存储。64 位有符号整数可以表示从现在起约 2920 亿年 之后的时间——对任何实际用途来说都几乎是无限的。

  • 64 位硬件上的大多数现代 Linux 发行版已经安全
  • Linux 内核多年来一直在 64 位系统上使用 64 位 time_t
  • 内核 5.6+ 为 32 位架构引入了 64 位 time_t 支持
  • Python、Go 和 Java 等编程语言在内部使用 64 位整数

如果你维护嵌入式系统或旧版软件,今天就检查一下你的 time_t 大小是值得的。

UTC 及其与 Unix 时间戳的关系

Unix 时间戳本质上是与时区无关的——它们始终指向 UTC。

什么是 UTC?

协调世界时(UTC)是全球用于调节时钟和时间的主要时间标准。它取代了格林尼治标准时间(GMT)成为国际标准,并由原子钟维护。

为什么 UTC 对 Unix 时间戳很重要

  • Unix 时间戳以 UTC 定义,因此一个时间戳在全球代表同一个时刻
  • 将 Unix 时间戳转换为本地时间纯粹是显示层的事
  • 时间戳本身不存储任何时区信息,这使得系统简单且可移植

这种设计意味着你可以与世界上任何人共享一个 Unix 时间戳,双方都可以毫无歧义地将其转换为自己的本地时间。

闰秒:罕见的例外

Unix 时间戳理论上计算自 epoch 以来的秒数,但它们忽略闰秒。即使一天增加了一秒闰秒,在 Unix 时间中仍然是恰好 86400 秒。这意味着在闰秒期间,Unix 时间戳不会前进,闰秒实际上从计数中消失了。

这种简化使系统保持实用,但也意味着 Unix 时间戳与原子时存在轻微偏差。这种偏差很小,对于日常应用几乎无关紧要。

常见时间戳范围

| 时间戳 | 人类可读日期 | 含义 | |-----------|---------------------|--------------| | 0 | 1970-01-01 00:00:00 UTC | Unix epoch | | 86400 | 1970-01-02 00:00:00 UTC | epoch 之后一天 | | 946684800 | 2000-01-01 00:00:00 UTC | 2000 年 | | 1234567890 | 2009-02-13 23:31:30 UTC | 一个容易记住的模式 | | 1785292800 | 2026-07-19 00:00:00 UTC | 今天的 epoch | | 2147483647 | 2038-01-19 03:14:07 UTC | 32 位最大值 |

总结

Unix 时间戳是一种优雅、可移植的方式,用单个整数表示时间。它的设计——从 1970 年 1 月 1 日 UTC 起计秒——使其成为操作系统、数据库和编程语言之间的通用时间标准。虽然 2038 年问题对旧版系统依然构成威胁,但向 64 位时间的持续过渡确保 Unix 时间戳将在未来几代人中继续作为计算计时的基石。

准备好使用 Unix 时间戳了吗?使用我们的 Unix 时间戳转换器 在时间戳和人类可读日期之间即时转换。