Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
書き換えて学ぶTemporal #fukts
Search
Hiroyuki ANAI
May 07, 2026
Programming
510
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
安心して変更できるWebフロントエンドの作り方
pirosikick
7
3.3k
fukuoka.ts #3 社内でESLintの共通設定を配りたい2025年春版
pirosikick
3
510
compilerOptions、全部読んだ
pirosikick
1
320
Step Functionsの設計時に知っておいたほうがいいかもしれないこと
pirosikick
0
560
Go言語による並行処理「4.4 orチャネル」の図
pirosikick
0
510
サイボウズWebフロントエンド脱レガシーの今までとこれから
pirosikick
6
17k
@cybozu/eslint-configから学ぶ、全社共通ESLint configの運用
pirosikick
4
1.9k
Web Share Target API #w3fukuoka
pirosikick
0
750
Google I/O '19のWebをまとめる会
pirosikick
2
900
Other Decks in Programming
See All in Programming
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
3k
dotNET_vulnclicker_intro.pdf
deka_morita
0
140
IBM Bob でAI駆動開発『QC-Playbook』
ichirokano2
0
110
phperだってパンチカードでコーディングしたい
o0h
PRO
0
270
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
200
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
380
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
110
APNsからLive Activityを開始する話
yumnumm
0
160
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
130
golang-bob.pdf
iwatsukayura
0
120
The Rails Doctrine Decade
koic
2
560
Jetpack Compose Mechanisms
skydoves
2
710
Featured
See All Featured
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.2k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
540
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
440
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.3k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
How to train your dragon (web standard)
notwaldorf
96
6.9k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
790
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
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
ありがとうございました!