2026 年 5 月 13 日、Publickey が Node.js、Date に代わる日時処理「Temporal」がデフォルト有効化。Temporal は Chrome / Edge / Firefox / Node.js で利用可能に を公開しました。Temporal APIは JavaScript の Date オブジェクトの根本的な後継仕様であり、ようやくランタイムとブラウザの双方でデフォルトになりました。
これまで弊社の受託開発で最頻出のバグは 「タイムゾーンずれ」「閏秒」「DST 切り替え」「Date 比較の罠」でした。これらは JavaScript Date の構造的欠陥であり、moment.js / Day.js / date-fnsを継ぎ足しても本質解決はできません。Temporal API のデフォルト有効化は、Date を業務コードから完全に追放することを 現実的選択肢にした転換点です。
なぜ Date / moment.js では限界なのか
| 課題 | Date / moment.js の状況 |
|---|---|
| タイムゾーン処理 | サーバ / クライアントで挙動が異なる |
| 不変性 | mutable で副作用が発生 |
| 閏秒・DST | 大半のライブラリが手当てしていない |
| TypeScript 親和性 | unknown / any への退化 |
| バンドルサイズ | moment.js は 290KB(gzip 後 70KB) |
| メンテナンス | moment.js は事実上凍結状態 |
これらの問題は **「いつかは直す」で先送りされ、「決済日 1 日ずれ」「請求書月末ずれ」**といった 業務インシデントとして顕在化します。Temporal は 設計レベルでこれらを解消した仕様です。
Temporal API の 5 つの強み
強み 1: 「Instant」と「ZonedDateTime」の明確な分離
「時刻の絶対座標」(Instant)と **「人間が見る時刻」(ZonedDateTime)を 別の型として扱います。「サーバ時刻と表示時刻を混ぜる」**バグが構造的に発生しません。
強み 2: 不変オブジェクト
Date の mutable な setHours / setDateは、副作用バグの温床でした。Temporal は 完全 immutableで、Functionalに時刻を扱えます。
強み 3: タイムゾーン IDs を一級市民として扱う
Asia/Tokyo, America/New_York といった IANA タイムゾーン IDを 型として保持し、DST 計算まで仕様で規定します。
強み 4: 期間(Duration / Period)の演算
「3 ヶ月後の月末営業日」といった 業務カレンダー演算を、標準 APIで表現できます。これは TypeScript 6 移行ガイド で扱った 「型で業務を表現する」潮流の日付版です。
強み 5: ライブラリ追加なし
Temporal は ランタイム / ブラウザ標準のため、外部依存ゼロです。バンドルサイズ削減 / セキュリティ監査範囲の縮小に直結します。
受託で構築する 4 つのモダナイゼーションフェーズ
フェーズ 1: 日付処理の棚卸し(2 週間)
ts-morph / AST 解析で new Date / moment( / dayjs( / date-fnsの使用箇所を全件抽出し、業務インパクトを 3 段階で分類します。
フェーズ 2: ラッパー層の導入(3 週間)
業務全体を Temporal に一気に書き換えるのは現実的でないため、ドメインの境界で Temporal に変換するラッパー層を先に入れます。DB → Temporal、Temporal → API レスポンスの 2 か所だけ最初は触ります。
フェーズ 3: ドメイン層の Temporal 移行(6〜10 週間)
業務ドメインごとに段階移行します。請求 → 売上 → 在庫 → 勤怠の順で 「業務単位でレビューと回帰テスト」を回します。回帰テストには Property-based Testing(fast-check 等)を併用します。
フェーズ 4: moment.js / Day.js / Date 削除(3 週間)
最終フェーズで ESLint の no-restricted-syntaxで new Date / moment( を禁止し、依存を削除します。
受託向け技術スタック標準セット
| レイヤ | 推奨 | 代替 |
|---|---|---|
| 時刻型 | Temporal API(標準) | luxon |
| DB 型変換 | Temporal ↔ ISO 8601 文字列 | Temporal ↔ Date のラッパー |
| API スキーマ | Zod + Temporal カスタム型 | tRPC / OpenAPI |
| テスト | fast-check + vitest | jest + sinon |
| 静的解析 | ESLint no-restricted-globals | typescript-eslint |
| ORM 連携 | Drizzle 用カスタム adapter | Prisma カスタム scalar |
| i18n | Intl.DateTimeFormat(標準) | date-fns/locale |
特に Zod + Temporal カスタム型で API 境界の型安全を確保すると、フロント / バックの時刻ずれバグが コンパイル時に検出できます。
どの案件で刺さるか
| 向く案件 | 効果 |
|---|---|
| 決済 / 請求 / 給与計算 | 月末ずれ / 締日ずれの構造的解消 |
| 予約 / シフト管理 | DST / TZ 跨ぎの正確性 |
| 国際 SaaS | 多言語 i18n の標準化 |
| ログ集計・分析 | Instant 統一で分析の正確性向上 |
| 監査ログ | 改ざん検知時の時刻整合 |
受託契約に書く 5 つの条項
| 条項 | 内容 | 顧客が確認すべきこと |
|---|---|---|
| 対象モジュール範囲 | 移行対象のドメイン | 範囲外モジュールの責任 |
| 互換 API 提供期間 | 旧 API の維持期間 | 移行中の運用負荷 |
| 回帰テスト基準 | 合格率としきい値 | 業務影響の許容範囲 |
| TZ / DST バグの保証 | 既存バグの解消範囲 | 期待値と現状の差分 |
| ESLint ガード | 旧 API 復活防止ルール | レビュー体制 |
価格モデル — Temporal モダナイゼーション受託
| プラン | 金額 | 対象 | 内容 |
|---|---|---|---|
| 診断 | 60 万円〜 | 2 週間 | 棚卸し + 移行コスト試算 |
| Lite | 350 万円〜 | 6 週間 | 1 ドメイン移行 + ラッパー導入 |
| Standard | 1,200 万円〜 | 3 ヶ月 | 全ドメイン段階移行 + 回帰テスト |
| Enterprise | 3,500 万円〜 | 6 ヶ月 | 上記 + 多サービス横断 + 監査対応 |
ハマりやすい 4 つの落とし穴
落とし穴 1: 「一気に書き換える」
業務ドメインを 同時並行で書き換えると、回帰テスト範囲が爆発します。1 ドメインずつしか進めない設計が必須です。
落とし穴 2: DB の型を放置する
DB に TIMESTAMP WITHOUT TIME ZONEで保存されているデータを Temporal に渡すと、「実は UTC ではなく JST だった」事故が発生します。DB 型監査をフェーズ 1 で必須実施します。
落とし穴 3: フロントだけ移行してバックを Date のまま
API レスポンスが Date 由来の文字列だと、Temporal 側で TZ 情報を再構築できないケースがあります。フロント / バック同時移行が必須です。
落とし穴 4: 旧 API を完全削除しない
「いつか戻ってきそう」と旧 API を残すと、3 ヶ月後に新規コードに Date が再侵入します。ESLint ガード + CI チェックを必ず入れます。
まとめ — 「Date 地獄」から「業務型として日時を表現する」へ
Temporal API のデフォルト有効化は、JavaScript の日時処理を 30 年遅れで近代化する転換点です。TZ ずれ / 閏秒 / 月末ずれといった 構造バグを、設計レベルで一掃できる選択肢が、ようやく 標準ランタイムで揃いました。
弊社では 診断 / Lite / Standard / Enterprise の 4 段階で Temporal モダナイゼーション受託パッケージを提供しています。「Date / moment.js を一掃したい」「TZ バグの再発防止を構造化したい」というご相談は お問い合わせフォーム からお気軽にどうぞ。