
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オブジェクトになりますが、以下のような日時の加算・減算をするスクリプトを実行してみましょう。
1 2 3 4 5 6 |
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に代入したとしましょう。
1 2 3 4 5 6 7 |
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オブジェクトと同様の結果となってしまうのです。
1 2 3 4 5 6 7 |
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」に対して実行をしたいのであれば
1 2 3 4 5 6 7 8 9 10 |
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オブジェクトのコピーのオブジェクトが生成されます。
例えば、前述の加算してから減算のスクリプトは
1 2 3 4 5 6 7 8 |
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オブジェクトについての日時の差をとる方法についてお伝えします。

どうぞお楽しみに!
連載目次:Google Apps ScriptでMoment.jsを使う
Google Apps Scriptでよく取り扱う日付と時刻。しかし、JavaScriptの標準Dateオブジェクトは扱いがなかなか難しいんですよね。その日時の操作をとっても簡単にすることができるライブラリ「Moment.js」の使い方について、解説をしていきます。- 日付&時刻の便利ライブラリ「Moment.js」をGoogle Apps Scriptで使う方法
- Google Apps ScriptでもMoment.jsで日付&時刻の書式フォーマットを簡単に指定
- Google Apps ScriptのMoment.jsで日時の各要素をGetとSetする方法
- GAS版Moment.jsライブラリで超簡単に日時の比較をする方法
- GASでMoment.jsライブラリを使って簡単に日時の計算をする方法
- GAS版Moment.jsの破壊的な日時計算メソッドの注意点とcloneメソッドによる回避
- GASでMoment.jsライブラリを使って超スマートに日時の差をとる方法
- Google Apps Scriptを使って80歳までの残り時間をチャットワークに日々通知する
コメント
すごく読みやすい記事ですね^_^
参考にさせていただきます!
わくひろさん
コメントありがとうございます!
嬉しいです…
引き続き良い記事を提供できるように頑張ります!