【问题标题】:Moment.js months differenceMoment.js 月差
【发布时间】:2013-10-31 11:15:38
【问题描述】:

我使用 moment.js 已经有一段时间了,它使日期操作变得更加容易,但我有一个特定的案例失败了,我不明白为什么。

在计算今天(2013 年 10 月 31 日)和 2014 年 2 月 1 日之间的差异时,月份差异返回为 2,尽管这两个日期之间有 3 个完整的月份和 1 天。

10 月 31 日和 1 月 31 日之间的差异可以正常工作:3 个月零天。

var mStartDate = moment([ periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate() ]);
var mTermDate = moment([ someDate.getFullYear(), someDate.getMonth(), someDate.getDate() ]);

console.log('periodStartDate: ' + periodStartDate);
console.log('someDate: ' + someDate);

// Years
var yearsDiff = mTermDate.diff(mStartDate, 'years');

// Months
var monthsDiff = mTermDate.diff(mStartDate, 'months', true);

控制台记录以下内容:

periodStartDate: Thu Oct 31 2013 11:13:51 GMT+0000 (GMT)
someDate: Sat Feb 01 2014 11:13:51 GMT+0000 (GMT)
monthsDiff: 2

如果我将 true 作为不舍入的布尔值传递,则月份差异为

monthsDiff: 2.983050847457627 

这只是 Moment.js.diff() 中的一个错误吗?我的其他每个测试用例都成功通过。

【问题讨论】:

  • 我在 2.2.1 版本上遇到过这种情况 - 我也可以看到它在 2.4.0 版本中发生

标签: javascript momentjs


【解决方案1】:

我认为这与The Fine Manual 中描述的“特殊处理”有关:

经过优化,保证两个月的日期相同 总是一个整数。

所以 1 月 15 日到 2 月 15 日应该正好是 1 个月。

2 月 28 日到 3 月 28 日应该正好是 1 个月。

2011 年 2 月 28 日到 2012 年 2 月 28 日应该正好是 1 年。

Moment.js 在处理31 Jan31 Oct(同一天)时应用了这种特殊处理:

// 31 Oct 2013 - 1 Feb 2014
> moment([2014, 1, 1]).diff(moment([2013, 9, 31]), 'months', true)
2.983050847457627

// 31 Oct 2013 - 31 Jan 2014
> moment([2014, 0, 31]).diff(moment([2013, 9, 31]), 'months', true)
3

// 31 Oct 2013 - 30 Jan 2014
> moment([2014, 0, 30]).diff(moment([2013, 9, 31]), 'months', true)
2.967741935483871

所以2.98 的值是正确的,只是第二个例子把结果变成了“日历月”的差异。

(关于四舍五入到 2,这也记录在同一页上)

【讨论】:

  • 谢谢罗伯特。但是,与 30/01 相比,值上升(计算与 31/01 的差异时)然后又下降,这不是很奇怪吗?我期望像 2.967,然后是 3,然后是 3.02 或类似的东西。如果两个日期之间有3个完整的月份,我加一天怎么能少?在这之后我要做的另一件事是,我以“X 个月和 Y 天”的方式显示差异。所以......如果有 2 个月,那将带我到 31/12,然后有 32 天才能到达 2 月 1 日。
  • @Khain 因为天数相同,所以它会将值钳制为整数(即​​“特殊处理”)。对于其他日期,它不钳制并使用精确的(浮点)值。
  • @robertklep 你的意思是 moment([2013, 10, 31]).diff 吗?可能是笔误?
  • @LPG 你的意思是创建一个代表 10 月 31 日的实例?那应该是moment([2013, 9, 31])(因为月份是 0 索引的,所以 0 是一月,1 是二月,等等)。
【解决方案2】:

我走了一条不同的路,试图获得两个月之间的差异

function getAbsoluteMonths(momentDate) {
  var months = Number(momentDate.format("MM"));
  var years = Number(momentDate.format("YYYY"));
  return months + (years * 12);
}

var startMonths = getAbsoluteMonths(start);
var endMonths = getAbsoluteMonths(end);

var monthDifference = endMonths - startMonths;

这对我来说很有意义,因为 moment 正在用 diff 做一些奇怪的事情,所以我决定弄清楚我的结果会是什么。

【讨论】:

  • 来自最新的moment库,只需返回d.month() + d.year()*12
  • 为什么要将年份乘以 12?如果没有它,这不会达到同样的结果吗?
  • 我做了 12,因为如果我们的开始是 04-2017 并且结束是 01-2018,如果你只花几个月 + 一年会给你 2021 - 2019 = 4,我正在寻找 9。
【解决方案3】:

如果您使用矩库,则两个月之间的值差异正确的简单解决方案

  const monthDifference =  moment(new Date(endDate)).diff(new Date(startDate), 'months', true);

如果要在endDate中添加天数

 const monthDifference = moment(new Date(endDate.add(1, 'days'))).diff(new Date(startDate), 'months', true);

【讨论】:

    【解决方案4】:

    试试这个method;

    function getMonthDifference(startDate, endDate) {
        const increment = startDate.getMonth() === endDate.getMonth() ? 2 : 1;
        const diff = moment(endDate).diff(moment(startDate), 'months', true);
        return Math.ceil(diff) + increment;    // this increment is opitional and totally depends on your need.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多