この記事で解決すること

「Temporal APIって何?Dateオブジェクトと何が違うの?」

2026年5月7日、Node.js 26.0.0がリリースされました。最大の目玉はTemporal APIがデフォルトで有効になったことです。この記事では、Temporal APIの基本と従来のDateオブジェクトとの違いを解説していきます。

Node.js 26の主な変更点

Node.js 26.0.0は2026年5月7日にリリースされたメジャーバージョンです。Current版としてリリースされ、今後LTS(長期サポート版)への昇格が予定されています。

アップデートの概要

主な変更点をまとめます。

項目内容
Temporal APIデフォルトで有効(フラグ不要)
V8エンジン14.6に更新
Undici8.0に更新
レガシーコード大幅に削除(破壊的変更あり)

Node.js 20からの移行を検討している方はNode.js 20のサポート終了と移行手順もあわせて確認してください。

V8エンジン14.6の恩恵

V8エンジンが14.6に更新されたことで、JavaScriptの実行パフォーマンスが向上しています。Temporal APIのネイティブサポートもこのV8更新によるものです。

Temporal APIとは

Temporal APIは、JavaScriptの新しい日付・時刻APIです。ES2026仕様に正式採用されました(2026年3月にStage 4到達)。従来のDateオブジェクトが抱えていた問題を根本から解決するために設計されています。

Dateオブジェクトの問題点

従来のDateオブジェクトには、初心者がつまずきやすい問題がいくつもあります。

// Dateオブジェクトの問題点

// 問題1: 月が0始まり(1月が0、12月が11)
const date = new Date(2026, 0, 1); // これは1月1日
console.log(date.getMonth()); // 0 ← 直感的でない

// 問題2: ミュータブル(元のオブジェクトが変わってしまう)
const original = new Date(2026, 4, 7);
const copy = original;
copy.setDate(10);
console.log(original.getDate()); // 10 ← originalも変わってしまう!

// 問題3: タイムゾーンの扱いが曖昧
const now = new Date();
// ローカルタイムゾーンに依存し、明示的な指定が難しい

これらの問題は、バグの原因になりやすいものでした。

Temporal APIの特徴

Temporal APIは以下の3つの特徴で、Dateの問題を解決します。

  • イミュータブル(不変): 一度作った値は変更されない。新しい値を返す
  • 明示的なタイムゾーン: タイムゾーンを必ず指定する設計
  • 直感的なAPI: 月は1始まり、メソッド名が分かりやすい

Temporal APIの基本的な使い方

Node.js 26では、フラグなしでTemporal APIを使えます。以前のバージョンでは --experimental-temporal フラグが必要でしたが、もう不要です。

今日の日付を取得する

// 今日の日付を取得(ローカルタイムゾーン)
const today = Temporal.Now.plainDateISO();
console.log(today.toString()); // "2026-05-08"

// 年・月・日を個別に取得
console.log(today.year);  // 2026
console.log(today.month); // 5 ← 直感的!(Dateだと4になる)
console.log(today.day);   // 8

Dateオブジェクトと違い、月が1始まりです。5月なら 5 が返ります。

特定の日付を作成する

// 文字列から日付を作成
const releaseDate = Temporal.PlainDate.from("2026-05-07");
console.log(releaseDate.toString()); // "2026-05-07"

// オブジェクトから日付を作成
const newYear = Temporal.PlainDate.from({
  year: 2027,
  month: 1,
  day: 1
});
console.log(newYear.toString()); // "2027-01-01"

// イミュータブルなので、元の値は変わらない
const nextDay = releaseDate.add({ days: 1 });
console.log(releaseDate.toString()); // "2026-05-07" ← 変わらない
console.log(nextDay.toString());     // "2026-05-08"

日付の差分(Duration)を計算する

// 2つの日付の差分を計算
const start = Temporal.PlainDate.from("2026-01-01");
const end = Temporal.PlainDate.from("2026-05-07");

const duration = start.until(end);
console.log(duration.toString()); // "P126D"(126日間)
console.log(duration.days);       // 126

// 月単位で差分を取得
const durationInMonths = start.until(end, { largestUnit: "month" });
console.log(durationInMonths.months); // 4
console.log(durationInMonths.days);   // 6
// → 4ヶ月と6日

// 日付に期間を加算
const deadline = Temporal.PlainDate.from("2026-05-08");
const extended = deadline.add({ weeks: 2, days: 3 });
console.log(extended.toString()); // "2026-05-25"

非同期処理と組み合わせてAPIからデータを取得する場面も多いでしょう。JavaScriptのasync/awaitの解説記事も参考になります。

タイムゾーンを扱う

// タイムゾーン付きの日時を作成
const tokyoNow = Temporal.Now.zonedDateTimeISO("Asia/Tokyo");
console.log(tokyoNow.toString());
// "2026-05-08T15:30:00+09:00[Asia/Tokyo]"

// ニューヨーク時間に変換
const nyTime = tokyoNow.withTimeZone("America/New_York");
console.log(nyTime.toString());
// "2026-05-08T02:30:00-04:00[America/New_York]"

// タイムゾーンの差を明示的に確認できる
console.log(tokyoNow.hoursInDay); // 24(通常の日)

タイムゾーンが明示的に指定されるため、「ローカル時間なのかUTCなのか分からない」という問題が起きません。

実践例:Temporal APIの活用シーン

1. イベントのカウントダウン

// イベントまでの残り日数を計算
const today = Temporal.Now.plainDateISO();
const event = Temporal.PlainDate.from("2026-12-25");

const remaining = today.until(event);
console.log(`クリスマスまであと${remaining.days}日`);

2. 営業日の計算

// 5営業日後を計算する関数
function addBusinessDays(startDate, days) {
  let current = startDate;
  let added = 0;

  while (added < days) {
    current = current.add({ days: 1 });
    // 土日を除外(6=土曜、7=日曜)
    if (current.dayOfWeek <= 5) {
      added++;
    }
  }
  return current;
}

const today = Temporal.PlainDate.from("2026-05-08");
const deliveryDate = addBusinessDays(today, 5);
console.log(deliveryDate.toString()); // "2026-05-15"(土日を除いた5日後)

3. 複数タイムゾーンの会議時間表示

// 会議時間を複数タイムゾーンで表示
const meetingTime = Temporal.ZonedDateTime.from({
  year: 2026,
  month: 5,
  day: 10,
  hour: 10,
  minute: 0,
  timeZone: "America/New_York"
});

const zones = ["Asia/Tokyo", "Europe/London", "America/Los_Angeles"];

zones.forEach(zone => {
  const local = meetingTime.withTimeZone(zone);
  console.log(`${zone}: ${local.hour}:${String(local.minute).padStart(2, "0")}`);
});
// Asia/Tokyo: 23:00
// Europe/London: 15:00
// America/Los_Angeles: 7:00

環境変数でタイムゾーンを管理する場合は環境変数の基本と設定方法を参考にしてください。

注意点・破壊的変更

Node.js 26にはいくつかの破壊的変更があります。アップデート前に確認しておきましょう。

レガシーコードパスの削除

Node.js 26では、非推奨だったレガシーコードパスが大幅に削除されています。古いAPIを使っているプロジェクトでは、エラーが発生する可能性があります。

// 削除された古いAPIの例(Node.js 26では動かない)
// util.pump() → stream.pipeline() を使う
// sys モジュール → util モジュールを使う

Undici 8.0の影響

HTTP クライアントライブラリのUndiciが8.0にメジャーアップデートされました。fetch() の内部実装に影響するため、一部のHTTPリクエストの挙動が変わる可能性があります。

移行時のチェックリスト

  1. node -v でバージョンを確認
  2. npm install で依存パッケージを再インストール
  3. テストを実行して動作確認
  4. 非推奨APIの警告が出ていないか確認
  5. CI/CDのNode.jsバージョンを更新

パッケージ管理の基本はnpm/yarnの違いと使い方で解説しています。

DateオブジェクトからTemporalへの移行

既存のコードをすぐにすべて書き換える必要はありません。新しいコードからTemporalを使い始めるのがおすすめです。

移行の目安

場面推奨
新規プロジェクトTemporal APIを使う
既存プロジェクト(小規模)段階的にTemporalへ移行
既存プロジェクト(大規模)新機能からTemporalを使う
ライブラリ開発当面はDateとの互換性を維持

DateとTemporalの相互変換

// Date → Temporal
const legacyDate = new Date("2026-05-07T00:00:00Z");
const instant = Temporal.Instant.fromEpochMilliseconds(legacyDate.getTime());
const zonedDateTime = instant.toZonedDateTimeISO("Asia/Tokyo");
console.log(zonedDateTime.toString());

// Temporal → Date
const temporal = Temporal.Now.instant();
const dateObj = new Date(temporal.epochMilliseconds);
console.log(dateObj.toISOString());

よくある質問(FAQ)

Q: Temporal APIはNode.js 26以外でも使えますか?

A: ブラウザではまだ実装が進行中です。ChromeやFirefoxで段階的にサポートが追加されています。Node.js 26が最初にデフォルト有効にした主要ランタイムです。ブラウザで使いたい場合は @js-temporal/polyfill パッケージが利用できます。

Q: moment.jsやday.jsはもう不要ですか?

A: Temporal APIが標準で使えるようになったため、新規プロジェクトではサードパーティライブラリなしで日付操作ができます。ただし、既存プロジェクトで使っているライブラリを急いで置き換える必要はありません。

Q: Temporal APIの学習コストは高いですか?

A: Dateオブジェクトよりも直感的に設計されているため、むしろ学びやすいです。月が1始まり、イミュータブル、メソッド名が明確など、初心者にも分かりやすい設計になっています。

Q: Node.js 26はすぐに本番環境で使えますか?

A: Node.js 26はCurrent版(最新版)としてリリースされています。本番環境ではLTS版が推奨されるため、LTSに昇格するまで待つのが安全です。開発環境やサイドプロジェクトで試すのがおすすめです。

Q: Temporal APIでDate.now()の代わりは何ですか?

A: Temporal.Now.instant() が現在時刻のInstant(瞬間)を返します。ミリ秒のタイムスタンプが欲しい場合は Temporal.Now.instant().epochMilliseconds を使います。

まとめ

  • Node.js 26.0.0が2026年5月7日にリリースされた
  • Temporal APIがデフォルトで有効に(フラグ不要)
  • Temporal APIはDateオブジェクトの問題(ミュータブル、月0始まり、タイムゾーン曖昧)を解決
  • V8エンジン14.6、Undici 8.0への更新も含まれる
  • レガシーコードパスの削除による破壊的変更あり
  • 新規コードからTemporalを使い始めるのがおすすめ

ターミナル操作を効率化したい方はターミナルのエイリアス設定も参考にしてください。


あわせて読みたい

関連リソース

JavaScriptをもっと深く学びたい方へ: