Date
)Date
を避けるZ
を追加するこの章では、日付を扱うためのJavaScriptのAPI、Date
クラスについて説明します。
Date
を避けるJavaScriptのDate
APIは使い勝手が悪いため、日付に関する処理にはライブラリに依存するのが最善です。一般的なライブラリには以下があります。
これらのライブラリのメリットとデメリットについては、ブログ記事“Why you shouldn’t use Moment.js…”を参照してください。
さらに、TC39はJavaScriptの新しい日付APIに取り組んでいます:temporal
.
2つの重要な点があります。
ツリーシェイキングは、ライブラリのサイズを大幅に削減できます。これは、どこかにインポートされているライブラリのエクスポートのみをウェブサーバーにデプロイするテクニックです。関数はクラスよりもツリーシェイキングに適しています。
タイムゾーンのサポート:後で説明するように、Date
はタイムゾーンをサポートしていません。これは多くの落とし穴を生み出し、重要な弱点です。日付ライブラリがタイムゾーンをサポートしていることを確認してください。
UTC、Z、GMTは、似ていますが微妙に異なる時間指定方法です。
UTC(協定世界時)は、すべてのタイムゾーンの基準となる時間標準です。タイムゾーンはUTCを基準に指定されます。つまり、どの国や地域もUTCを現地時間として使用していません。
Z(ズールータイムゾーン)は、UTC+0の別名として、航空や軍事でよく使われる軍用タイムゾーンです。
GMT(グリニッジ標準時)は、一部のヨーロッパとアフリカの国で使用されるタイムゾーンです。UTCプラスゼロ時間であり、UTCと同じ時刻です。
出典
日付は次の時間標準をサポートしています。
操作によっては、これらのオプションの一部しか使用できません。たとえば、日付を文字列に変換したり、月の曜日などの時間単位を抽出したりする場合、現地時間とUTCのいずれかしか選択できません。
内部的には、日付はUTCとして保存されます。現地時間との間の変換では、必要なオフセットは日付によって決定されます。次の例では、現地時間はEurope/Parisです。
// CEST (Central European Summer Time)
.equal(
assertnew Date('2122-06-29').getTimezoneOffset(), -120);
// CET (Central European Time)
.equal(
assertnew 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日です。
各操作でサポートされる時間標準を文書化する
この章の残りの部分では、各操作でサポートされる時間標準が示されています。
タイムゾーンを指定できないことには、2つの欠点があります。
複数のタイムゾーンをサポートすることが不可能になります。
場所固有のバグが発生する可能性があります。たとえば、前の例は、実行場所によって異なる結果を生成します。安全を期するためには
Z
またはタイムオフセットを使用する(詳細は次のセクションを参照)。日時形式は、以下を記述します。
Date.parse()
new Date()
Date.prototype.toISOString()
以下は、.toISOString()
によって返される日時文字列の例です。
'2033-05-28T15:59:59.123Z'
日時形式には次の構造があります。
日付形式:Y=年; M=月; D=日
YYYY-MM-DD
YYYY-MM
YYYY
時間形式:T=セパレータ(文字列'T'
); H=時; m=分; s=秒とミリ秒; Z=ズールータイムゾーン(文字列'Z'
)
THH:mm:ss.sss
THH:mm:ss.sssZ
THH:mm:ss
THH:mm:ssZ
THH:mm
THH:mmZ
日時形式:日付形式に時間形式が続きます。
YYYY-MM-DDTHH:mm:ss.sssZ
Z
(UTC+0)の代わりに、UTCからのタイムオフセットを指定することもできます。
THH:mm+HH:mm
などTHH:mm-HH:mm
などZ
を追加する文字列の最後にZ
を追加すると、日付のパースは異なる場所で異なる結果を生成しません。
Z
なし:入力は1月27日(Europe/Parisタイムゾーン)、出力は1月26日(UTC)。
> new Date('2077-01-27T00:00').toISOString()'2077-01-26T23:00:00.000Z'
Z
あり:入力は1月27日、出力は1月27日。
> new Date('2077-01-27T00:00Z').toISOString()'2077-01-27T00:00:00.000Z'
時間値は、1970年1月1日00:00:00 UTCからのミリ秒数によって日付を表します。
時間値を使用して日付を作成できます。
const timeValue = 0;
.equal(
assertnew Date(timeValue).toISOString(),
'1970-01-01T00:00:00.000Z');
日付を数値に変換すると、時間値が返されます。
> Number(new Date(123))123
順序演算子はオペランドを数値に変換します。したがって、これらの演算子を使用して日付を比較できます。
.equal(
assertnew Date('1972-05-03') < new Date('2001-12-23'), true);
// Internally:
.equal(73699200000 < 1009065600000, true); assert
次のメソッドは時間値を作成します。
Date.now(): number
(UTC)
現在時刻を時間値として返します。
Date.parse(dateTimeStr: string): number
(現地時間、UTC、タイムオフセット)
dateTimeStr
を解析し、対応する時間値を返します。
Date.UTC(year, month, date?, hours?, minutes?, seconds?, milliseconds?): number
(UTC)
指定されたUTC日時に対する時間値を返します。
Date.prototype.getTime(): number
(UTC)
Dateに対応する時間値を返します。
Date.prototype.setTime(timeValue)
(UTC)
timeValue
によってエンコードされた日付にthis
を設定します。
new Date(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, milliseconds?: number)
(現地時間)
2つのパラメータには落とし穴があります。
month
では、0は1月、1は2月などです。
year
が0≦year
≦99の場合、1900が加算されます。
> new Date(12, 1, 22, 19, 11).getFullYear()1912
そのため、この章の他の場所では、時間単位year
を避け、常にfullYear
を使用します。しかし、この場合は選択肢がありません。
例
> new Date(2077,0,27, 21,49).toISOString() // CET (UTC+1)'2077-01-27T20:49:00.000Z'
入力時刻(21)と出力時刻(20)が異なることに注意してください。前者は現地時間、後者はUTCを参照しています。
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'
new Date(timeValue: number)
(UTC)
> new Date(0).toISOString()'1970-01-01T00:00:00.000Z'
new Date()
(UTC)
new Date(Date.now())
と同じです。
日付には時間単位のゲッターとセッターがあります。たとえば
Date.prototype.getFullYear()
Date.prototype.setFullYear(num)
これらのゲッターとセッターは次のパターンに従います。
Date.prototype.get«Unit»()
Date.prototype.set«Unit»(num)
Date.prototype.getUTC«Unit»()
Date.prototype.setUTC«Unit»(num)
サポートされている時間単位は次のとおりです。
FullYear
Month
:月(0~11)。落とし穴:0は1月などです。Date
:月の曜日(1~31)Day
(ゲッターのみ):曜日の番号(0~6、0は日曜日)Hours
:時(0~23)Minutes
:分(0~59)Seconds
:秒(0~59)Milliseconds
:ミリ秒(0~999)前述のパターンに従わないゲッターがもう1つあります。
Date.prototype.getTimezoneOffset()
現地時間とUTCの差を分単位で返します。たとえば、Europe/Parisの場合、-120
(CEST、中央ヨーロッパ夏時間)または-60
(CET、中央ヨーロッパ時間)を返します。
> new Date('2122-06-29').getTimezoneOffset()-120
> new Date('2122-12-29').getTimezoneOffset()-60
日付の例
const d = new Date(0);
Date.prototype.toTimeString()
(現地時間)
> d.toTimeString()'01:00:00 GMT+0100 (Central European Standard Time)'
Date.prototype.toDateString()
(現地時間)
> d.toDateString()'Thu Jan 01 1970'
Date.prototype.toString()
(現地時間)
> d.toString()'Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)'
Date.prototype.toUTCString()
(UTC)
> d.toUTCString()'Thu, 01 Jan 1970 00:00:00 GMT'
Date.prototype.toISOString()
(UTC)
> d.toISOString()'1970-01-01T00:00:00.000Z'
次の3つのメソッドは、実際にはECMAScriptの一部ではなく、ECMAScript国際化APIの一部です。そのAPIは日付のフォーマットに関する多くの機能(タイムゾーンのサポートを含む)を持っていますが、パース機能はありません。
Date.prototype.toLocaleTimeString()
Date.prototype.toLocaleDateString()
Date.prototype.toLocaleString()
練習問題:日付文字列の作成
exercises/dates/create_date_string_test.mjs