
photo credit: Kristjan Aunver 17 ruined in a day two via photopin (license)
みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
Google Apps Scriptで日付&時刻の便利ライブラリMoment.jsを使う方法についてお伝えしています。
前回の記事はコチラ。
Moment.jsで日時の加算・減算をする方法についてお伝えしました。
しかし、その際に使うaddメソッドとsubtractメソッドには実は注意点があります。
使うと元のmomentオブジェクト自身が変更されてしまうのです。
これを別の言葉で「破壊的」というのですが、元のmomentオブジェクトも変更されちゃうと困るときありますし、わけがわからなくなりやすいですよね。
ということで、今回はGoogle Apps Scriptでmomentオブジェクトに対する破壊的メソッドついてまたcloneメソッドで元のデータを変更しないで日時計算をする方法です。
では、行ってみましょう!
Dateオブジェクトの日時計算は破壊的
まずはDateオブジェクトになりますが、以下のような日時の加算・減算をするスクリプトを実行してみましょう。
function calcDate(){ var date = new Date('2017/2/1'); var date1 = new Date(date.setMonth(date.getMonth()+1)); //2017/3/1 }
dateに対してgetMonthしたものにプラス1をしてsetMonthをします。簡単に言うと一月後になるわけですね。
では、以下のように、その後にdateの日にちをマイナス3してdate2に代入したとしましょう。
function calcDate(){ var date = new Date('2017/2/1'); var date1 = new Date(date.setMonth(date.getMonth()+1)); //2017/3/1 var date2 = new Date(date.setDate(date.getDate()-3)); //2017/1/29ではなくて2017/2/26 }
おそらく皆さんもdate2の値として「2017/1/29」を期待していると思うのですが、実はその値は「2017/2/26」になってしまいます。
このような事態が発生する理由は、setMonthやsetDateなどのメソッドが元のDateオブジェクト自体を変更してしまうという特性を持っているからなんですね。
このような特性を持つメソッドを「破壊的メソッド」と言います。
momentオブジェクトの日時計算も破壊的
前回の記事では、Moment.jsライブラリのaddメソッド、subtractメソッドで簡単に日時の計算をする方法をお伝えしたのですが、実はこれらのメソッドも残念ながら「破壊的メソッド」です。
以下スクリプトも、前述のDateオブジェクトと同様の結果となってしまうのです。
function calcDate(){ var m = Moment.moment('2017/2/1') var m1 = m.add(1,'months'); //2017/3/1 var m2 = m.subtract(3,'d'); //2017/2/26 }
ですから、後半のsubtractメソッドも、元の「2017/1/29」に対して実行をしたいのであれば
function calcDate(){ var m = Moment.moment('2017/2/1') var m1 = Moment.moment(m); //2017/2/1 m1 = m1.add(1,'months'); //2017/3/1 var m2 = Moment.moment(m); //2017/2/1 m2 = m2.subtract(3,'d'); //2017/1/29 }
このように、一度momentオブジェクトを別のmomentオブジェクトにコピーしてから、その別のオブジェクトに対してaddメソッドやsubtractメソッドを実行する必要が出てきます。
んー、ちょっと面倒ですよね。
cloneメソッドでmomentオブジェクトのクローンを作る
そんな時に、momentオブジェクトの複製を作るcloneメソッドが便利です。
こう書きます。
これで、momentオブジェクトのコピーのオブジェクトが生成されます。
例えば、前述の加算してから減算のスクリプトは
function calcDate(){ var m = Moment.moment('2017/2/1') var m1 = m.clone().add(1,'months'); //2017/3/1 var m2 = m.clone().subtract(3,'d'); //2017/1/29 Logger.log(m.format()); //2017/2/1 }
と書けばOKです。
このように、cloneメソッドで複製をしたものに対してaddメソッド、subtractメソッドを実行することで、元のmomentオブジェクトは破壊されなくて済みます。
まとめ
以上、Google Apps Scriptでmomentオブジェクトに対するaddメソッド、subtractメソッドを使うときの注意点、そしてcloneメソッドを使って元のオブジェクトを変更せずに日時計算を行う方法でした。
破壊的メソッド…名前はかっこいいですけど、知らないと頭の中がむちゃくちゃになりそうですね。
ぜひ、その存在とcloneメソッドによる回避法を覚えておいていただければと思います。
次回は、momentオブジェクトについての日時の差をとる方法についてお伝えします。
どうぞお楽しみに!