ES5以降では、Date.parse()
に不正な日時を渡した場合、NaN
を返す……が、不正な日時の解釈に実装によって違いがあることを今さら知った。タイトルのように2015-02-31を渡すと、Firefox 67はNaN
を返すが、Chrome 75などでは良きにはからって、つまり2015-03-03とみなしてくれる。書式そのものの解釈の違いだけでなく、こんなところにも非互換性が埋まっていて、まんまとハマった。
Chrome 75やEdge 18、Node.js v12.0.0では以下のようになる。対してFirefox 67は2番目のみNaN
を返す。
console.log(Date.parse("2015-02-28")); // 1425081600000
console.log(Date.parse("2015-02-31")); // 1425340800000
console.log(Date.parse("2015-03-03")); // 1425340800000
セケンではMoment.jsか何かを使い、Date
オブジェクトには一切触らないはずなので、あまり問題にならない。小さな書き捨てスクリプトで、おおむね日時っぽい文字列を何やらやる時にハマるかもしれない。
ES5の仕様では不正な日時ならNaN
を返すとなっているが、どうなっていると不正なのかは明確ではない。日付と時刻の書式でDDは01から31まで許可されているので、2015-02-31は書式として正しく、不正な日時ではないと考えられる。一方で2015-02-31は存在しない日付なので、不正な日時だとも考えられる。
不正な日時の定義があいまいである以上、どちらの実装も間違ってはいない。のかもしれない。と思う。よう知らんけど。