JavaScript中两个date之间的差异

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

任何帮助将是伟大的:)

“差异月份数”的定义受到很多解释。 🙂

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

例如,非现场的,这发现两个date之间有多less个整月 ,不包括部分月份(例如,不包括每个date的月份):

function monthDiff(d1, d2) { var months; months = (d2.getFullYear() - d1.getFullYear()) * 12; months -= d1.getMonth() + 1; months += d2.getMonth(); return months <= 0 ? 0 : months; } monthDiff( new Date(2008, 10, 4), // November 4th, 2008 new Date(2010, 2, 12) // March 12th, 2010 ); // Result: 15: December 2008, all of 2009, and Jan & Feb 2010 monthDiff( new Date(2010, 0, 1), // January 1st, 2010 new Date(2010, 2, 12) // March 12th, 2010 ); // Result: 1: February 2010 is the only full month between them monthDiff( new Date(2010, 1, 1), // February 1st, 2010 new Date(2010, 2, 12) // March 12th, 2010 ); // Result: 0: There are no *full* months between them 

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

包括上述的小数月份要复杂得多,因为典型的二月份的三天比八月份的三天(〜9.677%)是当月较大的一部分(〜10.714%),当然,甚至2月份也是一个移动的目标取决于是否是闰年。

还有一些JavaScript的date和时间库可能使这种事情更容易。

 return DisplayTo.getMonth() - DisplayFrom.getMonth() + (12 * (DisplayTo.getFullYear() - DisplayFrom.getFullYear())); 

有时你可能想要得到两个date之间的月份数量完全忽略了一天的部分。 举例来说,如果您有两个date(2013/06/21和2013/10/18),并且您只关注2013/06和2013/10部分,则下面是情景和可能的解决scheme:

 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; 

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

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

如果你想包括两个月

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

如果你需要计算满月,不pipe月份是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(合乎逻辑,因为是整整一个月)
  • 3月15日至15日—> 28或29天—>将导致1(合乎逻辑,一个月过去了)
  • 1月31日至2月1日—> 1日—>将导致0(显而易见,但在1个月后的结果中提到的答案)

这里有一个函数可以准确地提供两个date之间的月数。
默认行为只计算整个月份,例如3个月和1天将导致3个月的差异。 您可以通过将roundUpFractionalMonths参数设置为true来防止这种true ,因此3个月和1天的差异将会返回为4个月。

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

例如, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))返回0 ,这显然是错误的。 正确的区别是整整一个月或两个月的四舍五入。

这是我写的function:

 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), eg 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); }; 

JavaScript中两个date之间的差异:

  start_date = new Date(year, month, day); //Create start date object by passing appropiate argument end_date = new Date(new Date(year, month, day) 

start_date和end_date之间的总月数:

  total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth()) 

考虑每个月的date,然后减去找出差异。

 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()); 

这会让你看到两个date之间的差异,忽略了日子。

我知道这真的很晚,但无论如何发布,以防万一它帮助别人。 这是我提出的一个函数,似乎很好地计算了两个date之间的月份差异。 无可厚非的是,克劳德先生是一个比较粗鲁的人,但是通过joindate对象来提供更准确的结果。 这是在AS3,但你应该能够放下强大的打字,你会有JS。 随意让它看起来更好看!

  function countMonths ( startDate:Date, endDate:Date ):int { var stepDate:Date = new Date; stepDate.time = startDate.time; var monthCount:int; while( stepDate.time <= endDate.time ) { stepDate.month += 1; monthCount += 1; } if ( stepDate != endDate ) { monthCount -= 1; } return monthCount; } 

要扩大@TJ的答案,如果你正在寻找简单的月份,而不是整个日历月份,你可以检查d2的date是否大于或等于d1。 也就是说,如果d2的月份晚于d1的月份,则还有1个月。 所以你应该能够做到这一点:

 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),但是它更准确,只需几行代码。

在这里你可以用更less的循环来进行其他处理:

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

有两种方法,math和快速,但在日历中易受影响,或迭代和缓慢,但处理所有古怪(或至less代表处理它们到一个经过良好testing的库)。

如果您遍历日历,则将开始date递增一个月,然后查看是否通过了结束date。 这将exception处理委托给内置的Date()类,但是如果您为大量date执行此操作可能会很慢。 詹姆斯的回答采取了这种方法。 尽pipe我不喜欢这个想法,但我认为这是“最安全”的方法,如果只做一个计算,那么性能差异确实可以忽略不计。 我们倾向于过度优化只能执行一次的任务。

现在, 如果你正在数据集上计算这个函数,你可能不想在每一行上运行这个函数(或者上帝禁止,每个logging多次)。 在这种情况下, 除了被接受的答案之外 ,你几乎可以使用任何其他答案,这只是错误的( new Date()new Date()之间的区别是-1)?

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

 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; months += d2.getMonth() - d1.getMonth(); 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); } 

计算两个date之间的差异包括月份(天)的分数。


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

例如:
date1 :24/09/2015(2015年9月24日)
date2 :2015年11月9日(2015年11月9日)
差异:2.5(月)

以下代码在两个date之间返回完整的月份,同时考虑部分月份的天数。

 var monthDiff = function(d1, d2) { if( d2 < d1 ) { var dTmp = d2; d2 = d1; d1 = dTmp; } var months = (d2.getFullYear() - d1.getFullYear()) * 12; months -= d1.getMonth() + 1; months += d2.getMonth(); if( d1.getDate() <= d2.getDate() ) months += 1; return months; } monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 20)) > 1 monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 19)) > 0 monthDiff(new Date(2015, 01, 20), new Date(2015, 01, 22)) > 0 
 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; 

}

anyVar =(((DisplayTo.getFullYear()* 12)+ DisplayTo.getMonth()) – ((DisplayFrom.getFullYear()* 12)+ DisplayFrom.getMonth()));

看看我用什么:

 function monthDiff() { var startdate = Date.parseExact($("#startingDate").val(), "dd/MM/yyyy"); var enddate = Date.parseExact($("#endingDate").val(), "dd/MM/yyyy"); var months = 0; while (startdate < enddate) { if (startdate.getMonth() === 1 && startdate.getDate() === 28) { months++; startdate.addMonths(1); startdate.addDays(2); } else { months++; startdate.addMonths(1); } } return months; } 

以下逻辑将在几个月内取得差异

 (endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth()) 

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

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

计算两个date之间的差异,并从JavaScript调用该服务。

这假设你的后端是Java。