ので書き残しておきます。まあ「月末にだけ」という条件が見えた時点で勝ち確なんだけどね!

先にまとめ

  • new Date() して setMonth() 等で組み立てる実装
  • 試験データは 11 月 10 日(たぶん強い理由はない)
  • JS が 11 月 31 日という存在しない日付を 12 月 01 日と判断
  • new Date(year, month, date) のように最初から年月日を全部与えて解決
  • なお自分の WSL 環境の時刻がずれており報告時に手元では発生しなかった
  • あと時間とは関係ないところへ波及してコケていた

問題のある書き方

const date = new Date(); // 現在時刻 => 2023-05-31
date.setFullYear(2022); // 2022-05-31
date.setMonth(10); // 2022-11-31 => 2022-12-01
date.setDate(10); // 2022-12-10

引数なしで new Date() すると現在時刻になります。そこへ年月日を順に設定しているわけですが、11 月(添え字で 10)を与えたところ 11 月 31 日という存在しない日付になってしまい、これが 12 月 01 日へと正規化?されます。この後に 10 日を設定しても月は戻らず 12 月のままなので、試験の想定とずれてしまうわけです。

最初から年月日を全部与えて解決

const date = new Date(2022, 10, 10) // 2022-11-10

Date は色々引数を受け取れるんだけど、整数値で年月日時刻秒とミリ秒まで順に受け取れます。結果的に短くもなりました。

その他

月番号

MDN 見てたら month じゃなくて monthIndex という表現を使ってい(る場面があっ)た。そっちの方がわかりやすいね。

年と年月日

VS Code + TS のポップアップで知ったけど setFullYear() も年だけじゃなくて年月日で受け取れるんだ知らなかった。

setFullYear(yearValue, monthValue, dateValue)

日付の正規化

なんかうまいこと計算するよなと思って仕様を見てみた。

数字だけ見て Unix 時間的なものを組み立ててくっぽい。なので日付としておかしなもの、例えば 13 月(12)とか 0 日とか、なんなら -3 日とかでもそのまま受け入れて計算して合算した後に年月日へ変換するみたいな感じ。

おしまい

昨日は通っていたとの話だったので時間系かなとは思ったんだけど、報告受けたとき手元で試したら試験が通ったのでじっくりコールスタックをたどる旅を初めてしまった。そうだよなあ WSL なんだよなあ。もっと早く解決できた気がする。

それにしても、あるあるとはいえ実際に目の当たりにすると「あるんだ~」ってなるね!