結論: startOf('days')
で時間をまるめる
const dayOne = moment('2020-01-01 10:00:00').startOf('days'); const dayTwo = moment('2020-01-02 09:00:00').startOf('days'); console.log('dayOne', dayOne.format()); console.log('dayTwo', dayTwo.format()); console.log('diff', dayTwo.diff(dayOne, 'days'));
はじめに
こんにちは、フロントエンドチームの高田(@proghallelujah)です。
moment.jsには指定した二つの日時を比較し、出力するdiffという機能があります。
この機能は、2つの日付の差分を時間単位まで観測し、デフォルトでは秒数
で出力されます。
diff
は第二引数で測定する時間単位を指定することが可能です。しかしその時、内部では秒数を任意の単位に再計算した値
を返しています。
また、その時小数点以下は切り捨てられてしまいます
const dayOne = moment('2020-01-01 10:00:00'); const dayTwo = moment('2020-01-02 11:00:00'); const dayThree = moment('2020-01-02 09:00:00'); const dayFour = moment('2020-01-02 10:00:00'); console.log("dayTwo", dayTwo.diff(dayOne, 'days')); // dayTwoはdayOneの時間を過ぎているので1 console.log("dayTwo asFloat", dayTwo.diff(dayOne, 'days', true)); console.log("dayThree", dayThree.diff(dayOne, 'days')); // dayThreeはdayOneの時間を過ぎてないので0 console.log("dayThree asFloat", dayThree.diff(dayOne, 'days', true)); console.log("dayFour", dayFour.diff(dayOne, 'days')); // dayFourはdayOneと同じ時間なので1 console.log("dayFour asFloat", dayFour.diff(dayOne, 'days', true));
(tips: 第三引数にtrue
を渡すことで値から小数点を切り捨てず返されます)
以下はmomentjsでdiff
を行なっている箇所です。
GitHub - moment.js/moment/src/lib/moment/diff.js
厳密な日付を計算するのであればこれが最良ですが、時間を考えず単純に日にちが変わったかどうかを計算したい、といった場合も多いと思います。
startOf
を使えば、そのような機能を簡単に実装することができます。
startOfとは
momentの機能の一つで、指定した時間単位の始まりの値を出力します。
startOfで
day
を指定すると、日のはじまり0:00:00
に時刻を変換して出力されます。
ではstartOf
を用いでdiff
を使ってみます。
例
const dayOne = moment('2020-01-01 10:00:00').startOf('days'); const dayTwo = moment('2020-01-02 09:00:00').startOf('days'); console.log('dayOne', dayOne.format()); console.log('dayTwo', dayTwo.format()); console.log('diff', dayTwo.diff(dayOne, 'days'));
diff
は単位以下の値が同値の場合は1
になるので、これで日にちが変わったかどうか計算することができます。
アンチパターン、Math.round
を使う
小数点以下が切り捨てられるなら、Math.round
で繰り上げるようにすればよい、という案もあります。
しかし、Math.round
は意図せぬ値まで繰り上げてしまいます。
1. 第三引数にtrueを渡し、Math.round
を使う
const dayOne = moment('2020-01-01 01:00:00'); const dayTw0 = moment('2020-01-02 00:00:00'); const dayThree = moment('2020-01-01 17:00:00'); console.log(Math.round(dayTwo.diff(dayOne, 'days', true)), dayTwo.diff(dayOne, 'days', true)); console.log(Math.round(dayThree.diff(dayOne, 'days', true)), dayThree.diff(dayOne, 'days', true));
この場合、ある程度時間がたってしまった値だと、日付が同じでも繰り上げてしまいますので使用することができません。
なので、
startOf
が現状最良の手段だと思われます。
いかがでしたでしょうか?時間単位の日
はあくまで例に使っただけなので、その他の単位でも使用することができると思います。momentはドキュメントが丁寧でわかりやすく、自動翻訳でもそれなりに見ることができるので、皆さんもよかったらご一読ください。