このページは?
javascriptのnew Date(2024, 1)
とnew Date('2024-1')
の違いについて説明することができますか?
あまり直感的な仕様じゃなく、混乱したのでまとめます。開発者ツールのconsoleで気軽に確かめられることなので、是非自分でも動かしながら読んでください。
内容
monthにはmonthIndexが格納されている
前提として、Date型のmonth要素には月(1月-12月)ではなく、 monthIndex(0-11)が格納されています。
つまり、単純にgetMonth()
するとずれた値が返ってくる。
// date: 2024年1月
date.getMonth()
// 結果: 0
なので、現実世界の月として扱う際は+1する必要がある。
console.log(`${date.getFullYear()}年${date.getMonth()+1}月`)
// 結果: 2024年1月
new Date()するときの注意
ここからが本題です。上述の仕様に関連し、new Date()する際に、intを与えるかstringを与えるかで得られる結果が変わってきます。
// monthIndexに1が格納されるので2024年2月が返ってくる
new Date(2024, 1)
// 結果: Thu Feb 01 2024 00:00:00
// stringを与えると、そのまま2024年1月が返ってくる
new Date('2024-1')
// 結果: Mon Jan 01 2024 00:00:00
この仕様に惑わされて、画面上に実際とはズレた月が表示されるインシデントを起こしてしまいました。。
まとめ
month変数に現実世界の月の値が格納されているのかmonthIndexの値が格納されているのかコードから読み取るのは辛いので、その辺りの取り扱いについてチーム内で認識を合わせておくことが大切だと思います。自分としては、monthには現実世界の月の値を格納しておき、new Date()
する際にmonthIndex
に変換する方針が丸いのではないかなと考えています。
monthIndex
を扱う為に +1
-1
するのはマジックナンバーになってしまいますが、Date周りで扱っていればまあ察することができるだろうという。
// dateを生成する時
const year = 2024
const month = 1
new Date(year, month - 1)
// 結果: Mon Jan 01 2024 00:00:00
// monthを取得する時
const date = new Date('2024-1')
const month = date.getMonth() + 1
console.log(month)
// 結果: 1