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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Hiroyuki ANAI
May 07, 2026
Programming
48
0
Share
書き換えて学ぶ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
460
compilerOptions、全部読んだ
pirosikick
1
270
Step Functionsの設計時に知っておいたほうがいいかもしれないこと
pirosikick
0
510
Go言語による並行処理「4.4 orチャネル」の図
pirosikick
0
460
サイボウズWebフロントエンド脱レガシーの今までとこれから
pirosikick
6
17k
@cybozu/eslint-configから学ぶ、全社共通ESLint configの運用
pirosikick
4
1.9k
Web Share Target API #w3fukuoka
pirosikick
0
730
Google I/O '19のWebをまとめる会
pirosikick
2
880
PuppeteerでいらないCSSを消す
pirosikick
23
29k
Other Decks in Programming
See All in Programming
感情を設計する
ichimichi
5
1.6k
(Re)make Regexp in Ruby: Democratizing internals for the JIT
makenowjust
3
830
検索設計から 推論設計への重心移動と Recall-First Retrieval
po3rin
4
1.2k
Don't Prompt Harder, Structure Better
kitasuke
0
790
Spec Driven Development | AI Summit Vilnius
danielsogl
PRO
1
120
UIの境界線をデザインする | React Tokyo #15 メイントーク
sasagar
2
380
Kubernetes上でAgentを動かすための最新動向と押さえるべき概念まとめ
sotamaki0421
3
720
YJITとZJITにはイカなる違いがあるのか?
nakiym
0
260
From Formal Specification to Property Based Test
ohbarye
0
430
瑠璃の宝石に学ぶ技術の声の聴き方 / 【劇場版】アニメから得た学びを発表会2026 #エンジニアニメ
mazrean
0
300
Spec-driven Development: How AI Changes Everything (And Nothing)
simas
PRO
0
370
Angular Signal Forms
debug_mode
0
120
Featured
See All Featured
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
230
BBQ
matthewcrist
89
10k
Balancing Empowerment & Direction
lara
6
1.1k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
270
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.6k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.2k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
250
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.9k
Side Projects
sachag
455
43k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
64
54k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.7k
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
ありがとうございました!