关于javascript:Moment的diff方法两个日期正反比较值大小竟然不同看完算法原理原来是我天真了

9次阅读

共计 1538 个字符,预计需要花费 4 分钟才能阅读完成。

问题

大家好,我是数据里奥斯,明天有一段业务逻辑须要判断抉择的工夫范畴不能超过 3 个月,这种惯例的比拟用 moment.js 的 diff 办法不是手到擒来么?

moment('2020-3-30').diff(moment('2020-7-01'), 'months')

console 一下看了看后果:-3.03333333333333,不错,3 个月出头,稳~就是这个负的有点好受,把开始完结工夫换个地位吧

moment('2020-7-01').diff(moment('2020-3-30'), 'months')

卧槽,这 console 进去一看:3.064516129032258,额,这正负差异失常,为啥前面小数会有这么大差异?Moment 傻逼了?不,肯定是我傻逼了。。。。

思路

遇事不决,先看文档:diff() | Moment.js 文档 (momentjs.cn)

Emmm,如同没啥特地的,然而,有一行小字吸引了我:
See more discussion on the month and year diffs here 看起来这里的确有 Beef 啊,就算不能解决,我也进去吐槽一下,哈哈

这个老哥,和我的问题不能说同床异梦,只能说一毛一样啊,原来也有和我一样的二傻子啊(???干嘛这样说我本人)
我来看看上面各位大神是怎么教他做人的。。。

翻到最底下,这位吉布森老哥贴了个链接:difference should always return a “top-heavy balanced” duration with largest-first order of operations · Issue #993 · tc39/proposal-temporal (github.com)

这外面有一条评论是这样说的:

The algorithm Java uses seems to be something like this:

  1. Start with the smaller value: 2020-01-31
  2. Find the number of whole months that can be added to it without going past 2020-03-30. That’s one month.
  3. Add one month to 2020-01-31 and constrain that result to a valid date, e.g. 2020-02-29
  4. Now find the number of whole days that can be added without going past the end. That’s 30 days.
  5. Return P1M30D

看完这一段,我恍然大悟,拿咱们明天遇到的理论 case,我讲一下他解释的这段原理到底是怎么实现的:

  • diff 算法是先加或者减每个整月始终到不能减,而后再看剩下的天数和当月比拟的百分比
  • 比方 07-01 从零点开始计算,减 3 个月是 04-01 的零点,还剩下 3 -31、3-30 两天到 3 -30 号零点,3 月份有 31 天,所以是 2 /31=0.0645,加在一起就是 3.064516129032258
  • 第二种状况,是始终加到 03-30 的零点开始算起,到 06-30 零点不能加整月了,这时离 7 -01 零点还有 1 终日的工夫,6 月有 30 天,所以零头是 1 /30=0.333333333…,加在一起是 -3.03333333333333…

论断

所以,moment.js 的 diff 办法在比拟以天 / 月份 / 年份这样非凡粒度的单位时,都会优先依照整粒度扣除,剩下的小数局部,是依据子一级的粒度取当年 / 月 / 日为参照按比值算出的,这才有了这种 A 比 B 的值和 B 比 A 的值居然不一样的状况。虽说一般来讲这个值多一点少一点不会有影响,毕竟咱们是按找本人规定的粒度来比拟的,然而这种原理能整明确,也不失为一种“学到了”的播种,嘿嘿

我是数据里奥斯~

正文完
 0