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
Branded Typesで日時の複雑さと戦う
Search
Saji
November 23, 2025
4
1.1k
Branded Typesで日時の複雑さと戦う
TSKaigiHokuriku2025 LT
-
https://hokuriku.tskaigi.org/talks/41
X
-
https://twitter.com/sajikix
Saji
November 23, 2025
Tweet
Share
More Decks by Saji
See All by Saji
It’s “Time” to use Temporal
sajikix
3
240
ユーザーが作成したコードをブラウザ上で安全に実行できる Plugin システムへのアプローチ
sajikix
1
580
推しProposalと広がる夢~Intl.MessageFormatとDomLocalization~
sajikix
1
570
自作JSエンジンに推しプロポーザルを実装したい!
sajikix
1
310
Lookback TypeScript ESM support and what should we do now.
sajikix
5
780
フロントエンドで日時処理と戦うために 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
Featured
See All Featured
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.3k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
220
AI: The stuff that nobody shows you
jnunemaker
PRO
3
460
The Mindset for Success: Future Career Progression
greggifford
PRO
0
280
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
89
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
68
38k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.2k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
64
54k
Designing for humans not robots
tammielis
254
26k
How GitHub (no longer) Works
holman
316
150k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
150
Transcript
3ZVTFJ4BKJLJ!TBKJLJY #SBOEFE5ZQFTͰ࣌ͷෳࡶ͞ͱઓ͏
͍࣌͠Ͱ͢ΑͶʁ
ࣗͷνʔϜͰ՝ͩͬͨ
ҙࣝΛڞ༗͢ΔͨΊʹ ؆୯ʹLJOUPOFͷઆ໌
LJOUPOFʹ͍ͭͯ LJOUPOFɺϓϩάϥϛϯάͷ͕ࣝͳͯ͘ۀʹ߹ΘͤͨγεςϜΛ͢ ͘։ൃͰ͖ΔϊʔίʔυɾϩʔίʔυͰ͢ɻ σʔλΛੵɾҰཡɾݕࡧͰ͖ΔσʔλϕʔεػೳͱɺۀΛԁʹਐΊΔͨ Ίͷίϛϡχέʔγϣϯػೳ͕උΘ͍ͬͯ·͢ɻ
LJOUPOFͷʮΞϓϦʯػೳʹ͍ͭͯ LJOUPOFͷϝΠϯػೳʹʮΞϓϦػೳʯͱݺΕΔͷ͕͋Δ w ̎࣍ݩతʹ༷ʑͳϑΟʔϧυΛஔͯ͠ɺϑΥʔϜΛ࡞ w ϢʔβʔσʔλΛཷΊ͍ͯ͘͜ͱ͕Ͱ͖Δ w ଞʹɺϓϩηεཧίϝϯτଞΞϓϦͷࢀরͳͲ͕Ͱ͖Δ w ݱࡏɺ$MPTVSF-JCSBSZ+4ˠ3FBDU54ʹ৽த
LJOUPOFʮΞϓϦʯͷೖྗը໘
LJOUPOFͷʮΞϓϦʯʹ͋Δ࣌ܥͷϑΟʔϧυ ҎԼͷϑΟʔϧυ͕͋Δ w ϑΟʔϧυΛೖྗͰ͖ΔϑΟʔϧυ w ࣌ࠁϑΟʔϧυ࣌ࠁΛೖྗͰ͖ΔϑΟʔϧυ w ࣌ϑΟʔϧυͱ࣌ࠁΛ߹ΘͤͯೖྗͰ͖ΔϑΟʔϧυ w ࡞࣌
ΈࠐΈϑΟʔϧυ σʔλΛ࡞͕ͨ࣌ࣗ͠ಈͰೖΔ w ߋ৽࣌ ΈࠐΈϑΟʔϧυ σʔλΛߋ৽͕ͨ࣌ࣗ͠ಈͰೖΔ
LJOUPOFͷʮΞϓϦʯʹ͋Δ࣌ܥͷϑΟʔϧυ
࣌ܥͷϑΟʔϧυ࣮ͷ՝ ΞϓϦͷϑΥʔϜͷঢ়ଶΛཧ͢Δ࣌ʹɺશ෦4USJOHܕͰΛཧ͍ͯͨ͠ export type DateFieldValue = { type: typeof FORM_INPUT_FIELD_TYPE.DATE;
value: string; }; export type TimeFieldValue = { type: typeof FORM_INPUT_FIELD_TYPE.TIME; value: string; };
શ෦ಉ͡ܕͩͱ߹͕ѱ͍ʁ
ಉ͡ੑ࣭ͷσʔλ͡Όͳ͍ ؾ͕͢ΔΜͩΑͳ͊
ྨͷ؍͕ͭ͋Δͱߟ͑ͨ
؍ಛఆͷҰॠΛࢦ͢σʔλ͔ʁ ࣌ͷσʔλʹಛఆͷҰॠΛʮࢦ͢ͷʯͱʮࢦ͞ͳ͍ͷʯ͕͋Δ ྫʮੜ݄ʯͱ͍͏ใ࣌ͷσʔλ͕ͩɺಛఆͷҰॠࢦ͞ͳ͍ ͦΕͧΕผͷ֓೦Ͱ͋ΓɺมʹෆՄٯੑ͕͋Δ 2025-11-23 2025-11-23 16:40 16:40 ❌ ❌
؍ϢʔβʔͷೖྗΛ͏͔ʁ ϢʔβʔϩʔΧϧ࣌ؒʹੜ͖͍ͯΔ w Ϣʔβʔ͕ೖྗ͢ΔͷৗʹϩʔΧϧ࣌ؒ w Ͳ͔͜ͰϑΥʔϜͷঢ়ଶˠ65$ͷม͕ඞཁʹͳΔ ٯʹϢʔβʔͷೖྗ มߋ ͕ͳ͍ͷͰ͋Ε w
දࣔલʹϩέʔϧͱλΠϜκʔϯΛՃຯͨ͠ϑΥʔϚοτΛ͢Δ͚ͩ w format(datetime)
݁શવಉ͡ੑ࣭ͷσʔλͰͳ͍ ؍ಛఆͷҰॠΛࢦ͢σʔλ͔ʁ w ಛఆͷҰॠΛࢦ࣌͢ߋ৽࣌࡞࣌ w ಛఆͷҰॠΛࢦ͞ͳ͍࣌ࠁ ؍ɿϢʔβʔೖྗΛ͏σʔλ͔ʁ w ೖྗΛ͏࣌࣌ࠁ w
ೖྗΛΘͳ͍ߋ৽࣌࡞࣌
݁ಉ͡ੑ࣭ͷσʔλͰͳ͍ ಛఆͷҰॠΛࢦ͢ ಛఆͷҰॠΛࢦ͞ͳ͍ ϢʔβʔೖྗΛ͏ ࣌ϑΟʔϧυ ࣌ࠁϑΟʔϧυϑΟʔϧυ ϢʔβʔೖྗΛΘͳ͍ ߋ৽࣌࡞࣌ϑΟʔϧυ
͡Ό͚͋Α͏
ϧʔϧ࣌ͱͯ͠ѻ͏σʔλΛྨ͠ݶఆ͢Δ ࣌ͱͯ͠ѻ͏ อ࣋͢Δ σʔλΛҎԼͷͭʹݶఆͨ͠ 65$*404USJOH"2025-11-23T07:40:00.000Z" %BUF4USJOH"2025-11-23" 5JNF4USJOH"16:40"
-PDBM%BUF5JNF0CKFDU{date: "2025-11-23", time: "16:40"} w %BUF4USJOHͱ5JNF4USJOHΛ߹Θͤͨͷ
ϧʔϧ࣌ͱͯ͠ѻ͍͍ͬͯσʔλ ಛఆͷҰॠΛࢦ͢ ಛఆͷҰॠΛࢦ͞ͳ͍ ϢʔβʔೖྗΛ͏ -PDBM%BUF5JNF0CKFDU ˣ 65$*404USJOH %BUF4USJOH5JNF4USJOH ϢʔβʔೖྗΛΘͳ͍ 65$*404USJOH
ؒ %BUFμϝͳͷ %BUFͷ··σʔλͷอ࣋ΓऔΓ͢Δ͜ͱඇਪʹͯ͠Δ ཧ༝ w ͦͦγεςϜλΠϜκʔϯ ↔︎ 65$͔͠αϙʔτ͍ͯ͠ͳ͍ w ೖग़ྗΛ65$γεςϜͷͲͬͪͰѻ͏͔͕҉త
w จࣈྻͷύʔε͕͔ͳΓτϦοΩʔ w ͜͜ʹօ͞Μͷࢥ͏ҙͷ%BUFͷෆຬΛೖΕΔ
ܕͰ͚͍ͨʂ
#SBOEFE5ZQFTͩʂ #SBOEFE5ZQFTͱ w ʮߏ͕ಉ͡ͳΒಉ͡ܕͱ͢Δʯͱ͍͏54ͷݪଇΛճආ͠ɺ w ߏ͕ಉ͡ܕͰޓ͍ʹ۠ผ͕ͭ͘Α͏ʹ͢Δख๏ ࣗͳΜͰ͔ΜͰಋೖ͢Δͷʹ৻ॏɻͰ࣌ʹؔͯ͠ w ಘΒΕΔԸܙ ࣌ͷ͜͠͞
#SBOEFE5ZQFTʹΑΔσϝϦοτ ͱࢥͬͯΔ
࣮ࡍͷίʔυ #SBOEFE5ZQFͷఆٛ ྫUTCISOStringܕ const utcisoStringBrand = Symbol('for UTCISOStringBrand'); export
type UTCISOString = string & { [utcisoStringBrand]: unknown; };
࣮ࡍͷίʔυ "TTFSUJPOؔηοτͰ࡞Δͱศར export function createUTCISOString( rawString: string, strict: boolean =
true ): UTCISOString { if (strict && !UTC_ISO_DATE_TIME_REGEX.test(rawString)) { throw new Error(`Invalid UTC ISO String : ${rawString}`); } return rawString as UTCISOString; }
'&Ͱ#SBOEFE5ZQFTʹҠߦ͢Δ࣌ͷίπ ֎෦͔ΒͷσʔλɾϢʔβʔೖྗɾ4UBUFͷ̏ํ͔ΒݫີԽ͢Δͱྑ͍ ίʔυ ϕʔε ֎෦σʔλ "1* 4UBUF Ϣʔβʔೖྗύʔπ ;PE4DIFNB "TTFSUJPO7BMJEBUJPO
ܕఆٛݫີԽ
#SBOEFE5ZQFTΛ࣌σʔλʹಋೖͯ͠Έͯ ܕΛݟΔ͚ͩͰɺԿΛͯ͘͠ΕΔͷ͔Ұྎવ w ྫҾ͕-PDBM%BUF5JNF0CKFDUฦΓ͕65$*404UJOH w ˠ*40ܗࣜͳΜͩͳʂฦΓ65$ͳͷͰ࣌ࠩมͯ͠Δʂ ܕΤϥʔ͕ग़ΔͷͰؒҧ͍ͬͯͦ͏ͳͱ͜ΖΛൃݟɾ༧Ͱ͖Δ w ࣌ͷυϝΠϯʹৄ͘͠ͳ͍δϡχΞϝϯόʔͰ҆৺ νʔϜͰͷڞ௨ݴޠʹͳΔ
Α͏ʹؤுͬͯΔͱ͜Ζ
͜͜·ͰͰेศར͚ͩͲ
কདྷΛݟਾ͑Δ
࣌Yকདྷ
࣌Yকདྷ5FNQPSBM
5FNQPSBMΛҙࣝͯ͠Δ ࣮͜ͷྨ5FNQPSBMΛࢀߟʹ͍ͯ͠Δ ͱ͍͏͔͓ͷͣͱͦ͏ͳΔ 5FNQPSBMͱͷରԠؔ w 65$*404USJOHTemporal.Instant w %BUF4USJOHTeporal.PlainDate w
5JNF4USJOHTeporal.PlainTime w -PDBM%BUF5JNF0CKFDUTeporal.PlainDateTime
5FNQPSBMΛҙࣝͯ͠Δ UTCISOString LocalDateTimeObj DateStiring TimeString
5FNQPSBMͷੴ ݁ہ5FNQPSBM͕ղܾ͔ͨͬͨ͜͠ͱͱಉࠜͷͩͬͨ w ͦΕΛ#SBOEFE5ZQFͰղܾͯ͠Δ w ·ͩ5FNQPSBM͔͔࣌ؒΓͦ͏ͳͷͰ ٯʹݴ͑ɺ5FNQPSBMҠߦ؆୯ʹͳΔͣͰ͢Ͷʂ w ରରԠͯ͠ΔͷͰมͯ͠Δ͚ͩͰ͍͍
·ͱΊ ࣌ͷσʔλΛѻ͏ͷ͍͠ w ಛʹಠཱͨ࣌͠ࠁΛѻ͏߹%BUFͷ͍উख͕ LJOUPOFͷΞϓϦը໘৽Ͱ#SBOEFE5ZQFTͰ࣌σʔλΛྨɾ੍ݶͯ͠Δ w ϝϦοτڗडͰ͖ͯΔ ͱࢥ͏ ࣌σʔλͷྨ5FNQPSBMΛࢀߟʹ
ݟӽͯ͠ ࡞͍ͬͯΔ w ૣ͘5FNQPSBM͕͘Εղܾ͢Δͷʹͳ͊ ࣌σʔλͷཧͰࠔͬͨͱ͖#SBOEFE5ZQFT͕ॿ͚ʹͳΔ͔͠Εͳ͍
4BKJ3ZVTFJ4BKJLJ 'SPOUFOE%FWFMPQFSBU$ZCP[V JOD 𝕏 !TBKJLJY
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠