@sustny note

忘れっぽさを補うためのメモ

Moment.js(for GAS)の日付計算

Moment.gsとでも言うのがいいのだろうか。

GASのMoment.jsライブラリを使った日付操作でハマったのでメモ。

function daycalc() {
  var day =Moment.moment([2017,1,1]);
  //この日付をベースに仕様を確かめていく
  
  var day0 = day.clone().subtract(1,'days').format('YYYY/MM/DD');
  Logger.log(day0);
  //結果: 2017/01/31 ... 引き算する項目を"日"、引き算する値を"1"と指定すると日が1減る→わかる
  
  var day1 = day.clone().subtract(1,'months').format('YYYY/MM/DD');
  Logger.log(day1);
  //結果: 2017/01/01 ... 引き算する項目を"月"、引き算する値を"1"と指定すると変わらない→わからない
  
  var day2 = day.clone().subtract(2,'months').format('YYYY/MM/DD');
  Logger.log(day2);
  //結果: 2016/12/01 ... 引き算する項目を"月"、引き算する値を"2"と指定すると月が1減る→わかってきた
  
  var day3 = day.clone().subtract(0,'months').format('YYYY/MM/DD');
  Logger.log(day3);
  //結果: 2017/02/01 ... 引き算する項目を"月"、引き算する値を"0"と指定すると月が1増える→ですよね
  
  var day4 = day.clone().subtract(0,'years').format('YYYY/MM/DD');
  Logger.log(day4);
  //結果: 2017/02/01 ... 引き算する項目を"年"、引き算する値を"0"と指定すると月が1増える→おまえもか
  
  /* ----- 試しにnew Date()でもやってみよう ----- */
  var nday = new Date('2017/1/1');
  
  var nday1 = new Date(nday.getYear(), nday.getMonth(), nday.getDate());
  nday1 = Utilities.formatDate(nday1, 'JST', 'yyyy/MM/dd');
  Logger.log(nday1); //結果: 2017/01/01 →想定通りで安心
  
  var mday = new Date(day); //冒頭にMomentで作っておいた'2017/1/1'をnew Dateで取得してみる
  
  var mday1 = new Date(mday.getYear(), mday.getMonth(), mday.getDate());
  mday1 = Utilities.formatDate(mday1, 'JST', 'yyyy/MM/dd');
  Logger.log(mday1); //結果: 2017/02/01 →なんで!!!
  
  var day5 = Moment.moment(nday);
  day5 = day5.clone().subtract(0,'years').format('YYYY/MM/DD');
  Logger.log(day5);
  //結果: 2017/01/01 →new Date()で取得した日付をMoment()の引数にすると思ってたとおりに動く
  
  var day6 = Moment.moment(nday);
  day6 = day6.clone().subtract(1,'months').format('YYYY/MM/DD');
  Logger.log(day6);
  //結果: 2016/12/01 →同上
  
  var day7 = Moment.moment(nday);
  day7 = day7.clone().subtract(1,'days').format('YYYY/MM/DD');
  Logger.log(day7);
  //結果: 2016/12/31 →同上
}

当初は「月の計算が0始まりなの意味分からんわ〜!」って記事にしようと思ったのに、試しに年計算もやってみたらより混迷を極める結果になった。

Moment.moment()で日付を取得すると年がおかしくなるのに対して、new Date()で取得したものをMoment.moment()で取得し直し、それ以降の操作をMomentを使っておこなうと直感で分かりやすく日付の計算を扱えるようです(以下にその仕様でのみ操作をした例を記載します)。

function daycalc() {
  var base = new Date('2017/1/1');
  
  var day1 = Moment.moment(base);
  day1 = day1.clone().add(3,'years').format('YYYY/MM/DD');
  Logger.log(day1); //結果: 2020/01/01
  
  var day2 = Moment.moment(base);
  day2 = day2.clone().subtract(13,'months').format('YYYY/MM/DD');
  Logger.log(day2); //結果: 2015/12/01
  
  var day3 = Moment.moment(base);
  day3 = day3.clone().add(5,'days').format('YYYY/MM/DD');
  Logger.log(day3); //結果: 2017/01/06
}

ちなみに、Moment.jsをGASで使う方法については上の記事を参照しました。

tonari-it.com

以上です。