Temporal API

JavaScript Temporal API:Date のモダンな代替

JavaScript Date は何十年も前から既知の形で壊れています。TC39 Temporal——2025 年初頭から Stage 4 で、モダンなブラウザと Node.js に搭載——は、瞬間、壁時計の日付、ゾーン付き日時をきれいに分離します。本ガイドでは新しい型、それらが Unix タイムスタンプにどう対応するか、そして移行方法を説明します。

ひと目でわかる Temporal vs Date

JavaScript の組み込み Date は何十年もバグの既知の原因でした。可変であり、ローカルタイムゾーンと UTC しか理解せず、月は 0 始まりで、パースは緩く仕様化されています。Temporal は標準化された代替——Stage 4 で ECMAScript 2026 の一部——であり、これらの問題のそれぞれを目的別の不変な型で解決します。下の表は大まかな対比です。本ガイドの残りで型と、それらが Unix タイムスタンプにどう対応するかを扱います。

観点Date(旧)Temporal
可変性可変不変
精度ミリ秒ナノ秒
タイムゾーンローカル + UTC のみ任意の IANA ゾーン(ZonedDateTime)
月のインデックス0 始まり(0 = 1 月)1 始まり(1 = 1 月)
パース寛容、実装依存厳密な ISO 8601 / RFC 9557
瞬間 vs 壁時計1 つの型に混在別々の型

なぜ Temporal があるのか

JavaScript Date は複数の異なる概念を混同しています:正確な瞬間、壁時計の時刻、ゾーン付き日時です。Date にはまた、よく知られたパースの癖、単一のタイムゾーン(ユーザーのもの)、そしてミリ秒精度があります。Temporal は基礎となる概念を別々の型として公開し、ナノ秒精度、任意の IANA タイムゾーン、明示的なカレンダー系をサポートします。

  • 2025 年初頭から Stage 4。最初に Firefox 139 で既定搭載された
  • 現在は Chrome 144+、Firefox 139+、Node.js 26+ で利用可能
  • ポリフィル(@js-temporal/polyfill)はあらゆるモダンな環境で動く
  • Date との共存を前提に設計——相互運用メソッドが双方向に存在する

Temporal の中核となる型

小さな型の集合が日時の問題をきれいにカバーします。各型には正準の文字列形式があります(ISO 8601、ゾーン付き型では RFC 9557 で拡張):

表すもの例の文字列
Temporal.InstantUnix タイムスタンプのような正確な瞬間(ns 精度)2026-01-01T00:00:00Z
Temporal.ZonedDateTime瞬間 + IANA タイムゾーン + カレンダー2026-01-01T09:00:00+09:00[Asia/Tokyo]
Temporal.PlainDateTime日付 + 時刻、タイムゾーンなし2026-01-01T09:00:00
Temporal.PlainDateカレンダー上の日付(例:誕生日)2026-01-01
Temporal.PlainTime壁時計の時刻09:00:00
Temporal.Duration単位を意識した期間P3DT4H10M

Unix タイムスタンプを扱う

Temporal.Instant が Unix タイムスタンプの型です。搭載 API はミリ秒とナノ秒の epoch 変換しか公開しません——以前の fromEpochSeconds と fromEpochMicroseconds メソッドは Stage 4 の前に削除されました——なので Unix 秒は 1000 を掛けて変換します。保存と転送には Instant を、特定のタイムゾーンでの壁時計表示が必要なときは ZonedDateTime を使います。

  • Temporal.Now.instant() — 現在の正確な瞬間
  • Temporal.Instant.fromEpochMilliseconds(Date.now()) — JS のミリ秒タイムスタンプから
  • Temporal.Instant.fromEpochMilliseconds(1700000000 * 1000) — Unix 秒から(× 1000)
  • Temporal.Instant.fromEpochNanoseconds(1700000000000000000n) — ナノ秒から(BigInt)
  • instant.epochMilliseconds と instant.epochNanoseconds — epoch 値を読み戻す
  • instant.toZonedDateTimeISO("America/New_York") — あるゾーンでの壁時計表示

タイムゾーンと DST を正しく扱う

ZonedDateTime は IANA タイムゾーンを持つので、DST 切替、ギャップ時刻、重複時刻はすべて明示的に扱われます。曖昧性解決オプションで曖昧なローカル時刻に対する方針を選べ、正準の文字列形式は RFC 9557(ゾーンを角括弧で付した ISO 8601 タイムスタンプ)です。

  • zdt.timeZoneId — IANA 名(例:America/Los_Angeles)
  • zdt.add({ hours: 1 }) — 壁時計の観点での DST 対応の算術
  • zdt.until(zdt2) — 2 つのゾーン付き日時の間の距離
  • 曖昧性解決オプション:"earlier"、"later"、"compatible"(既定 — ギャップは後、重複は前)、"reject"
  • 往復:instant ↔ ゾーン付き日時は無損失

Date からの移行パターン

最も簡単な移行戦略は、まず境界(入力のパース、出力のフォーマット)で Temporal を導入し、内部ロジックを徐々に移すことです。

  • Date → Instant:Temporal.Instant.fromEpochMilliseconds(date.getTime())
  • Instant → Date:new Date(instant.epochMilliseconds)
  • 新しいコードではどこでも Temporal を優先し、API の縁でのみ Date に変換する
  • date-fns と Luxon はどちらも Temporal 対応のモード/アダプターを持つ
  • JSON:Temporal.Instant.prototype.toJSON は ISO 8601 文字列を返す

ブラウザとランタイムのサポート

Temporal は 2025 年に搭載され、ネイティブサポートは今や広範ですが、まだ普遍的ではありません。古いブラウザや Safari 安定版がまだ使われている間は、ポリフィルが最も安全な道です。

  • Firefox 139+:最初に搭載、既定で有効(2025 年 5 月)
  • Chrome 144+:既定で有効(2026 年 1 月)
  • Node.js 26+:既定で有効(2026 年 5 月)
  • Safari:Technology Preview で利用可能、安定版にはまだ未搭載
  • ポリフィル:@js-temporal/polyfill または temporal-polyfill — 同じ API、あらゆるモダンな環境

関連リファレンス

FAQ

Temporal は Date の代替ですか?
はい——Temporal は新しいコードで Date を完全に置き換えるよう設計されています。Date は後方互換性のため言語に残り、両者は epoch ミリ秒を介して相互運用します。
Unix タイムスタンプを Temporal にどう変換しますか?
Temporal.Instant.fromEpochMilliseconds() を使います。Unix 秒なら 1000 を掛けます:Temporal.Instant.fromEpochMilliseconds(seconds * 1000)。搭載 API には fromEpochMilliseconds と fromEpochNanoseconds しかありません——古い fromEpochSeconds メソッドは Temporal が Stage 4 に達する前に削除されました。
Temporal はナノ秒をサポートしますか?
はい。Temporal.Instant は内部でナノ秒精度を持ち、epochNanoseconds を BigInt として公開します。
今日 Node.js で Temporal を使えますか?
Node.js 26+ では Temporal が既定で有効です。古い Node では @js-temporal/polyfill をインストールします——API の表面は同一です。
どのブラウザが Temporal をサポートしますか?
Firefox 139+(2025 年 5 月)、Chrome 144+(2026 年 1 月)、Node.js 26+(2026 年 5 月)が Temporal を既定で搭載します。Safari は Technology Preview にあります。それより古いものには @js-temporal/polyfill を使います。
Temporal は DST のギャップをどう扱いますか?
ZonedDateTime のコンストラクターと算術は曖昧性解決オプションを受け取ります。"compatible"(既定)はギャップには後の瞬間、重複には前の瞬間を選びます。"reject" はローカル時刻が曖昧ならエラーを投げます。