📖 推定読了時間:約6分
JavaScriptを触ったことがあるすべてのエンジニアが、人生で一度は叫んだことがあるはずです。「なぜ1月が『0』で、12月が『11』なんだ!?」「なぜ日付を変更しただけで元のオブジェクトまで勝手に書き換わるんだ!?」と。
1995年、Netscapeのブレンダン・アイク氏がわずか10日間でJavaScriptを設計した際、当時のJava 1.0に存在していた悪名高き `java.util.Date` の実装をそのまま突貫工事で移植してしまった――この約30年前に生まれた歴史の負債が、現代に至るまでWebフロントエンド界隈に数え切れないバグと阿鼻叫喚をもたらしてきました。しかし、ついにこの悪夢に終止符が打たれます。TC39によって長年議論が重ねられてきた待望の次世代日時標準仕様「Temporal API」が、主要ブラウザへの実装段階に入りました!
この記事のポイント
- 旧来の `Date` オブジェクトが抱えていた「5大欠陥」の正体
- タイムゾーン・夏時間を完璧に分離するTemporalの画期的な型システム
- Moment.jsやdate-fnsを完全に置き換える、標準仕様の実践コード例
なぜDateは嫌われたのか?呪われし「5大欠陥」
これまでの標準 `Date` は、現代のWebアプリケーションが求める厳格な要件を満たすことが原理的に不可能でした。その主な理由は以下の通りです。
- ❌ミュータブル(破壊的変更)である:`date.setMonth()` などを実行すると、元のオブジェクトの中身が直接書き換わってしまい、思わぬバグを引き起こす。
- ❌月が0始まり(0-indexed):1月が `0`、12月が `11` という直感に反する仕様。一方で日は `1` から始まるため混乱を招く。
- ❌タイムゾーンのサポートが貧弱:ユーザーのローカル時間とUTCの2種類しか扱えず、特定の国(例: ニューヨーク時間)を指定した計算ができない。
- ❌サマータイム(夏時間)の移行に対応できない:夏時間の切り替わり日に「1日加算」すると、25時間や23日のズレが発生して発狂する。
- ❌日付のみ・時刻のみの概念がない:「誕生日(2000-01-01)」を保存したいだけなのに、勝手にミリ秒単位の時刻とタイムゾーンが付加される。
こうした欠陥を埋めるために、フロントエンド開発の現場では Moment.js、Day.js、date-fns といった外部ライブラリの導入が長年必須となっていました。モダンなWeb標準の進化やECMAScriptの最新トレンドを網羅的にキャッチアップしたい方は、JavaScript新仕様実践ガイドブック を手元に置いておくと、言語仕様のアップデートに迷わず追従できます。
Temporal APIの真髄:目的に応じて分かれた「明快な型設計」
Temporal APIの最大の特徴は、「日付」と「時刻」と「タイムゾーン」を明確に切り離した独立したクラス群を提供している点です。
| クラス名 | 保持する情報 | 主なユースケース |
|---|---|---|
| Temporal.PlainDate | 年・月・日(時間なし・タイムゾーンなし) | 生年月日、祝日、イベント開催日など |
| Temporal.PlainTime | 時・分・秒・ミリ秒(日付なし) | 店舗の開店時間、目覚ましアラームなど |
| Temporal.ZonedDateTime | 完全な日時+厳密なタイムゾーン+暦法 | 国際Web会議、航空券予約など |
| Temporal.Duration | 時間の長さ(例: 2時間30分) | 動画の再生時間、タイマー計測など |
すべてのオブジェクトは「完全なイミュータブル(不変)」として設計されているため、加算や減算を行っても常に新しいオブジェクトが返され、元の変数が勝手に破壊される事故は100%防止されます。もちろん、月は「1〜12」の常識的な数値で扱われます!
コードで見る感動的な進化:直感的な日時計算
実際にどれほど直感的になったのか、コードで比較してみましょう。
// 今日から3ヶ月と5日後を計算する
const today = Temporal.Now.plainDateISO();
const targetDate = today.add({ months: 3, days: 5 });
console.log(targetDate.toString()); // 例: "2026-07-22"
// タイムゾーンを指定して別地域の現在時刻を取得する
const tokyoTime = Temporal.Now.zonedDateTimeISO('Asia/Tokyo');
const nyTime = tokyoTime.withTimeZone('America/New_York');
// 2つの日時の差分を美しく求める
const duration = targetDate.since(today);
console.log(`${duration.months}ヶ月と${duration.days}日の差があります`);
ライブラリを何メガバイトもインポートすることなく、ネイティブの構文だけでこれほど流麗かつ型安全に日時操作が完結します。特にTypeScriptと組み合わせた開発では、コンパイル時に日時の型定義ミスを完璧に捕捉できるため開発効率が跳ね上がります。厳格な型安全設計を極めたいエンジニアは、TypeScript関連書籍 で型推論や最新エコシステムのベストプラクティスを押さえておくことを強くおすすめします。
まとめ:外部ライブラリを捨てて標準APIに移行する準備を!
Temporal APIは、JavaScriptコミュニティが数十年にわたって待ち望んでいた最大の救世主です。すでに主要ブラウザ(Chrome, Firefox, Safari)でのフラグ付き実装やポリフィル(`@js-temporal/polyfill`)が広く利用可能となっており、正式な標準サポートも目前に迫っています。
「日時の計算は外部ライブラリに頼るのが当たり前」という時代は、まもなく過去のものになります。これから新規プロジェクトを立ち上げる方や、コードベースのリファクタリングを予定している方は、ぜひこの美しいTemporal APIの導入を検討してみてください!



0 件のコメント:
コメントを投稿