Javascript プログラミング

setMonth()による迂闊な日付操作で月末限定のバグを出した話

月末にだけ発生するバグ!?

この記事で作ったグーグルカレンダーへのワンライナーアプリは、その後も使っています。

結構アクセスも多くてこのブログの中では人気記事に入ります。

しかし、今日(2022年8月31日)、歯医者の受付で予約したばかりの日時を入れたのですが、Googleカレンダーに反映されません。

変だなぁと思って検索してみると、11月に登録したハズの予定が12月の同じ日に登録されています。

試しにいろいろな予定を入れてみましたが、どれも1ヶ月後ろにずれて登録されていました。

これまでこんなコトは無かったので、最初はGASの関数に仕様変更でもあったのかと思いました。

ところが検索してもそんな情報はありません。これは私のコードに問題がありそうです。

そんなわけでシンプルなコードで実験してみたところ、現象が再現できました。

const time = new Date();
console.log(time);
//2022-08-31T12:30:27.219Z

time.setMonth(10);//timeを11月に変更
console.log(time);
//2022-12-01T12:30:27.219Z

まず、timeオブジェクトに現在の日付(8月31日)を入れます。

次に、timeオブジェクトの月だけを11月に変更しました。

するとtimeオブジェクトは12月になってしまいました。

月の日数の違いでズレが生じる

月がずれてしまう理由は11月が30日までしかないためでした。

8月31日の月だけを11にすると11月31日になります。

しかし11月は30日しかないので、Dateオブジェクトは自動的にオーバーフロー処理を行って12月1日に変更しました。バグどころか、気が利いているのでした。

28日までであればこうした問題は生じません。

このため月末に限って起きるバグとなってしまいました。

検索してみると結構たくさん見つかるので、やりがちなミスみたいです。

カレンダー登録アプリの方は、以下のように変更しました。

//変更前
  eventTime.setMonth(data[0] - 1);//月を設定。月末には、ここで日がオーバーフローして月がズレる場合がある
  eventTime.setDate(data[1]);

//変更後
  eventTime.setDate(1);//いったん日付を1にする
  eventTime.setMonth(data[0] - 1);//月を変更
  eventTime.setDate(data[1]);//日付を変更

-Javascript, プログラミング