Upgrade to Pro — share decks privately, control downloads, hide ads and more …

It’s “Time” to use Temporal

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →
Avatar for Saji Saji
March 16, 2026

It’s “Time” to use Temporal

Avatar for Saji

Saji

March 16, 2026

More Decks by Saji

Other Decks in Technology

Transcript

  1. ⚠ 注意 ⚠ • 個人の主張・予測・思想がそれなりに含まれます ◦ みんなの意見もぜひ聞きたい • Temporalの全体像を話すというわけではない ◦

    自分が大事だと思ってるところ(好きな所)をひたすら話す感じです • Temporalの基礎的な話はスキップしてる ◦ ほぼ英語版しかないけどMDNがすごく詳しい(読み物としても👍)
  2. JSのDateがつらいこと • システム以外のタイムゾーン(サマータイム)サポートがない ◦ UTC ↔ システムタイムゾーン しかできない (しかも変換が暗黙的) •

    日時文字列のパース動作の信頼性が低い ◦ 渡す文字列によってタイムゾーン解釈が変わる・そもそも環境差がある • 日付オブジェクトの可変性の問題 ◦ set系のメソッドで書き換えられてしまう • 日時計算が行いづらい ◦ 加減算や比較ですら一旦値を取り出す + Setし直しという工程が発生
  3. Temporalで解決すること • IANAで管理されているタイムゾーン全てに対応 ◦ システムのタイムゾーン以外でも自由に変換できる • パースできる文字列・数値を厳密化 ◦ RFC3339 とその拡張であるIXDTFだけに限定

    • immutableなAPI ◦ 計算後は新しいTemporalのオブジェクトを返す • 基礎的な日時計算メソッドの搭載 ◦ 日時の加減算や比較などは標準で搭載するようになった
  4. 今回のテーマ Temporalで • 変わること / 変わらないこと • Scopeじゃないこと / まだできないこと

    を考えることで Temporal Native 時代の解像度が上がる そこから自ずとどう使っていくべき か、どう移行する かが分かってくる
  5. タイムゾーンのデータはExactTimeとWallClockTime の橋渡しで必要 • 逆にそこの橋渡しをしない場合は必ずしも必要ないなる 暦の指定は WallClockTime を明確化するのに必要 • 暦が確定できないと WallClockTime

    で示しているデータの意味が変わる • 例 : 2026年1月28日 ◦ 中国で使われる旧暦の場合 → 2026年3月16日(グレゴリオ暦) タイムゾーンと暦を指定するところ
  6. Temporalによる整理 WallClockTime vs ExactTime の分離 • WallClockTIme : Teporal.PlainXX という名前のクラス

    • ExactTime : Temporal.Instant これらの2つは Temporal.ZonedDateTimeで橋渡しされ、変換できる
  7. Temporalによる整理 PlainXX という命名のClassたち = WallClock Time • PlainDateTime : 特定の年月日時刻のデータ

    • PlainDate : 時刻のデータを持たない日付だけのデータ • PlainTime : 日付のデータを持たない時刻だけのデータ • PlainMonthDay : 特定の月と日だけのデータ • PlainYearMonth : 特定の月(年と月だけ)のデータ
  8. 型 = 意味 = 振る舞い が違う もちろんデータの型と意味が違うと言うことは • 生えているプロパティ・メソッドも違う ◦

    例 : PlainMonthDay にyearは生えていない • 生成時や変換時の制約も違う ◦ 生成に必要なデータ・補完されるデータもが違う ◦ 変換で求められるデータ・補完されるデータが違う
  9. 日時の扱いを考え直すところから 「日時」と言う安易な一言で本来異なるものを一括りにしてなかったか? • Dateを使ってる限りは「日時? → Dateにしとけ」で済ましていた ◦ (で、痛い目を見ていた ) •

    違うものを一緒にしてたらそりゃうまくいかない この考え方を変えない限りTemporalにする旨みは活かせない • TemporalでどのObject / API を使うべきか選べない
  10. Temporalだと... それぞれ • データベースに保存する更新タイムスタンプ → Instant / Now • 日時入力フォームに入力された日時

    → PlainDateTime • ユーザーの生年月日 → PlainDate • カレンダーで表示してる月 → PlainYearMonth
  11. 入力と保持するデータ ユーザーが入力するのは基本WallClockTime (= PlainXX) 保存する時を考えると... • 一瞬を表しているもの → タイムスタンプで保存したい ◦

    大抵 PlainDateTime → ZonendDateTime → timestampに変換でいける ◦ 逆もまた然り • 特定の一瞬を表してない → 別途違うフォーマットで保存する ◦ PlainDate / PlainYearMonth → 文字列に変換とかが安全そう
  12. よくありそうなデータの変換 ローカルな日時 → タイムスタンプで保存したい const inputDateTime = Temporal.PlainDateTime.from('2026-03-16T10:00:00'); const zonedDateTime

    = inputDateTime.toZonedDateTime('Asia/Tokyo'); const instant = zonedDateTime.toInstant(); console.log(instant.epochMilliseconds); // 1773622800000
  13. よくありそうなデータの変換 タイムスタンプ → ローカルでの解釈 const savedTimestamp = 1773622800000; const instant

    = Temporal.Instant.fromEpochMilliseconds(savedTimestamp); const zonedDateTime = instant.toZonedDateTimeISO('Asia/Tokyo'); const plainDateTime = zonedDateTime.toPlainDateTime();
  14. 特定の一瞬じゃないデータの保存 案 : そのまま toStringした値を保存してしまうのが良い? • 変にInstant化するとタイムゾーンでずれるミスをしたりすることも • どうせTemporal の

    fromメソッドで復元できる const birthday = Temporal.PlainDate.from('1988-09-20'); const dbValue = birthday.toString(); console.log(dbValue); // '1988-09-20' const restored = Temporal.PlainDate.from(dbValue);
  15. 閑話 : 自分のいるチームでは Dateでの値の保存・やり取りを非推奨にしてる (内部的には仕方ないが) 代わりに文字列ベース(+それらを持つObject)のBrandedTypesを導入 • 基本の4つ : UTCISOString

    / DateString / TimeString / LocalDateTimeObject • それぞれ Temporalの Instant / PlainDate / PlainTime / PlainDateTime に対応 常に「この日時データはどれ?」ということを意識させる
  16. Temporalが受け入れる文字列は厳密にRFC3339/IXDTFとその部分文字列だけ • 2026-03-16T19:00:00.00000000+09:00[Asia/Tokyo] Dateのように曖昧なParse挙動はなくなった • Parseできない : “Mon Mar 16

    2026 19:00:00”,“2026/3/16 19:00” 逆にいうとParseの機能は限定的になったとも言える • ややこしいよりは全然いいけど parseはより厳密で限定的に
  17. Temporalの話とはズレるので深入りしないが、日時のformatはとてもややこしい • 日時表記として / 文法的におかしい形にformatできてしまう可能性 • ライブラリでformatPattern文字列の仕様あんまり守れてない問題 • そもそも formatPatternを正しく使うの知識いる問題

    • 参照するデータが現地のユースケースをちゃんと反映できるか問題... ↑ みたいなことを考え出すと本当に面倒なのでIntlで済むならそれが一番 日時のformatって複雑で ...(早口)
  18. メソッドチェーン形式だと大変そう • dateX(date).setYear(2026).toUTCString() date-fns みたいな関数合成パターン + 各関数の引数の型を制限 / 引数から推論 •

    formatUTCISOString(addDays(plainMonthDay,9)) ライブラリの Temporalサポート(想像) PlainMonthDay だったら? TimeZone情報 まだないよ? PlainMonthDayは 渡せないよ!