GASでDate関数のMonthが月末に実行した時だけ月がズレる問題を解消した件

#JavaScript
writtdden by GOATしゃっちょ

はだざみいでございまさーねー。

でさーねー。

とハリウッドザコシャチョウです。

09/06から今年も月見バーガーが始まりました。大好きです。

やっぱりチーズ月見が1番でさーね。

ということで、今回のテーマです。

事象解説

AppScrpitで動作するGASを使って、スプレッドシートを処理しておりました。

やっていたことは本当に単純で、
Date関数で01月~12月まで回して文字列を生成していただけです。

function hoge {
 var dt = new Date();
 for(var i = 0; i < 12; i++){
  dt.setFullYear(2023);
  dt.setMonth(i);
  var d1 = Utilities.formatDate(dt, 'Asia/Tokyo', 'yyyy/MM');
  console.log(dt);
 }
}

コードで書くとこんな感じ。(JavascriptじゃなくてGASです。)

期待結果としては、

と本当に単純!ただ月をyyyy/MMの形式で出力したかっただけです。

ですが、忘れもしません。

2023/08/31にこのGASを実行すると・・・月がひと月ズレてしまうんです!
2023/2が期待結果のパターンで2023/3が表示されてしまいます!

なんでだ!!!この間まで動いていたのに。。。。

検証

Date関数の初期値

そもそも、

var dt = new Date();

上記の時は何が入っているんだ・・?

なるほど!実行日した時の日時が入りますね!

(GASはGoogleのサーバで動作するので、PCのシステム日時では無いと思われる)

2023/08/31にセットして日付まで見てみる

はい。日時を2023/08/31にしてみて、フォーマットをyyyy/MM/ddに変えました。
(Monthは0~11なので8月は7でOK)

この後に、

dt.setMonth(8);

を実施してみましょう!

なんということでしょう。

期待結果は、2023/09/30でした。

ですが、9月には31日は存在しないので、10/01になってしまうんですね!
今回は年月日を見たのでわかりやすかったですが、「年月」で見てた時は「???」状態でした。

ちなみに

dt.setMonth(9);

とすると、

うわーおって感じでした!年月だけみると

2023/8
2023/10
2023/10

と表示されるので、一瞬、怪奇現象だと本当に思いました。

原因は
dt=2023/08/31
の状態で、
setMonth(8);
とすると、
2023/09/31は無いので、2023/10/1になる。

setMonth(9);
にすると、dt=2023/08/31のから月を10月に変えただけなので、2023/10/31になる

といった事ですね。

解決方法

解決策として、「年月」までしか使わない場合でも、しっかり「日」をセットしてあげればいいだけです。

こうすればいいだけですね。

最後に

思いもよらぬ落とし穴でした!

まだまだ知らないことはたくさんありますね。

今回の教訓としては、Dateの初期値は現在日!そこから加算する場合はシステム実行日によって初期値が変わるので注意しよう!

でさーね。

あっした!!(ありがとうございました。)

Favorite