Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Branded Typesで日時の複雑さと戦う
Search
Saji
November 23, 2025
2
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
推しProposalと広がる夢~Intl.MessageFormatとDomLocalization~
sajikix
1
390
自作JSエンジンに推しプロポーザルを実装したい!
sajikix
1
260
Lookback TypeScript ESM support and what should we do now.
sajikix
4
740
フロントエンドで日時処理と戦うために 2025 ver
sajikix
6
4.5k
先取り!Temporal
sajikix
0
250
アプリ文言のパースで学ぶ 文字列Literal型パズル入門
sajikix
3
1.2k
The Future of Frontend i18n : Intl.MessageFormat
sajikix
1
4k
Temporalを取り巻く仕様を整理する
sajikix
3
1k
Intlの今までとこれから
sajikix
7
4.2k
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Typedesign – Prime Four
hannesfritz
42
2.9k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.8k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
Site-Speed That Sticks
csswizardry
13
1k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Producing Creativity
orderedlist
PRO
348
40k
Building Adaptive Systems
keathley
44
2.9k
BBQ
matthewcrist
89
9.9k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
720
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
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠