Timestamps in JavaScript

在 JavaScript 中处理 Unix 时间戳

在 JavaScript 中处理 Unix 时间戳所需的一切 —— 获取当前时间、从时间戳创建 Date、为任意时区格式化、避免常见错误 —— 附一份可复制粘贴的速查表和深入指南的链接。

JavaScript 时间戳速查表

JavaScript 以毫秒工作:Date.now() 和 Date 构造函数都使用自 Unix 纪元起的毫秒,而其他大多数系统使用秒 —— 所以几乎每个 JavaScript 时间戳任务都归结为记住一个 × 1000 或 ÷ 1000。下表是快速参考;其后的各节解释每个操作,深入指南则完整讲解时区和 Temporal API。

任务代码结果
当前时间(毫秒)Date.now()1700000000000
当前时间(秒)Math.floor(Date.now() / 1000)1700000000
秒 → Datenew Date(s * 1000)Date 对象
毫秒 → Datenew Date(ms)Date 对象
Date → 毫秒date.getTime()1700000000000
Date → ISO 8601date.toISOString()2023-11-15T06:13:20.000Z
ISO 字符串 → 毫秒Date.parse(str)1700000000000

获取当前 Unix 时间戳

JavaScript 提供了几种等价的方式把当前时间获取为数字时间戳。它们都返回自 Unix 纪元起的毫秒数。

  • Date.now() → 最快也最易读 —— 1700000000000(毫秒)
  • Math.floor(Date.now() / 1000) → 秒级 Unix 时间戳 —— 1700000000
  • +new Date() → 与 Date.now() 相同,使用一元加运算符
  • new Date().getTime() → 显式方法调用,结果与 Date.now() 相同

从 Unix 时间戳创建 Date 对象

Date 构造函数接受自纪元起的毫秒。把秒级时间戳传给构造函数之前,务必先乘以 1000。

  • new Date(1700000000 * 1000) → 从秒(最常见的情形)
  • new Date(1700000000000) → 从毫秒(JavaScript 的 API、Java)
  • new Date(Date.now()) → 当前时间作为 Date 对象
  • new Date(0) → Unix 纪元:1970 年 1 月 1 日 00:00:00 UTC

格式化日期 —— 内置字符串方法

Date 对象有几个内置的字符串转换方法。每个都生成不同的格式。

  • .toISOString() → '2023-11-15T06:13:20.000Z' — ISO 8601,始终 UTC,机器可读
  • .toUTCString() → 'Wed, 15 Nov 2023 06:13:20 GMT' — RFC 7231,人类可读的 UTC
  • .toString() → 带完整时区名的本地时区字符串
  • .toLocaleString() → 在用户本地时区下感知区域设置的格式

感知时区的格式化

对于感知时区的格式化,用带显式 timeZone 的 Intl.DateTimeFormat —— 它会自动应用 DST,且不需要库。时区本身就是一个深入的主题;专门的 JavaScript 时区指南讲解 formatToParts、检测用户时区,以及困难的挂钟→UTC 方向。

  • new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'long' }).format(date)
  • date.toLocaleString('en-GB', { timeZone: 'Europe/London', hour12: false })

把日期字符串转换回 Unix 时间戳

要走相反方向 —— 从日期字符串到 Unix 时间戳 —— 用 Date.parse(),或把字符串传给 Date 构造函数。

  • new Date('2023-11-15T06:13:20Z').getTime() / 1000 → 从 ISO 8601 UTC 得到 Unix 秒
  • new Date('2023-11-15T01:13:20-05:00').getTime() → 从带偏移的 ISO 得到 Unix 毫秒
  • Date.parse('2023-11-15T06:13:20Z') → 与 new Date(...).getTime() 相同
  • 为了可预测的解析,始终使用带显式时区的 ISO 8601 格式

常见陷阱

这些是 JavaScript 开发者在日期和时间戳上最常犯的错误:

  • new Date(1700000000) —— 缺少 × 1000 会转换到约 1970 年而非 2023 年
  • getMonth() 返回 0–11 而非 1–12 —— 显示时务必加 1
  • new Date('2024-01-01') 是 UTC 午夜;new Date('2024/01/01') 是本地午夜
  • new Date(2024, 0, 1) = 1 月 1 日(构造函数里月份也是从 0 开始)
  • 用加 86400000 毫秒来得到“明天”可能在 DST 边界失败 —— 改用 setDate(d.getDate() + 1)

Temporal API —— Date 的现代替代

TC39 的 Temporal API 已达到 Stage 4,并在现代浏览器和 Node.js 中发布。它修复了 Date 的核心缺陷 —— 不可变、纳秒精度、感知时区 —— 而 Temporal.Instant 就是它的 Unix 时间戳类型。发布的 API 以毫秒或纳秒转换纪元(较旧的 fromEpochSeconds 已被移除),所以把 Unix 秒乘以 1000。完整 API 见 Temporal 完整指南。

  • Temporal.Now.instant() —— 纳秒精度的当前瞬间
  • Temporal.Instant.fromEpochMilliseconds(Date.now()) —— 从 JS 毫秒时间戳
  • Temporal.Instant.fromEpochMilliseconds(1700000000 * 1000) —— 从 Unix 秒(× 1000)
  • Temporal.ZonedDateTime —— 瞬间 + IANA 时区,Date 本该是的类型
  • 已在 Firefox 139+、Chrome 144+、Node.js 26+ 发布;Safari 在 Technology Preview;其余用 polyfill

进一步阅读

FAQ

在 JavaScript 中如何获取秒级 Unix 时间戳?
用 Math.floor(Date.now() / 1000)。Date.now() 返回毫秒,所以除以 1000 再向下取整即可得到整数 Unix 秒。
在 JavaScript 中如何把 Unix 时间戳转换为可读日期?
把秒乘以 1000,传给 Date 构造函数,再格式化:new Date(1700000000 * 1000).toISOString() 得到 "2023-11-14T22:13:20.000Z"。对于特定时区,用带 timeZone 选项的 Intl.DateTimeFormat。
为什么用 Unix 时间戳调用 new Date() 会显示 1970?
Date 构造函数期望毫秒。10 位的秒级时间戳必须乘以 1000:new Date(seconds * 1000)。
如何为特定时区格式化 JavaScript 日期?
用带显式 timeZone 选项的 Intl.DateTimeFormat,例如 new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York' })。它会自动应用夏令时,且不需要外部库。
我该用 Date 还是 Temporal?
对于运行时支持的新代码,优先用 Temporal —— 它不可变、感知时区,并能避开 Date 的坑。Date 对简单的 epoch 毫秒工作仍然没问题,而且依旧是支持最广的。