Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
It’s “Time” to use Temporal
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Saji
March 16, 2026
Technology
1
120
It’s “Time” to use Temporal
#temporal_study
-
https://web-study.connpass.com/event/383606/
X
-
https://twitter.com/sajikix
Saji
March 16, 2026
Tweet
Share
More Decks by Saji
See All by Saji
ユーザーが作成したコードをブラウザ上で安全に実行できる Plugin システムへのアプローチ
sajikix
1
560
Branded Typesで日時の複雑さと戦う
sajikix
4
1.1k
推しProposalと広がる夢~Intl.MessageFormatとDomLocalization~
sajikix
1
570
自作JSエンジンに推しプロポーザルを実装したい!
sajikix
1
310
Lookback TypeScript ESM support and what should we do now.
sajikix
5
770
フロントエンドで日時処理と戦うために 2025 ver
sajikix
6
4.6k
先取り!Temporal
sajikix
0
280
アプリ文言のパースで学ぶ 文字列Literal型パズル入門
sajikix
3
1.2k
The Future of Frontend i18n : Intl.MessageFormat
sajikix
1
4.2k
Other Decks in Technology
See All in Technology
[JAWS DAYS 2026]私の AWS DevOps Agent 推しポイント
furuton
0
150
Agent ServerはWeb Serverではない。ADKで考えるAgentOps
akiratameto
0
100
[E2]CCoEはAI指揮官へ。Bedrock×MCPで構築するコスト・セキュリティ自律運用基盤
taku1418
0
160
Evolution of Claude Code & How to use features
oikon48
1
600
Oracle Cloud Infrastructure IaaS 新機能アップデート 2025/12 - 2026/2
oracle4engineer
PRO
0
130
実践 Datadog MCP Server
nulabinc
PRO
2
190
Claude Codeの進化と各機能の活かし方
oikon48
22
13k
ナレッジワーク IT情報系キャリア研究セッション資料(情報処理学会 第88回全国大会 )
kworkdev
PRO
0
190
スクリプトの先へ!AIエージェントと組み合わせる モバイルE2Eテスト
error96num
0
170
わたしがセキュアにAWSを使えるわけないじゃん、ムリムリ!(※ムリじゃなかった!?)
cmusudakeisuke
1
730
会社紹介資料 / Sansan Company Profile
sansan33
PRO
16
410k
今のWordPress の制作手法ってなにがあんねん?(改) / What’s the Deal with WordPress Development These Days?
tbshiki
0
450
Featured
See All Featured
Done Done
chrislema
186
16k
The SEO Collaboration Effect
kristinabergwall1
0
390
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
60
42k
The Pragmatic Product Professional
lauravandoore
37
7.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.8k
Code Reviewing Like a Champion
maltzj
528
40k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.8k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
140
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
110
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
100
Transcript
It’s “Time” to use Temporal #temporal_study Saji (Ryusei Sajiki) /
@sajikix
Congrats for Stage4 🎉
⚠ 注意 ⚠ • 個人の主張・予測・思想がそれなりに含まれます ◦ みんなの意見もぜひ聞きたい • Temporalの全体像を話すというわけではない ◦
自分が大事だと思ってるところ(好きな所)をひたすら話す感じです • Temporalの基礎的な話はスキップしてる ◦ ほぼ英語版しかないけどMDNがすごく詳しい(読み物としても👍)
多分みんなが知ってる ?こと JSのDateがつらい • 日付処理を書いた人は一度は苦しめられたことでしょう TemporalはDateのつらみを解決する • Dateがつらすぎて作られた仕様なんでしょう? 長い時を経て最近Stage4になったらしい •
なんか先週あたりタイムラインが盛り上がってたよね
復習も兼ねて
JSのDateがつらいこと • システム以外のタイムゾーン(サマータイム)サポートがない ◦ UTC ↔ システムタイムゾーン しかできない (しかも変換が暗黙的) •
日時文字列のパース動作の信頼性が低い ◦ 渡す文字列によってタイムゾーン解釈が変わる・そもそも環境差がある • 日付オブジェクトの可変性の問題 ◦ set系のメソッドで書き換えられてしまう • 日時計算が行いづらい ◦ 加減算や比較ですら一旦値を取り出す + Setし直しという工程が発生
Temporalで解決すること • IANAで管理されているタイムゾーン全てに対応 ◦ システムのタイムゾーン以外でも自由に変換できる • パースできる文字列・数値を厳密化 ◦ RFC3339 とその拡張であるIXDTFだけに限定
• immutableなAPI ◦ 計算後は新しいTemporalのオブジェクトを返す • 基礎的な日時計算メソッドの搭載 ◦ 日時の加減算や比較などは標準で搭載するようになった
…みたいな話はもう結構ある
多分みんなが気になってること 私たちのコードベースはどう変わるの? • 結局本番でどう使っていけばいいのか 別に今でもDate直接触らずライブラリ使ってるじゃん • どうせライブラリ使う自分たちにどこまで関係があるのか Temporalで全てが解決するんか? • 日時にまつわる大変さはたくさんあるけれど...
It’s “Time” to use Temporal
今回のテーマ Temporalで • 変わること / 変わらないこと • Scopeじゃないこと / まだできないこと
を考えることで Temporal Native 時代の解像度が上がる そこから自ずとどう使っていくべき か、どう移行する かが分かってくる
「日時」って曖昧すぎない?
“日時”と言う曖昧なものの解体 そもそもみんなが「日時」と気軽に言う”それ”は同じもの? • 使う場所・コンテキストで微妙に違うものじゃないですか? 以下は全部同じデータ? • ドキュメントの更新日時 • タスクの期限日 •
決算月 • 毎日のリマインダーの時刻設定
あなた(or ユーザー)が「日時」と言った時それはどちらを意味してる? WallClockTime vs ExactTime WallClockTime 特定のロケール・暦における日時の表現 例 • 2026年3月16日
19時 • 2026年正月28 (中国暦) ExactTime 世界共通のある一瞬 例 • 2026-03-16T10:00:00.000Z • 1773655200000 (Unix Epoch)
WallClockTime ↔ ExactTimeの変換にはタイムゾーン(+暦)のデータが不可欠 ExactTime → WallClockTImeは基本決定的 • 未来の日時以外で言えば一意に決定できる • (未来は「タイムゾーン自体の変更が...」とか考えだすとややこしい)
WallClockTime → ExactTimeは曖昧性を持つ • サマータイム開始・終了時などで曖昧な期間がどうしても発生する WallClockTime ↔ ExactTime
タイムゾーンのデータはExactTimeとWallClockTime の橋渡しで必要 • 逆にそこの橋渡しをしない場合は必ずしも必要ないなる 暦の指定は WallClockTime を明確化するのに必要 • 暦が確定できないと WallClockTime
で示しているデータの意味が変わる • 例 : 2026年1月28日 ◦ 中国で使われる旧暦の場合 → 2026年3月16日(グレゴリオ暦) タイムゾーンと暦を指定するところ
自分たちが「日時」を指定する時、必ず「あるー瞬」を指してるわけではない • 誕生日 : ローカルなカレンダーにおける「日」自体しか定義していない • 今月 : 特定のカレンダーの特定の「月」だけを表してる ここでいう「日時」は点だったりだったり期間だったりする
日時は必ずしも「ある一瞬」ではない ある一瞬 月 日
Dateのつらさの正体 (の1つ) 日時と言う曖昧な概念を1つのClassで扱うことに限界があった のでは? いろんな意味の「日時」を1つに詰め込んだ歪みとして • ローカルの計算だけでいいのにタイムゾーンを持ってる • 時刻は関係ないのに時刻まで内部的に持つ •
etc… そりゃあ、挙動が暗黙的になったり、想定してないものが返るように見える...
Temporalによる整理 Temporalは型レベルでこれらの「日時」を厳密に区別 する • WallClockTime vs ExactTime の分離 • PlainDateTime以外にもPlain〇〇がそれぞれある
これがTemporalのAPI設計における本質であり重要な部分(だと思ってる)
Temporalによる整理 WallClockTime vs ExactTime の分離 • WallClockTIme : Teporal.PlainXX という名前のクラス
• ExactTime : Temporal.Instant これらの2つは Temporal.ZonedDateTimeで橋渡しされ、変換できる
Temporalによる整理 PlainXX という命名のClassたち = WallClock Time • PlainDateTime : 特定の年月日時刻のデータ
• PlainDate : 時刻のデータを持たない日付だけのデータ • PlainTime : 日付のデータを持たない時刻だけのデータ • PlainMonthDay : 特定の月と日だけのデータ • PlainYearMonth : 特定の月(年と月だけ)のデータ
型 = 意味 = 振る舞い が違う もちろんデータの型と意味が違うと言うことは • 生えているプロパティ・メソッドも違う ◦
例 : PlainMonthDay にyearは生えていない • 生成時や変換時の制約も違う ◦ 生成に必要なデータ・補完されるデータもが違う ◦ 変換で求められるデータ・補完されるデータが違う
データと振る舞いが変わる ↓ 使い方も変わる
日時の扱いを考え直すところから 「日時」と言う安易な一言で本来異なるものを一括りにしてなかったか? • Dateを使ってる限りは「日時? → Dateにしとけ」で済ましていた ◦ (で、痛い目を見ていた ) •
違うものを一緒にしてたらそりゃうまくいかない この考え方を変えない限りTemporalにする旨みは活かせない • TemporalでどのObject / API を使うべきか選べない
もう一度コードを見直そう コードにはいろんなタイプの「日時」が溢れている • データベースに保存する更新タイムスタンプ • ユーザーの生年月日 • カレンダー表示する月のデータ • 日時入力フォームに入力された日時
Temporalだと... それぞれ • データベースに保存する更新タイムスタンプ → Instant / Now • 日時入力フォームに入力された日時
→ PlainDateTime • ユーザーの生年月日 → PlainDate • カレンダーで表示してる月 → PlainYearMonth
入力と保持するデータ ユーザーが入力するのは基本WallClockTime (= PlainXX) 保存する時を考えると... • 一瞬を表しているもの → タイムスタンプで保存したい ◦
大抵 PlainDateTime → ZonendDateTime → timestampに変換でいける ◦ 逆もまた然り • 特定の一瞬を表してない → 別途違うフォーマットで保存する ◦ PlainDate / PlainYearMonth → 文字列に変換とかが安全そう
よくありそうなデータの変換 ローカルな日時 → タイムスタンプで保存したい 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
よくありそうなデータの変換 タイムスタンプ → ローカルでの解釈 const savedTimestamp = 1773622800000; const instant
= Temporal.Instant.fromEpochMilliseconds(savedTimestamp); const zonedDateTime = instant.toZonedDateTimeISO('Asia/Tokyo'); const plainDateTime = zonedDateTime.toPlainDateTime();
特定の一瞬じゃないデータの保存 案 : そのまま 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);
閑話 : 自分のいるチームでは Dateでの値の保存・やり取りを非推奨にしてる (内部的には仕方ないが) 代わりに文字列ベース(+それらを持つObject)のBrandedTypesを導入 • 基本の4つ : UTCISOString
/ DateString / TimeString / LocalDateTimeObject • それぞれ Temporalの Instant / PlainDate / PlainTime / PlainDateTime に対応 常に「この日時データはどれ?」ということを意識させる
閑話 : 自分のいるチームでは 詳しくはTS Kaigi Hokuriku で発表したLT資料を見てね!
Temporalだけだと 難しいこと
有名な日時ライブラリと比べると計算メソッドが抱負とまでは言えない • addBusinessDays / isWeekend / isSameDay とかは流石にない とはいえ、基本的な計算メソッドはカバーしてる •
add / subtract / since / until … どこまで求めるかになってきそう 計算メソッドは最低限 ?
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はより厳密で限定的に
Temporalのformat機能は基本Intlに乗っかっている • toLocaleStringはIntlをそのまま使ってる Intlのインスタンス生成コストはバカにならないので素直にIntlから使うのが良い • TemporalサポートでIntlもTemporalの各インスタンスが受け取れる 多く日時ライブラリの持つようなformatPatternによるformatは使えない • formatPatternによるformat :
“yyyy/MM/dd” みたいな文字列でのformat format機能はIntl頼り
Temporalの話とはズレるので深入りしないが、日時のformatはとてもややこしい • 日時表記として / 文法的におかしい形にformatできてしまう可能性 • ライブラリでformatPattern文字列の仕様あんまり守れてない問題 • そもそも formatPatternを正しく使うの知識いる問題
• 参照するデータが現地のユースケースをちゃんと反映できるか問題... ↑ みたいなことを考え出すと本当に面倒なのでIntlで済むならそれが一番 日時のformatって複雑で ...(早口)
日時ライブラリは?
ライブラリあれば Temporal不要論 a.k.a 「Temporal複雑すぎて直接使うやついないだろ論」 それは本当に「Temporalによる複雑さ」なのか? • 日時そのものの扱いの難しさだったのでは? ◦ TC39が意地悪して使いづらくしてるわけはあるまいて 日時の難しさはTemporalを使わなかろうが一生付き纏う問題
• 今までDateとライブラリでうまく誤魔化せていただけの可能性がある ◦ or 単にそこまで複雑な日時計算してなかった可能性
確かにTemporalになくて有名ライブラリにある機能はまだまだある • parse / format周りの機能 • 便利な計算メソッド なので「Temporalあれば日時ライブラリ不要!」とまでは言えないかも 一方でTemporalのサポートでライブラリ側も変更は余儀なくされるはず •
= 扱うデータ型によって機能を調整しなくてはいけない問題 日時ライブラリの役割と今後
Temporalのインスタンスによって持っている情報に差がある • eg. PlainDateTimeはTimeZone情報を持たない 単に「Temporalのインスタンスを受け取れる」って言っても... ライブラリの Temporalサポート(想像) Before dateX(date).toUTCString() After
dateX(date).toUTCString() Date String Date String PlainDT throw error?
メソッドチェーン形式だと大変そう • dateX(date).setYear(2026).toUTCString() date-fns みたいな関数合成パターン + 各関数の引数の型を制限 / 引数から推論 •
formatUTCISOString(addDays(plainMonthDay,9)) ライブラリの Temporalサポート(想像) PlainMonthDay だったら? TimeZone情報 まだないよ? PlainMonthDayは 渡せないよ!
どちらにせよインスタンスによってできる操作が違う ことは意識する必要がある • → Temporalの知識が無駄になることはないんじゃないか 全部ZonedDateTimeで無理やり持つみたいなことすれば意識しづらいかも • 一旦の移行戦略としてはある • 個人的には「なんのためにTemporalにしてるんだ!」と思ってしまうが...
ライブラリの Temporalサポート(想像)
まだ広く使えると言える(=Baselineに入る)まで時間はある 今のうちから備えられそうなこと • コードで日時を表してる所を洗い出して「Temporalで言うどれ?」をやる ◦ → ついでに無闇にDateでやってるとこを減らせると良い • RFC3339/タイムスタンプ以外のフォーマットでやり取りしてないか点検 ◦
→ やめといた方が良い(そんなことしてるとこ少なそうだけど) • 個人のものとかならPolyfill入れてみて操作感を覚える 今からできること
軽量でいい Polyfillがあるらしいよ!
• Temporal は今ままで暗黙的だった「日時という何か」を解体し明示的にする ◦ Temporalを使いこなすことは暗黙的だった部分を照らし直すこと • Temporalは日時処理の特効薬ではないし、人によっては苦い薬かもしれない ◦ でも使うことで日時の難しさに正しく向き合って良くしていける良薬 ◦
Temporalがくる前から向き合わなくてはいけなかった問題でもある • Temporalだけで解決しないこともあるが、前進はする • Temporalが来る今こそ、日時ともう一回真剣に向き合う時 ! まとめ
It’s “Time” to use Temporal and rethink DateTime !