我如何在JavaScript中计算出两个Date()对象的差异,而只返回差异中的月份数?

任何帮助都是最好的:)


当前回答

扩展一下@ tj。的答案,如果你在寻找简单的月份,而不是完整的日历月份,你可以检查d2的日期是否大于或等于d1的日期。也就是说,如果d2的月份晚于d1的月份,那么就多了一个月。所以你应该可以这样做:

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth();
    // edit: increment months if d2 comes later in its month than d1 in its month
    if (d2.getDate() >= d1.getDate())
        months++
    // end edit
    return months <= 0 ? 0 : months;
}

monthDiff(
    new Date(2008, 10, 4), // November 4th, 2008
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 16; 4 Nov – 4 Dec '08, 4 Dec '08 – 4 Dec '09, 4 Dec '09 – 4 March '10

这并没有完全考虑到时间问题(例如,3月3日下午4:00和4月3日下午3:00),但它更准确,而且只适用于几行代码。

其他回答

有两种方法,数学的和快速的,但受制于日历的变幻莫测,或者迭代的和缓慢的,但处理所有奇怪的(或者至少委托处理它们到一个经过良好测试的库)。

If you iterate through the calendar, incrementing the start date by one month & seeing if we pass the end date. This delegates anomaly-handling to the built-in Date() classes, but could be slow IF you're doing this for a large number of dates. James' answer takes this approach. As much as I dislike the idea, I think this is the "safest" approach, and if you're only doing one calculation, the performance difference really is negligible. We tend to try to over-optimize tasks which will only be performed once.

现在,如果您在数据集中计算这个函数,您可能不希望在每一行上运行该函数(或者上帝禁止,每条记录多次)。在这种情况下,您几乎可以使用这里的任何其他答案,除了接受的答案,这是错误的(new Date()和new Date()之间的差异是-1)?

下面是我尝试的一种数学而快速的方法,它解释了不同的月份长度和闰年。你真的应该只使用这样的函数,如果你将应用它到一个数据集(做这个计算一遍又一遍)。如果只需要执行一次,可以使用上面James的迭代方法,因为您正在将所有(许多)异常的处理委托给Date()对象。

function diffInMonths(from, to){
    var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear()));

    if(to.getDate() < from.getDate()){
        var newFrom = new Date(to.getFullYear(),to.getMonth(),from.getDate());
        if (to < newFrom  && to.getMonth() == newFrom.getMonth() && to.getYear() %4 != 0){
            months--;
        }
    }

    return months;
}

它还计算天数并以月为单位进行转换。

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;   //calculates months between two years
    months -= d1.getMonth() + 1; 
    months += d2.getMonth();  //calculates number of complete months between two months
    day1 = 30-d1.getDate();  
    day2 = day1 + d2.getDate();
    months += parseInt(day2/30);  //calculates no of complete months lie between two dates
    return months <= 0 ? 0 : months;
}

monthDiff(
    new Date(2017, 8, 8), // Aug 8th, 2017    (d1)
    new Date(2017, 12, 12)  // Dec 12th, 2017   (d2)
);
//return value will be 4 months 

下面是另一种更少循环的方法:

calculateTotalMonthsDifference = function(firstDate, secondDate) {
        var fm = firstDate.getMonth();
        var fy = firstDate.getFullYear();
        var sm = secondDate.getMonth();
        var sy = secondDate.getFullYear();
        var months = Math.abs(((fy - sy) * 12) + fm - sm);
        var firstBefore = firstDate > secondDate;
        firstDate.setFullYear(sy);
        firstDate.setMonth(sm);
        firstBefore ? firstDate < secondDate ? months-- : "" : secondDate < firstDate ? months-- : "";
        return months;
}

以月为单位考虑每个日期,然后相减找出差值。

var past_date = new Date('11/1/2014');
var current_date = new Date();

var difference = (current_date.getFullYear()*12 + current_date.getMonth()) - (past_date.getFullYear()*12 + past_date.getMonth());

这将得到两个日期之间的月差,忽略日。

下面的代码片段帮助我找到两个日期之间的月份

找到两个日期之间的月份计数JS


两个日期之间的月份 代码片段

function diff_months_count(startDate, endDate) {
    var months;
    var d1 = new Date(startDate);
    var d2 = new Date(endDate);
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth();
    months += d2.getMonth();
    return months <= 0 ? 0 : months;
}