GASで日付の計算をしたときに、記述の仕方によって処理結果が大きく変わってしまいましたので投稿します。
参考サイト
成功した記述例
// 今日から3日前の日付
var date = new Date(); // 今日の日付を取得
var newDate = new Date(date.getYear(), date.getMonth(), date.getDate() - 3); // 3日前にする
// 今日から5日後の日付
var newDate = new Date(date.getYear(), date.getMonth(), date.getDate() + 5); // 5日前にする
for文を使用
var date = new Date(); // 今日の日付を取得
for( var i = 1; i < 7; i++ ){
var newDate = new Date(date.getYear(), date.getMonth(), date.getDate() - i); // 1日ずつ日付をさかのぼる
Logger.log( Utilities.formatDate( newDate, 'Asia/Tokyo', 'yyyy/M/d') ); // ログに出力
}
失敗した記述例1
for文を使用した場合に以下のような記述にしてしまうと思わぬ処理結果になります。
説明を分かりやすくするために日付を指定しておきます。
var date = new Date("2019/12/2"); // 日付を指定
var day = date.getDate(); // 日付のみ取得
for( var i = 1; i < 7; i++ ){
date.setDate(day - i);
Logger.log( Utilities.formatDate( date, 'Asia/Tokyo', 'yyyy/M/d') );
}
上記のように getYear()
getMonth()
を書かずに getDate()
のみとし、 setDate()
を使用すると以下のように途中から1月ずつさかのぼってしまいます。
出力結果
2019/12/1
2019/11/30
2019/10/30
2019/9/28
2019/8/28
2019/7/27
失敗した記述例2
今度は date.getDate()
を変数に入れずに直接記述したものです。
var date = new Date("2019/12/2"); // 日付を指定
for( var i = 1; i < 7; i++ ){
date.setDate(date.getDate() - i);
Logger.log( Utilities.formatDate( date, 'Asia/Tokyo', 'yyyy/M/d') );
}
出力結果
2019/12/1
2019/11/29
2019/11/26
2019/11/22
2019/11/17
2019/11/11
このように日付が1日ずつではなくさかのぼる日数がどんどん増えていきます。
減算の例のみをあげましたが、加算の場合でも同様の結果になります。
記述例1の方は月が変わる処理をしてしまうと、1月ずつさかのぼってしまいますが月が変わらなければ正常に処理が可能です。
なお、どちらのパターンでもfor文を使用しなければ指定した数字での計算が可能です。
var date = new Date("2019/12/2"); // 日付を指定
var day = date.getDate(); // 日付のみ取得
date.setDate(day - 3);
Logger.log( Utilities.formatDate( date, 'Asia/Tokyo', 'yyyy/M/d') );
出力結果
2019/11/29
結論
日付の計算をする場合は getYear()
getMonth()
getDate()
のすべてを指定しておくとよさそうです。
new Date(date.getYear(), date.getMonth(), date.getDate() - n);