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 毫秒工作仍然沒問題,而且依舊是支援最廣的。