JavaScript 中两个日期之间的月差

IT技术 javascript date datediff
2021-01-29 17:19:36

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

任何帮助都会很棒:)

6个回答

“差异月数”的定义受到很多解释。:-)

您可以从 JavaScript 日期对象获取月中的年、月和日。根据您要查找的信息,您可以使用这些信息来计算两个时间点之间有多少个月。

例如,现成的:

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

(请注意 JavaScript 中的月份值以 0 = 一月开始。)

在上面包括小数月份要复杂得多,因为典型的二月份的三天比八月份的三天(〜9.677%)占该月的更多部分(~10.714%),当然即使是二月份也是一个移动目标要看是不是闰年。

也有一些可用于 JavaScript 的日期和时间库,可能会使这类事情变得更容易。


注意:上面曾经有一个+ 1,这里是:

months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
// −−−−−−−−−−−−−−−−−−−−^^^^
months += d2.getMonth();

那是因为我最初说:

...这会找出两个日期之间有多少完整的月份,不计算部分月份(例如,不包括每个日期所在的月份)。

我删除它有两个原因:

  1. 不计算部分月份的结果并不是很多(大多数?)来回答的人想要的,所以我想我应该把它们分开。

  2. 即使按照这个定义,它也并不总是有效。:-D (对不起。)

很棒的回答者!谢谢!我解决了“上面曾经有过+1”的问题,只是在 d2 日期中增加了一天(它对我的场景起到了作用)。
2021-04-09 17:19:36

如果您不考虑月份中的哪一天,这是迄今为止更简单的解决方案

function monthDiff(dateFrom, dateTo) {
 return dateTo.getMonth() - dateFrom.getMonth() + 
   (12 * (dateTo.getFullYear() - dateFrom.getFullYear()))
}


//examples
console.log(monthDiff(new Date(2000, 01), new Date(2000, 02))) // 1
console.log(monthDiff(new Date(1999, 02), new Date(2000, 02))) // 12 full year
console.log(monthDiff(new Date(2009, 11), new Date(2010, 0))) // 1

请注意,月份索引是从 0 开始的。这意味着January = 0December = 11

从 2018/01 和 2017/01 相隔 12 个月这一事实开始。从那里向后工作。这个答案明白了。;)
2021-03-14 17:19:36
如果你只是想知道这个月数这个是完美的!!!!!如果您需要根据月份中的天数来了解,这将不起作用。
2021-03-25 17:19:36
谢谢!这个功能对我很有帮助
2021-03-27 17:19:36
除了每个月都开始计算之外,没有什么比这更复杂的了。31/03/2011 -> 01/05/2011 和 01/03/2011 -> 31/05/2011 一样是两个月,但准确地说应该是三个月。
2021-04-05 17:19:36
这是迄今为止我见过的最短且最容易理解的代码!
2021-04-09 17:19:36

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

上面接受的答案(TJ Crowder 的答案)不准确,它有时会返回错误的值。

例如,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);
};
说真的,谁投了反对票?他是对的,公认的答案只是……错误。
2021-03-15 17:19:36
如果我们说 date1 是 1 月 22 日,而 date2 是 8 月 22 日,这是不对的。然后它返回 7,这显然应该是 8?
2021-03-16 17:19:36
这是最合适的答案。
2021-03-18 17:19:36
做出这个公认的答案。这比公认的更准确。例如,接受的答案不计算天数
2021-03-29 17:19:36
克劳德接受的答案已经更新。它与此答案之间可能仍然存在重要差异,但在撰写本文时,此处列出的问题已得到解决。
2021-03-30 17:19:36

有时您可能只想获得两个日期之间的月份数量,而完全忽略日期部分。因此,例如,如果您有两个日期 - 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.如果你只想要两个日期之间的月数,不包括month1和month2

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

2.如果你想包括任何一个月份

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

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

numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;
这是最好的答案。谢谢!
2021-03-12 17:19:36
是的,很好,更优雅的方法。
2021-03-16 17:19:36
这是简单而干净的。感谢您编写出色的代码。
2021-03-23 17:19:36
好东西!非常适合我。
2021-03-29 17:19:36
对于最后一个,我会推荐:numberOfMonths=(year2-year1)*12+(month2-month1)+1;它的作用相同,但对我来说在语义上更正确
2021-03-29 17:19:36

如果您需要计算完整的月份,无论月份是 28、29、30 还是 31 天。下面应该工作。

var months = to.getMonth() - from.getMonth() 
    + (12 * (to.getFullYear() - from.getFullYear()));

if(to.getDate() < from.getDate()){
    months--;
}
return months;

这是答案https://stackoverflow.com/a/4312956/1987208的扩展版本,但修复了从 1 月 31 日到 2 月 1 日(1 天)计算 1 个月的情况。

这将涵盖以下内容;

  • 1 月 1 日至 1 月 31 日 ---> 30 天 ---> 将导致 0(合乎逻辑,因为它不是整月)
  • 2 月 1 日到 3 月 1 日 ---> 28 或 29 天 ---> 将导致 1(合乎逻辑,因为它是整月)
  • 2 月 15 日至 3 月 15 日 ---> 28 或 29 天 ---> 将导致 1(自一个月过去以来的逻辑)
  • 1 月 31 日至 2 月 1 日 ---> 1 天 ---> 将导致 0(很明显,但帖子中提到的答案会在 1 个月内产生结果)
我以为我来这里是为了验证,这是唯一对我有意义的答案
2021-03-13 17:19:36
当比较月份较短的两个月时,这不起作用。例如,从 3 月 31 日到 4 月 30 日。那是整个四月,所以答案应该是“1”。
2021-04-08 17:19:36