javascript Moment.js 月差
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19705003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Moment.js months difference
提问by Khain
I've been using moment.js for a short while now, and it's made date manipulation a lot easier but I have a specific case that is failing, and I can't see why.
我已经使用 moment.js 有一段时间了,它使日期操作变得更加容易,但我有一个特定的案例失败了,我不明白为什么。
When calculating the diff between today (31st October 2013) and the 1st February 2014, the months diff comes back as 2, although there are 3 complete months and one day between the two dates.
在计算今天(2013 年 10 月 31 日)和 2014 年 2 月 1 日之间的差异时,月份差异返回为 2,尽管两个日期之间有 3 个完整的月份和一天。
Diff between 31st October and 31st January works fine: 3 months and zero days.
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);
The console logs the following:
控制台记录以下内容:
periodStartDate: Thu Oct 31 2013 11:13:51 GMT+0000 (GMT)
someDate: Sat Feb 01 2014 11:13:51 GMT+0000 (GMT)
monthsDiff: 2
If I pass true as the boolean not to round, the months diff is
如果我将 true 作为布尔值传递给不舍入,则月份差异为
monthsDiff: 2.983050847457627
Is this just a bug in Moment.js.diff()? Every single one of my other test cases pass successfully.
这只是 Moment.js.diff() 中的一个错误吗?我的其他测试用例中的每一个都成功通过。
回答by robertklep
I think this has to do with the 'special handling' as described in The Fine Manual:
我认为这与The Fine Manual 中描述的“特殊处理”有关:
It is optimized to ensure that two months with the same date are always a whole number apart.
So Jan 15 to Feb 15 should be exactly 1 month.
Feb 28 to Mar 28 should be exactly 1 month.
Feb 28 2011 to Feb 28 2012 should be exactly 1 year.
它经过优化以确保具有相同日期的两个月始终相隔一个整数。
所以 1 月 15 日到 2 月 15 日应该正好是 1 个月。
2 月 28 日到 3 月 28 日应该正好是 1 个月。
2011 年 2 月 28 日到 2012 年 2 月 28 日应该正好是 1 年。
Moment.js applies this special handling when dealing with 31 Jan
and 31 Oct
(having the same day):
Moment.js 在处理31 Jan
和31 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
So the 2.98
value is correct, it's just that the second example turns the result into a 'calender months' difference.
因此该2.98
值是正确的,只是第二个示例将结果转换为“日历月”差异。
(as for rounding down to 2, that's also documented on the same page)
(至于四舍五入到 2,这也记录在同一页面上)
回答by MrB
I went a different route trying to get the difference between two months
我走了一条不同的路,试图找出两个月之间的差异
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;
This made sense to me and since moment is doing some strange things with diff I just decided to make it clear what my result will be.
这对我来说很有意义,因为 moment 正在用 diff 做一些奇怪的事情,我只是决定明确我的结果会是什么。
回答by Gaurav verma
Simple And Easy Solution with correct value difference between two months if you are using moment Library
如果您使用的是矩库,则具有两个月之间正确值差异的简单而简单的解决方案
const monthDifference = moment(new Date(endDate)).diff(new Date(startDate), 'months', true);
If you want to add the number of days in endDate
如果要在 endDate 中添加天数
const monthDifference = moment(new Date(endDate.add(1, 'days'))).diff(new Date(startDate), 'months', true);