焦らず学ぶJavaScript (ES2022版)
本書をサポートしてください:購入する または 寄付する
(広告です。ブロックしないでください。)

44章 日付 (Date)



この章では、日付を扱うためのJavaScriptのAPI、Dateクラスについて説明します。

44.1章 ベストプラクティス:組み込みのDateを避ける

JavaScriptのDate APIは使い勝手が悪いため、日付に関する処理にはライブラリに依存するのが最善です。一般的なライブラリには以下があります。

これらのライブラリのメリットとデメリットについては、ブログ記事“Why you shouldn’t use Moment.js…”を参照してください。

さらに、TC39はJavaScriptの新しい日付APIに取り組んでいます:temporal.

44.1.1項 日付ライブラリで探すべき点

2つの重要な点があります。

44.2章 時間標準

44.2.1項 背景:UTCとZとGMT

UTC、Z、GMTは、似ていますが微妙に異なる時間指定方法です。

出典

44.2.2項 日付はタイムゾーンをサポートしていません

日付は次の時間標準をサポートしています。

操作によっては、これらのオプションの一部しか使用できません。たとえば、日付を文字列に変換したり、月の曜日などの時間単位を抽出したりする場合、現地時間とUTCのいずれかしか選択できません。

内部的には、日付はUTCとして保存されます。現地時間との間の変換では、必要なオフセットは日付によって決定されます。次の例では、現地時間はEurope/Parisです。

// CEST (Central European Summer Time)
assert.equal(
  new Date('2122-06-29').getTimezoneOffset(), -120);
  
// CET (Central European Time)
assert.equal(
  new Date('2122-12-29').getTimezoneOffset(), -60);

日付を作成または変換する際には、使用されている時間標準に注意する必要があります。たとえば、new Date()は現地時間を使用し、.toISOString()はUTCを使用します。

> new Date(2077, 0, 27).toISOString()
'2077-01-26T23:00:00.000Z'

日付は0を1月と解釈します。月の曜日は現地時間では27日ですが、UTCでは26日です。

  各操作でサポートされる時間標準を文書化する

この章の残りの部分では、各操作でサポートされる時間標準が示されています。

44.2.2.1項 タイムゾーンを指定できないことの欠点

タイムゾーンを指定できないことには、2つの欠点があります。

44.3章 背景:日時形式(ISO)

日時形式は、以下を記述します。

以下は、.toISOString()によって返される日時文字列の例です。

'2033-05-28T15:59:59.123Z'

日時形式には次の構造があります。

Z(UTC+0)の代わりに、UTCからのタイムオフセットを指定することもできます。

44.3.1項 ヒント:日付パースを確定的にするためにZを追加する

文字列の最後にZを追加すると、日付のパースは異なる場所で異なる結果を生成しません。

44.4章 時間値

時間値は、1970年1月1日00:00:00 UTCからのミリ秒数によって日付を表します。

時間値を使用して日付を作成できます。

const timeValue = 0;
assert.equal(
  new Date(timeValue).toISOString(),
  '1970-01-01T00:00:00.000Z');

日付を数値に変換すると、時間値が返されます。

> Number(new Date(123))
123

順序演算子はオペランドを数値に変換します。したがって、これらの演算子を使用して日付を比較できます。

assert.equal(
  new Date('1972-05-03') < new Date('2001-12-23'), true);

// Internally:
assert.equal(73699200000 < 1009065600000, true);

44.4.1項 時間値の作成

次のメソッドは時間値を作成します。

44.4.2項 時間値の取得と設定

44.5章 日付の作成

44.5.1項 数値による日付の作成

new Date(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, milliseconds?: number) (現地時間)

2つのパラメータには落とし穴があります。

> new Date(2077,0,27, 21,49).toISOString() // CET (UTC+1)
'2077-01-27T20:49:00.000Z'

入力時刻(21)と出力時刻(20)が異なることに注意してください。前者は現地時間、後者はUTCを参照しています。

44.5.2項 文字列からの日付のパース

new Date(dateTimeStr: string) (現地時間、UTC、タイムオフセット)

最後にZがある場合、UTCが使用されます。

> new Date('2077-01-27T00:00Z').toISOString()
'2077-01-27T00:00:00.000Z'

最後にZまたはタイムオフセットがない場合、現地時間が使用されます。

> new Date('2077-01-27T00:00').toISOString() // CET (UTC+1)
'2077-01-26T23:00:00.000Z'

文字列に日付のみが含まれる場合、UTCとして解釈されます。

> new Date('2077-01-27').toISOString()
'2077-01-27T00:00:00.000Z'

44.5.3項 日付の作成方法その他

44.6章 ゲッターとセッター

44.6.1項 時間単位ゲッターとセッター

日付には時間単位のゲッターとセッターがあります。たとえば

これらのゲッターとセッターは次のパターンに従います。

サポートされている時間単位は次のとおりです。

前述のパターンに従わないゲッターがもう1つあります。

44.7章 日付を文字列に変換する

日付の例

const d = new Date(0);

44.7.1項 時刻を含む文字列

44.7.2項 日付を含む文字列

44.7.3項 日付と時刻を含む文字列

44.7.4項 その他のメソッド

次の3つのメソッドは、実際にはECMAScriptの一部ではなく、ECMAScript国際化APIの一部です。そのAPIは日付のフォーマットに関する多くの機能(タイムゾーンのサポートを含む)を持っていますが、パース機能はありません。

  練習問題:日付文字列の作成

exercises/dates/create_date_string_test.mjs