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

任何帮助都是最好的:)


当前回答

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

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;
}
 

其他回答

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

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;
}

一种方法是编写一个使用JODA库的简单Java Web服务(REST/JSON)

http://joda-time.sourceforge.net/faq.html#datediff

计算两个日期之间的差异,并从javascript调用该服务。

这假设您的后端是Java。

下面是一个函数,它精确地提供了两个日期之间的月数。 默认行为只计算整个月份,例如3个月和1天将导致3个月的差异。您可以通过将roundUpFractionalMonths参数设置为true来防止这种情况,因此3个月和1天的差异将返回为4个月。

上面公认的答案(T.J.克劳德的答案)是不准确的,它有时会返回错误的值。

例如,monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))返回0,这显然是错误的。正确的差值是1个月或2个月。

这是我写的函数:

function getMonthsBetween(date1,date2,roundUpFractionalMonths)
{
    //Months will be calculated between start and end dates.
    //Make sure start date is less than end date.
    //But remember if the difference should be negative.
    var startDate=date1;
    var endDate=date2;
    var inverse=false;
    if(date1>date2)
    {
        startDate=date2;
        endDate=date1;
        inverse=true;
    }

    //Calculate the differences between the start and end dates
    var yearsDifference=endDate.getFullYear()-startDate.getFullYear();
    var monthsDifference=endDate.getMonth()-startDate.getMonth();
    var daysDifference=endDate.getDate()-startDate.getDate();

    var monthCorrection=0;
    //If roundUpFractionalMonths is true, check if an extra month needs to be added from rounding up.
    //The difference is done by ceiling (round up), e.g. 3 months and 1 day will be 4 months.
    if(roundUpFractionalMonths===true && daysDifference>0)
    {
        monthCorrection=1;
    }
    //If the day difference between the 2 months is negative, the last month is not a whole month.
    else if(roundUpFractionalMonths!==true && daysDifference<0)
    {
        monthCorrection=-1;
    }

    return (inverse?-1:1)*(yearsDifference*12+monthsDifference+monthCorrection);
};

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

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。

有时你可能想要得到两个日期之间的月份数量,完全忽略日期部分。例如,如果你有两个日期——2013/06/21和2013/10/18——你只关心2013/06和2013/10部分,下面是场景和可能的解决方案:

var date1=new Date(2013,5,21);//Remember, months are 0 based in JS
var date2=new Date(2013,9,18);
var year1=date1.getFullYear();
var year2=date2.getFullYear();
var month1=date1.getMonth();
var month2=date2.getMonth();
if(month1===0){ //Have to take into account
  month1++;
  month2++;
}
var numberOfMonths; 

1.如果您只想知道两个日期之间的月份数,不包括第1个月和第2个月

numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;

2.如果你想包括这两个月中的任何一个

numberOfMonths = (year2 - year1) * 12 + (month2 - month1);

3.如果你想包括这两个月

numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;