16 ポイント 投稿者 GN⁺ 2024-08-25 | 5件のコメント | WhatsAppで共有
  • ECMAScriptの最近の変更の中で、最も注目すべきものはTemporal提案
    • このAPIは、FullCalendarチームが提供するポリフィルを通じてすでに利用可能
    • このAPIの主な利点の1つは、ついに「Zoned Date Time」を表現するネイティブオブジェクトができたこと

Zoned Date Timeとは何か?

  • 人間のための日付を扱うとき、私たちは通常、タイムゾーンを省略して日付と時刻を話す
  • しかし、JavaScriptのDateオブジェクトは数値しか扱わないため、元の日付の意味が失われる
  • たとえば、カード決済の時点を記録しようとするとき、多くの人は次のようなコードを使うかもしれない
    const paymentDate = new Date('2024-07-20T10:30:00');  
    
  • これは、ブラウザがユーザーのタイムゾーン(CET)を基準にミリ秒を計算するため。しかし、保存された情報はタイムゾーンによって異なって解釈されうる
  • JavaScriptにおける日付はUTCではなく、うるう秒が完全に無視されるPOSIXであるという非常に重要な事実に加えて、数値だけでは日付の元の意味が失われるという問題がある
  • 多くの人は、UTCで扱ったりISO形式で日付を渡したりすれば安全だと思っているが、依然として情報が失われる可能性があるため、これは正しくない

UTCだけでは十分ではない

  • ISO形式で扱っても、日付を表示するときには依然としてタイムゾーン情報が不足している
  • タイムスタンプを人間が読める日付に変換する関数はinjective(単射)ではない
  • たとえば、マドリードからシドニーへ旅行して戻ってきたとき、銀行の取引履歴のタイムゾーン問題で混乱が生じることがある

Temporal APIの紹介

  • Temporal APIは、タイムゾーン付きで日付と時刻を表すTemporal.ZonedDateTimeオブジェクトを導入する
  • RFC 3339の拡張を提案し、文字列で日付をシリアライズおよびデシリアライズするための標準を提示する
  • 1996-12-19T16:39:57-08:00[America/Los_Angeles]
    • この文字列は1996年12月19日16時39分57秒を表し、
    • オフセットはUTCから-08:00であり(ロサンゼルスが属する太平洋標準時 PST)
    • タイムゾーンを認識するアプリケーションが考慮できるよう、関連する標準タイムゾーン(「太平洋標準時」)も追加で指定する
  • さまざまな暦システムをサポートする(例: 仏暦、中国暦、檀紀、グレゴリオ暦、イスラム暦、ペルシャ暦、日本暦など)

基本的な演算

日付の生成
  • Temporal APIはタイムゾーンを処理するための強力なツールを提供する。
  • たとえば、Temporal.ZonedDateTimeオブジェクトを生成するとき、タイムゾーンが正確に反映されるようにする:
    const zonedDateTime = Temporal.ZonedDateTime.from({  year: 2024,  month: 8,  day: 16,  hour: 12,  minute: 30,  second: 0,  timeZone: 'Europe/Madrid'});  
    
  • これにより、タイムゾーンの変更やDSTのような地域時間の調整があっても正確な時刻を維持できる。
日付の比較
  • ZonedDateTimeオブジェクトはcompareメソッドを提供し、2つのZonedDateTimeを比較できる:
    const one = Temporal.ZonedDateTime.from('2020-11-01T01:45-07:00[America/Los_Angeles]');  
    const two = Temporal.ZonedDateTime.from('2020-11-01T01:15-08:00[America/Los_Angeles]');  
    Temporal.ZonedDateTime.compare(one, two);  // => -1  
    
便利な組み込み機能
  • hoursInDayプロパティは、その日の実際の時間数を返す:
    Temporal.ZonedDateTime.from('2020-03-08T12:00-07:00[America/Los_Angeles]').hoursInDay;  // => 23  (DST開始日)  
    
タイムゾーン変換
  • withTimeZoneメソッドを使ってZonedDateTimeのタイムゾーンを変更できる:
    zdt = Temporal.ZonedDateTime.from('1995-12-07T03:24:30+09:00[Asia/Tokyo]');  
    zdt.withTimeZone('Africa/Accra').toString(); // => '1995-12-06T18:24:30+00:00[Africa/Accra]'  
    
基本的な算術演算
  • .addメソッドを使うと、DSTルールに従って日付を加算または減算できる:
    zdt = Temporal.ZonedDateTime.from('2020-03-08T00:00-08:00[America/Los_Angeles]');  
    laterDay = zdt.add({ days: 1 });  // => 2020-03-09T00:00:00-07:00[America/Los_Angeles]  
    
日付間の差の計算
  • .untilメソッドは2つの時刻の差を計算し、Temporal.Durationオブジェクトとして返す。
    • たとえば、zdt.until(other)のように使える。

結論

  • Temporal APIはJavaScriptで時間を扱う方法を革新的に変える
  • この記事では、人間が読める日付とUTCの日付の違い、そしてTemporal.ZonedDateTimeオブジェクトを使ってそれを正確に表現する方法を扱った
  • 次の記事では、Instant、PlainDate、Durationなど他の興味深いオブジェクトを探る予定

GN⁺の意見

  • JavaScript開発者を長年悩ませてきた日付・時刻処理の問題は、Temporal APIによって解決されるだろう
  • タイムゾーンやDSTの問題を自動的に処理できるため、グローバルアプリケーションの開発で非常に有用
  • 既存のDateオブジェクトとの互換性およびマイグレーションの問題は考慮すべき点
  • Temporal APIは明確で直感的な方法で設計されており、さまざまなカレンダーシステムをサポートするなど、国際化対応の面でも優れている
  • このような変化は、JavaScript開発者の生産性を大きく向上させると期待される

5件のコメント

 
kyc1682 2024-08-26

ついに!

 
hongminhee 2024-08-26

参考までに、DenoはすでにTemporal APIを内蔵しています。

 
huiya 2024-08-26

すごい。グローバルサービスを設計するとき、日付はいつも頭の痛い問題でした。
これ、一度使ってみたいですね

 
jjpark78 2024-08-26

本当に、ついにmomentやdayjsを使わなくてもよくなるのでしょうか

 
GN⁺ 2024-08-25
Hacker Newsの意見
  • Javascriptで日付と時刻を扱うのは非常に難しい

    • Momentライブラリは日付と時刻を混同し、多くの問題を引き起こす
    • PythonのArrowライブラリも同じ誤りを犯している
    • RustのChronoライブラリは予測可能で欠陥が少ない
    • JSのDateとMomentは使いにくい
  • 新しいAPIがJSのタイムゾーン問題を解決すると期待されている

    • 特定のタイムゾーンは正しくパースできるが、他の場合にはUTCと見なしてしまう問題がある
    • 前職でこの問題にかなり苦しめられた
  • タイムスタンプを人間が読める日付に変換する関数は単射ではない

    • injectivityとwell-definednessの概念を混同している
    • タイムスタンプtに対して一意な人間可読の日付xが存在するわけではない
  • 時間処理の難易度曲線についてのジョーク

    • 初心者はUTCタイムスタンプだけを使う
    • 中級者はタイムゾーンを保存して変換すべきだと主張する
    • 上級者は再びUTCタイムスタンプだけを使う
  • 未来の日付の例をもっと使えば記事はより説得力が増すはず

    • タイムスタンプを記録する際にはUTCと位置情報だけが必要
    • 銀行の例は単なるUXの問題であり、情報損失ではない
  • 時間処理を理解できず不安を感じているユーザー

    • Pythonのような言語での時間処理の問題を理解するための良い入門書を求めている
  • 良いdatetime標準を持つことは戦いの半分にすぎない

    • 残り半分は広く採用されることだ
    • 他のシステムとの互換性のためには、ISO文字列やunixタイムスタンプに変換するのが安全だ
  • ISO日付文字列は正確な情報を捉えるべきだ

    • JavaScriptや他の言語に組み込みの構造が必要だという考えには疑問がある
    • TemporalとDateは単純な問題を複雑に解決している
  • Postgresでこの問題をどう扱うべきかという質問

  • Temporalが実際に導入されるという証拠は不足している

    • 多くの有望なJS提案と同じく、長いあいだ議論されるだけになっている