Timestamp Formats

Unix 时间戳格式详解

一份所有 Unix 时间戳格式的完整参考 —— 秒、毫秒、微秒、ISO 8601 和 RFC 2822 —— 配有示例显示每种语言和数据库使用哪种格式,以及如何一眼区分它们。

一眼看尽每种 Unix 时间戳格式

Unix 时间戳只是一个数字,而它的格式其实只是它的单位 —— 它从 1970 年 1 月 1 日 UTC 起数得有多细。单位几乎总能从位数读出:10 位是秒,13 是毫秒,16 是微秒,19 是纳秒。两种字符串格式 ISO 8601 和 RFC 2822 则是自描述的。下表是全貌;其后的各节讲解每种格式以及如何区分它们。

格式位数示例使用者
101700000000Python, PHP, Go, Ruby, C, SQL
毫秒131700000000000JavaScript, Java, .NET
微秒161700000000000000PostgreSQL, Rust
纳秒191700000000000000000Go UnixNano, 追踪系统
ISO 8601字符串2023-11-15T06:13:20ZAPI、日志(自描述)
RFC 2822字符串Wed, 15 Nov 2023 06:13:20 GMT邮件、HTTP 头

秒级 Unix 时间 —— 通用格式

最常见的格式:一个 32 位或 64 位整数,计自 1970 年 1 月 1 日 00:00:00 UTC 起的整秒数。当前是约 17 亿的 10 位数字。

  • 示例:1700000000 = 2023-11-15 06:13:20 UTC
  • 使用者:Python time.time(), PHP time(), Go time.Now().Unix(), Ruby Time.now.to_i, C time(NULL)
  • 存储为:32 位 int(旧式,最大年份 2038)、64 位 int(现代,数十亿年内安全)
  • 数据库:MySQL UNIX_TIMESTAMP(), PostgreSQL EXTRACT(EPOCH FROM NOW())::BIGINT

毫秒级 Unix 时间 —— JavaScript 的格式

自 Unix 纪元起的毫秒:一个提供毫秒精度的 13 位整数。这是 JavaScript 的 Date 对象内部使用的格式。

  • 示例:1700000000000 = 2023-11-15 06:13:20.000 UTC
  • 使用者:JavaScript Date.now(), Java System.currentTimeMillis(), .NET DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
  • 转换为秒:Math.floor(ms / 1000)
  • 从秒转换:seconds * 1000

ISO 8601 —— 可读的标准

ISO 8601 是把日期和时间表示为字符串的国际标准。与 Unix 时间戳不同,它是自描述的:格式同时编码了日期/时间和时区偏移。

  • 2023-11-15T06:13:20Z —— UTC(Z 后缀表示 UTC)
  • 2023-11-15T01:13:20-05:00 —— 带显式 UTC 偏移(EST)
  • 2023-11-15T06:13:20.000Z —— 带毫秒
  • JavaScript:date.toISOString() 总是返回带 Z 后缀的 UTC
  • Python:datetime.isoformat(),Go:time.Format(time.RFC3339)

RFC 2822 —— 邮件与 HTTP 日期格式

RFC 2822(邮件由 RFC 5322 更新,HTTP 由 RFC 9110 沿用)是邮件头和 HTTP 响应中使用的可读日期格式。JavaScript 的 Date.toUTCString() 返回这种格式。

  • 示例:Wed, 15 Nov 2023 06:13:20 GMT
  • 用于:HTTP 响应头(Last-Modified, Date, Expires)、邮件头(Date:)
  • JavaScript:date.toUTCString()
  • 在现代 API 中较少见,但在 Web 基础设施中仍广泛遇到

如何检测时间戳格式

当你收到一个未知的时间戳值时,这些规则能识别它的格式。位数决定每一种数值情形;两种字符串格式一看便知。

线索格式
10 位Unix 秒
13 位Unix 毫秒
16 位微秒
19 位纳秒
含 T 或 ZISO 8601
逗号或星期名RFC 2822
负整数1970 年之前的秒或毫秒
  • 常识检查:任何数值都应解码为当前时代的可信日期(10 位秒大致是 2001—2038 年)
  • 靠近 1970 年或数千年之外的日期意味着单位读错了

微秒与纳秒

一些高精度系统使用比毫秒更小的单位。它们在应用层代码中很少见,但出现在底层系统、数据库内部和可观测性工具里。

  • 微秒(µs):16 位整数 —— Rust SystemTime as_micros(), PostgreSQL clock_gettime()
  • 纳秒(ns):19 位整数 —— Go time.Now().UnixNano(), Rust SystemTime as_nanos()
  • PostgreSQL EXTRACT(EPOCH) 返回一个以微秒为小数部分的浮点数
  • 把纳秒转换为秒:除以 1,000,000,000(1e9)

分辨率与亚秒精度

上面每种格式承载不同的时间分辨率。选择一种格式就是选择你能多精细地区分两个时刻 —— 从一秒到一纳秒。

  • 1 秒分辨率:Unix 秒(10 位)、传统 POSIX time_t
  • 1 毫秒:JavaScript Date, MongoDB BSON Date, Java Instant.toEpochMilli()
  • 1 微秒:Chrome/WebKit 时间戳, Python datetime.timestamp(), PostgreSQL timestamp precision 6
  • 100 纳秒:Windows FILETIME, .NET DateTime.Ticks
  • 1 纳秒:Java Instant(完整精度), Go time.UnixNano(), JS Temporal.Instant.epochNanoseconds(BigInt)
  • 皮秒及以下:PTP/IEEE 1588 线缆格式(一秒的 1/2^32)、NTP 小数字段
  • 选择满足你需求的最粗分辨率 —— 亚秒精度常在 JSON 序列化或字符串往返时丢失
  • 在格式间转换时,经由 Unix 毫秒或纳秒(通过 BigInt)—— 那是保留精度的最小公分母

时间戳格式转换器

在 Unix 时间与你在实践中遇到的平台专用时间戳格式之间转换:

FAQ

Unix 时间戳是多少位?
现代的秒级 Unix 时间戳是 10 位(约 17 亿);毫秒级是 13 位。微秒是 16 位,纳秒是 19 位。
JavaScript 使用哪种时间戳格式?
JavaScript 的 Date 以毫秒工作 —— Date.now() 返回一个 13 位的毫秒时间戳,new Date(ms) 期望毫秒。把 Unix 秒乘以 1000 再传给 Date。
Unix 时间和 ISO 8601 有什么区别?
Unix 时间是自 1970 年 UTC 起的单个秒数或毫秒数,不带时区。ISO 8601 是一个自描述字符串,如 2023-11-15T06:13:20Z,它编码了日期、时间和偏移。
RFC 2822 日期格式是什么?
RFC 2822(由 RFC 5322 更新)是邮件和 HTTP 头中使用的可读日期格式,如 "Wed, 15 Nov 2023 06:13:20 GMT"。JavaScript 用 date.toUTCString() 生成它。
我怎么检测一个时间戳是秒还是毫秒?
数位数:10 位的值是秒,13 位的值是毫秒。如果一个值转换出靠近 1970 年或远在未来的日期,就是单位读错了。