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
書き換えて学ぶTemporal #fukts
Search
Hiroyuki ANAI
May 07, 2026
Programming
430
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
書き換えて学ぶTemporal #fukts
https://fukuoka-ts.connpass.com/event/387858/
Hiroyuki ANAI
May 07, 2026
More Decks by Hiroyuki ANAI
See All by Hiroyuki ANAI
fukuoka.ts #3 社内でESLintの共通設定を配りたい2025年春版
pirosikick
3
490
compilerOptions、全部読んだ
pirosikick
1
300
Step Functionsの設計時に知っておいたほうがいいかもしれないこと
pirosikick
0
540
Go言語による並行処理「4.4 orチャネル」の図
pirosikick
0
490
サイボウズWebフロントエンド脱レガシーの今までとこれから
pirosikick
6
17k
@cybozu/eslint-configから学ぶ、全社共通ESLint configの運用
pirosikick
4
1.9k
Web Share Target API #w3fukuoka
pirosikick
0
740
Google I/O '19のWebをまとめる会
pirosikick
2
900
PuppeteerでいらないCSSを消す
pirosikick
23
29k
Other Decks in Programming
See All in Programming
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
330
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
250
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
390
React本体のコードリーディング
high_g_engineer
1
160
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
2
1.2k
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
240
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
120
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
160
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
150
「つくるAI」だけではバグは見つからない ~テストに必要な「見つけるAI」を分離させる戦略~
mfunaki
0
180
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
120
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
580
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
220
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
So, you think you're a good person
axbom
PRO
2
2.1k
Designing Experiences People Love
moore
143
24k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
450
Site-Speed That Sticks
csswizardry
13
1.5k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
870
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
810
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Transcript
書き換えて学ぶTemporal 2026-05-07 fukuoka.ts #4 @pirosikick
自己紹介 © LayerX Inc. @pirosikick / 穴井宏幸 株式会社LayerX バクラク勤怠のソフトウェアエンジニア 趣味:
プロ野球観戦 今年のホークス、みんなどう思うか? 2
今日の話 © LayerX Inc. 「Temporal?Dateの進化版ね」くらいの理解から進んでいない Stage 4になったし、 バクラク勤怠という日付・時刻を扱うプロダクトに関わっているので、 重い腰を上げてちゃんと向き合うぞ!という話 3
先に結論 © LayerX Inc. APIが豊富: 勤怠管理という日付・時刻を扱うドメインでも十分 APIが直感的: 統一感があり、ちょっと書けばしっくりくる 型が豊富: コードの意図が明確に
Stage 4になったし、乗り換え待ったなし 4
目次 © LayerX Inc. 今日の話 Date のつらさ Temporal とは バクラク勤怠のコードを書き換えてみる
基礎編 応用編 気づき 5
Date のつらさ
Dateのつらさ © LayerX Inc. Dateのつらさ タイムゾーンの扱い システムのローカル or UTC ミュータブル
パースが微妙 new Date("2026-05-07") はUTC、 new Date("2026/05/07") はローカル時刻 月だけが0始まり(1月 → new Date(2026, 0, 1) ) APIが貧弱 ⋯ etc 7
Dateの仕様 © LayerX Inc. Dateのつらさ ES5で少し機能追加されたが、ベースの部分は初期から変わってない 短い設計期間の中で、Java 1.0の java.util.Date をそのままコピー
8
Temporalとは
Temporalとは © LayerX Inc. Temporalとは ECMAScript の新しい日時API Date の問題点をすべて解決するために設計された 2021年にStage
3、2026年3月にStage 4 到達 10
タイムゾーンを型レベルで表現できる 型 用途 Temporal.PlainDate 日付のみ(タイムゾーンなし) Temporal.PlainTime 時刻のみ Temporal.PlainDateTime 日時(タイムゾーンなし) Temporal.ZonedDateTime
タイムゾーン付き日時 Temporal.Instant 絶対時刻(Unix時刻相当) © LayerX Inc. Temporalとは 型が多いぶん、意図が明確になる 11
イミュータブル © LayerX Inc. Temporalとは 12
バクラク勤怠のコードを書き換えてみる
バクラク勤怠 © LayerX Inc. https://bakuraku.jp/attendance/ LayerX が提供する勤怠管理 SaaS Slackアプリ、PCログ、AIによるシフト変換機能 ...
etc 14
プロダクト画像は現地のみ! © LayerX Inc. 15
これは置き換え甲斐がありそうだぜ.... 勤怠管理アプリは日付・時刻がいっぱい
基本編 豊富なAPIをいっちょ試してみるかのコーナー
タイムゾーン付きで現在時刻の取得 © LayerX Inc. 現在時刻の取得: Temporal.Now ※バクラク勤怠では、日付・時刻処理にはDay.jsを利用し、 new Date をESLintで禁止している
18
現在時刻の取得: Temporal.Now © LayerX Inc. 型ごとの現在時刻関数 instant() plainDateISO(timeZone?) plainDateTimeISO(timeZone?) plainTimeISO(timeZone?)
zonedDateTimeISO(timeZone?) timeZoneを省略するとtimeZoneId()が設定される timeZoneId() システムで設定されているタイムゾーンを返す ex) "Asia/Tokyo 19
値の取得 Date Temporal getFullYear() year getMonth() (0始まり) month (1始まり) getDate()
day ⋯ ⋯ © LayerX Inc. Dateは関数、Temporalはプロパティ 20
プロパティ 意味 dayOfWeek 曜日(1=月曜、7=日曜) dayOfYear 年通算日(1〜366) weekOfYear 年通算週番号 daysInMonth 月の日数(28〜31)
daysInYear 年の日数(365 or 366) inLeapYear うるう年かどうか microsecond , nanosecond マイクロ秒/ナノ秒(0〜999) © LayerX Inc. プロパティ 21
曜日はちょっと注意 © LayerX Inc. 曜日: dayOfWeek Date( getDay() )は0始まり、0=日曜日、6=土曜日 Temporal(
dayOfWeek )は1始まり、1=月曜日、7=日曜日 故に、 getDay() === dayOfWeek % 7 22
特定の日付・時刻を作成 © LayerX Inc. 23
.from , .with © LayerX Inc. 特定の日付・時刻を作成 24
比較: .compare , .equals © LayerX Inc. 25
加算・減算: .add , .subtract © LayerX Inc. 26
応用編 勤怠管理のドメインに寄った話
どの型を使うか? © LayerX Inc. 出勤簿の年月: PlainYearMonth 出勤簿の各日付: PlainDateTime 28
打刻時間はPlainTime? © LayerX Inc. どの型を使うか 18:00 など。 PlainTime でよさそうじゃね? 29
退勤時刻は24:00を超える場合がある © LayerX Inc. どの型を使うか ex: 25:00 は翌日の1時 深夜残業や、深夜シフトなど 30
PlainTimeは〜23:59なので、 © LayerX Inc. どの型を使うか 31
PlainDateTime or ZonedDateTime がよさそう バクラク勤怠では ZonedDateTime がよさそう。 © LayerX Inc.
どの型を使うか 32
出勤・退勤時刻から労働時間の計算 © LayerX Inc. どの型を使うか 33
31日締め × 2月問題 © LayerX Inc. 締め日の設定は1〜31日。でも2月は最大28日(うるう年は29日) 現状は Math.min で手動クランプ:
34
overflow オプション © LayerX Inc. 31日締め × 2月問題 35
constrain と reject を用途で使い分けるとよさそう: © LayerX Inc. overflowオプション 36
constrain と reject を用途で使い分けるとよさそう: © LayerX Inc. overflowオプション 37
「業務月」はカレンダー月ではない © LayerX Inc. 14日締めの会社の「4月」の出勤簿に表示される期間 = 4/15 ~ 5/14 14日締めの会社の
5/10 の業務月は 「4月」 38
「業務月」の取得 締め日で分岐して、カレンダー月の前月・次月・当月を返す © LayerX Inc. 39
「次の月」の取得 © LayerX Inc. 「業務月」はカレンダー月ではない getNextYearMonth は12月を手書きで処理している: 前月( getPrevYearMonth )も似たようなもん
40
ただ、 .add , .subtract を使えば、よい © LayerX Inc. 「業務月」はカレンダー月ではない PlainYearMonth
を使うと 年またぎが自動処理 される: 41
Branded Typeで「業務月」を型で区別 © LayerX Inc. 「業務月」はカレンダー月ではない 現状、コード上で年月は { year: number;
month: number } で表現されており、 「これ、どっちだっけ ... ?」となりがち PlainYearMonth + Branded Type で 型レベルで業務月とカレンダー月を区別できる: 42
有給休暇「2年後の前日」× うるう年 © LayerX Inc. 有給休暇の有効期限は付与日から 2年間(労働基準法) Q. 2024年2月29日(うるう年)に付与された有給はいつまで有効? A.
2026年2月27日 有効期限は「付与された日から2年後の、前日(応当日)まで」 43
うるう年の2年後 © LayerX Inc. 有給休暇「2年後の前日」× うるう年 ライブラリの場合、実装による Day.jsは、 .add(2, "year")
でOK 44
Temporal は仕様で動作が明示されている 「ライブラリによる」ではなく 仕様として保証 されている点が重要 © LayerX Inc. 有給休暇「2年後の前日」× うるう年
45
気づき その他の実際に使ってみて気づいたこと
「Temporal.型~」 、長い © LayerX Inc. 「Temporal.型.~」のコード上での存在感がすごい AIがコードを書く時代で、よかったね そうでなければ、ラップした関数を作っていたかも知れない 47
フォーマッターをどうするか © LayerX Inc. Day.jsのformat関数を結構使ってた Intl.DateTimeFormat、使いづらくないか? 任意のフォーマットで出力できる関数(ex: format('YYYY-MM-DD') )はToo Muchだと思うの
で、 特定のフォーマットで出力できる関数を作る程度でいい気がする 48
フォーマッター以外はAPIで困ることはない © LayerX Inc. API・型が豊富 日付・時刻に関するユースケースはほぼカバーされていると言っても過言ではない、か もしれない 49
ありがとうございました!