概要
JavaScriptで開発をしている時に、2023年2月31日など暦上存在しない日付に対してDate.parse
を実行する機会がありました。そうしたら、MDNの説明と異なる動きが起きたため、Date.parse
の挙動はブラウザによって異なることを知りました。そこで今回はブラウザ毎のDate.parse
の挙動の違いを調査しました。
結論
- ブラウザのJSエンジン毎に
Date.parse
の挙動が一部異なります。 - 異なる点として、Chromeは2023年2月31日を2023年3月3日と繰り上げた日付を返却するのに対し、SafariとFirefoxは
NaN
を返却します。
動作が異なる原因
ブラウザ上でのJavaScriptの挙動はJSエンジンによって決定されます。
ChromeやSafariではそれぞれ違うJSエンジンが使われています。JSエンジンが違えば挙動も違うため、Date.parse
の挙動に差異が生じていると考えられます。
調査方法
MDN曰く、Date.parse
は日時を表す文字列を解釈します。対応するよう明示的に指定されているのはISO8601形式YYYY-MM-DDTHH:mm:ss.sssZ
です。今回はこの形式の文字列でDate.parse
の挙動の違いを調査します。
例:2023-02-09T14:30:30.111+0900
は2023年2月9日14時30分30秒111ミリ秒(日本時間)を指します。
型 | 意味 | 例 |
---|---|---|
YYYY | 年 | 2023 |
MM | 月 | 02 |
DD | 日付 | 09 |
T | 日付と時刻の区切り | T |
HH | 時間 | 14 |
mm | 分 | 30 |
ss | 秒 | 30 |
sss | ミリ秒 | 111 |
Z | タイムゾーン | +0900 |
下記の調査対象の日付を確認し、返り値がNaN
ではない場合、返り値をもとに日付を作成してDate.parse
の引数とどのような違いがあるか確認します。
調査対象の日付
- 存在する日付(2023年2月10日)
- 存在しない日付(2023年2月99日)
- 特定の月には存在しない日付(2023年2月31日)
- 閏日(2024年2月29日)
調査対象のブラウザはそれぞれ使われているJSエンジンが異なる、Chrome、Safari、Firefoxを対象とします。
存在する日付の場合(2023年2月9日)
// Chromeの場合
console.log(Date.parse('2023-02-09T00:00:00.000+0900'))
// 1675868400000
console.log(new Date(1675868400000))
// Thu Feb 09 2023 00:00:00 GMT+0900 (日本標準時)
// Safariの場合
console.log(Date.parse('2023-02-09T00:00:00.000+0900'))
// 1675868400000
console.log(new Date(1675868400000))
// Thu Feb 09 2023 00:00:00 GMT+0900 (日本標準時)
// Firefoxの場合
console.log(Date.parse('2023-02-09T00:00:00.000+0900'))
// 1675868400000
console.log(new Date(1675868400000))
// Thu Feb 09 2023 00:00:00 GMT+0900 (日本標準時)
存在しない日付(2023年2月99日)
// Chromeの場合
console.log(Date.parse('2023-02-99T00:00:00.000+0900'))
> NaN
// Safariの場合
console.log(Date.parse('2023-02-99T00:00:00.000+0900'))
> NaN
// Firefoxの場合
console.log(Date.parse('2023-02-99T00:00:00.000+0900'))
> NaN
他の月には存在するが、特定の月には存在しない日付(2023年2月31日)
// Chromeの場合
console.log(Date.parse('2023-02-31T00:00:00.000+0900'))
> 1677769200000
console.log(new Date(1677769200000))
> Fri Mar 03 2023 00:00:00 GMT+0900 (日本標準時)
// Safariの場合
// 他の月には存在するが、特定の月には存在しない日付(2023年2月31日)
console.log(Date.parse('2023-02-31T00:00:00.000+0900'))
> NaN
// Firefoxの場合
console.log(Date.parse('2023-02-31T00:00:00.000+0900'))
> NaN
閏年など、場合によっては存在する日付(2024年2月29日)
// Chromeの場合
console.log(Date.parse('2024-02-29T00:00:00.000+0900'))
> 1709132400000
console.log(new Date(1709132400000))
> Thu Feb 29 2024 00:00:00 GMT+0900 (日本標準時)
// Safariの場合
console.log(Date.parse('2024-02-29T00:00:00.000+0900'))
> 1709132400000
console.log(new Date(1709132400000))
> Thu Feb 29 2024 00:00:00 GMT+0900 (日本標準時)
// Firefoxの場合
console.log(Date.parse('2024-02-29T00:00:00.000+0900'))
> 1709132400000
console.log(new Date(1709132400000))
> Thu Feb 29 2024 00:00:00 GMT+0900 (日本標準時)
まとめ
条件 | Chrome | Safari | Firefox |
---|---|---|---|
存在する日付(2023年2月10日) | Thu Feb 09 2023 00:00:00 GMT+0900 (日本標準時) | Thu Feb 09 2023 00:00:00 GMT+0900 (日本標準時) | Thu Feb 09 2023 00:00:00 GMT+0900 (日本標準時) |
存在しない日付(2023年2月99日) | NaN | NaN | NaN |
特定の月には存在しない日付(2023年2月31日) | Fri Mar 03 2023 00:00:00 GMT+0900 (日本標準時) | NaN | NaN |
閏日(2024年2月29日) | Thu Feb 29 2024 00:00:00 GMT+0900 (日本標準時) | Thu Feb 29 2024 00:00:00 GMT+0900 (日本標準時) | Thu Feb 29 2024 00:00:00 GMT+0900 (日本標準時) |
Date.parse
の挙動はブラウザ(JSエンジン)毎によって一部異なることがわかりました。
Chromeで2023年2月31日を入力すると、2023年3月3日を返却しました。一方で、SafariとFirefoxで2023年2月31日を入力した場合、NaN
を返すという挙動の違いを確認することができました。