Moment.jsを利用して、現在日時を基準にして連続した日時データを取得しようとした際に確認した事象です。
const m = moment()
for (let i = 0; i < 30; i++) {
let cur_date1 = m.add(i ,"minutes").format('YYYY-MM-DD HH:mm')
}
上のコードの期待としては「1分ずつ値が増えていく」でした。
しかし、実際には1回目こそ想定の値であるが、2回目は1分、3回目は3分、4回目は6分、5回目は10分、6回目は15分…と回を重ねるごとに、想定値とかけ離れていく。
理由としては、momentはミュータブルであり、addやsubtractのManipulate系メソッドの実行では元の値も変更されるため。
当然ながら、ドキュメントには書いてありました。
momentjs.com
Note: It should be noted that moments are mutable. Calling any of the manipulation methods will change the original moment.
If you want to create a copy and manipulate it, you should use moment#clone before manipulating the moment.
訳:momentsはミュータブルな点に注意すべきです。操作メソッドが呼び出されると元のmoment(の値)は変わります。もし、コピーを作成して操作をしたければ、操作前のmomentで「 moment#clone 」を使うべきです。
この記述に習い、基準となる日時のコピーを都度作成してそのコピーに対して追加を行う方式へ変更。
const m = moment()
for (let i = 0; i < 30; i++) {
let cur_date1 = m.clone().add(i ,"minutes").format('YYYY-MM-DD HH:mm')
}
希望通り、1分ずつ加算される結果となりました。
実際に動作確認ページも作ってみました。
「add」を押すたびに、moment#clone していないもの(上)としているもの(下)の値の動きに違いが出てくるのがわかります。
https://rykawamu.github.io/js_code_sample/public/moment_add_sample.html