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

任何帮助都是最好的:)


当前回答

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

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 calcualteMonthYr(){
    var fromDate =new Date($('#txtDurationFrom2').val()); //date picker (text fields)
    var toDate = new Date($('#txtDurationTo2').val());

var months=0;
        months = (toDate.getFullYear() - fromDate.getFullYear()) * 12;
        months -= fromDate.getMonth();
        months += toDate.getMonth();
            if (toDate.getDate() < fromDate.getDate()){
                months--;
            }
    $('#txtTimePeriod2').val(months);
}

任何值连同它的绝对值一起返回。

function differenceInMonths(firstDate, secondDate) {
    if (firstDate > secondDate) [firstDate, secondDate] = [secondDate, firstDate];
    let diffMonths = (secondDate.getFullYear() - firstDate.getFullYear()) * 12;
    diffMonths -= firstDate.getMonth();
    diffMonths += secondDate.getMonth();
    return diffMonths;
}
 
function monthDiff(d1, d2) {
var months, d1day, d2day, d1new, d2new, diffdate,d2month,d2year,d1maxday,d2maxday;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
months = (months <= 0 ? 0 : months);
d1day = d1.getDate();
d2day = d2.getDate();
if(d1day > d2day)
{
    d2month = d2.getMonth();
    d2year = d2.getFullYear();
    d1new = new Date(d2year, d2month-1, d1day,0,0,0,0);
    var timeDiff = Math.abs(d2.getTime() - d1new.getTime());
          diffdate = Math.abs(Math.ceil(timeDiff / (1000 * 3600 * 24))); 
    d1new = new Date(d2year, d2month, 1,0,0,0,0);
    d1new.setDate(d1new.getDate()-1);
    d1maxday = d1new.getDate();
    months += diffdate / d1maxday;
}
else
{
      if(!(d1.getMonth() == d2.getMonth() && d1.getFullYear() == d2.getFullYear()))
    {
        months += 1;
    }
    diffdate = d2day - d1day + 1;
    d2month = d2.getMonth();
    d2year = d2.getFullYear();
    d2new = new Date(d2year, d2month + 1, 1, 0, 0, 0, 0);
    d2new.setDate(d2new.getDate()-1);
    d2maxday = d2new.getDate();
    months += diffdate / d2maxday;
}

return months;

}

如果你不考虑每月的日期,这是迄今为止最简单的解决方案

function monthDiff(dateTo, dateTo) 回来了 (12 * (dateTo.getFullYear) - dateyear .getFullYear() 的 /和 控制台(新日期(2000年,01年),新日期(2000年,02年)// 1 控制台,log(monthDiff, new Date(1999, 02), new Date(2000, 02)) // 12年 控制台.log(monthDiff,新日期(2009年,11年),新日期(2010年,0)// 1

注意,月份索引是基于0的。这意味着一月= 0,十二月= 11。

计算两个日期之间的差,包括月的分数(天)。


var difference = (date2.getDate() - date1.getDate()) / 30 +
    date2.getMonth() - date1.getMonth() +
    (12 * (date2.getFullYear() - date1.getFullYear()));

例如: 日期:24/09/2015(2015年9月24日) 日期2:09/11/2015(2015年11月9日) 差异:2.5个月