我如何计算JavaScript中两个Date()对象的差异,而只返回差异中的月数?
任何帮助都会很棒:)
答案 0 :(得分:202)
“差异中的月数”的定义需要进行大量解释。 : - )
您可以从JavaScript日期对象中获取月份,月份和日期。根据您要查找的信息,您可以使用这些信息来确定两个时间点之间的月数。
例如,在袖口之外,这会发现两个日期之间存在多少整月,而不计算部分月份(例如,排除每个日期所在的月份):
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月开头。)
包括上述的分数月要复杂得多,因为一个典型的二月份的三天比那个月的大部分(~10.714%)比八月的三天(~9.677%)更大,当然甚至二月是移动目标取决于它是否是闰年。
还有一些可用于JavaScript的date and time libraries可能会使这种事情变得更容易。
答案 1 :(得分:61)
如果您不考虑当月的日期,这是迄今为止最简单的解决方案
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 = 0
和December = 11
。
答案 2 :(得分:28)
有时您可能只想获得两个日期之间的月份数量,完全忽略了日期部分。例如,如果您有两个日期 - 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;
答案 3 :(得分:22)
如果您需要计算整月,无论月份是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个月的情况。
这将涵盖以下内容;
答案 4 :(得分:21)
这是一个准确提供两个日期之间的月数的函数
默认行为仅计算整月,例如3个月和1天将导致3个月的差异。您可以将roundUpFractionalMonths
参数设置为true
来阻止此操作,因此3个月和1天的差异将返回为4个月。
上面接受的答案(T.J.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);
};
答案 5 :(得分:7)
JavaScript中两个日期之间的差异:
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())
答案 6 :(得分:6)
我知道这已经很晚了,但无论如何都是为了以防万一,以防万一。这是我提出的一个函数,似乎可以很好地计算两个日期之间的差异。不可否认,它比Mr.Crowder's更加笨拙,但通过逐步完成日期对象可以提供更准确的结果。它在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;
}
答案 7 :(得分:5)
以月为单位考虑每个日期,然后减去以找出差异。
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());
这将为您提供两个日期之间的月份差异,忽略日期。
答案 8 :(得分:4)
有两种方法,数学和数学快速,但受日历中的变幻莫测,或迭代&amp;慢,但处理所有奇怪的事情(或至少代表处理它们到一个经过良好测试的库)。
如果您遍历日历,请将开始日期增加一个月&amp;看看我们是否通过了结束日期。这会将异常处理委托给内置的Date()类,但可能会很慢 IF 您在大量日期执行此操作。詹姆斯&#39;答案采用这种方法。尽管我不喜欢这个想法,但我认为这是最安全的&#34;方法,如果您只进行一次计算,性能差异实际上可以忽略不计。我们倾向于尝试过度优化只执行一次的任务。
现在,如果您在数据集上计算此功能,您可能不想在每一行上运行该功能(或者上帝禁止,每条记录多次) 。在这种情况下,你可以在这里使用几乎任何其他答案除了接受的答案,这是错误的(new Date()
和new Date()
之间的差异是-1)?
这是我采用数学和快速方法的方法,它解释了不同的月份长度和闰年。如果你要将它应用于数据集(通过&amp; over进行计算),你真的应该只使用这样的函数。如果你只需要做一次,请使用James&#39;上面的迭代方法,因为您将所有(许多)例外处理委托给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;
}
答案 9 :(得分:3)
Here你采用其他方法减少循环:
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;
}
答案 10 :(得分:2)
这应该可以正常工作:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months += d2.getMonth() - d1.getMonth();
return months;
}
答案 11 :(得分:1)
这是我能找到的最简单的解决方案。这将直接返回月数。虽然,它总是给出一个绝对值。
new Date(new Date(d2) - new Date(d1)).getMonth();
对于非绝对值,您可以使用以下解决方案:
function diff_months(startDate, endDate) {
let diff = new Date( new Date(endDate) - new Date(startDate) ).getMonth();
return endDate >= startDate ? diff : -diff;
}
答案 12 :(得分:1)
function monthDiff(date1, date2, countDays) {
countDays = (typeof countDays !== 'undefined') ? countDays : false;
if (!date1 || !date2) {
return 0;
}
let bigDate = date1;
let smallDate = date2;
if (date1 < date2) {
bigDate = date2;
smallDate = date1;
}
let monthsCount = (bigDate.getFullYear() - smallDate.getFullYear()) * 12 + (bigDate.getMonth() - smallDate.getMonth());
if (countDays && bigDate.getDate() < smallDate.getDate()) {
--monthsCount;
}
return monthsCount;
}
答案 13 :(得分:1)
低于逻辑将在几个月内获取差异
(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
答案 14 :(得分:1)
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;
}
答案 15 :(得分:1)
以下代码在两个日期之间返回完整的月份,同时考虑部分月份的nr天。
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
答案 16 :(得分:1)
计算两个日期之间的差异,包括月份(天)的分数。
var difference = (date2.getDate() - date1.getDate()) / 30 +
date2.getMonth() - date1.getMonth() +
(12 * (date2.getFullYear() - date1.getFullYear()));
例如:
date1 :2015年9月24日(2015年9月24日)
date2 :2015年11月9日(2015年11月9日)
差异:2.5(月)
答案 17 :(得分:1)
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);
}
答案 18 :(得分:0)
anyVar =(((DisplayTo.getFullYear()* 12)+ DisplayTo.getMonth()) - ((DisplayFrom.getFullYear()* 12)+ DisplayFrom.getMonth()));
答案 19 :(得分:0)
看看我用的是什么:
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;
}
答案 20 :(得分:0)
它还计算天数并将其转换为几个月。
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
答案 21 :(得分:0)
为了繁荣,
使用Moment.js,您可以通过执行以下操作来实现此目的:
const monthsLeft = moment(endDate).diff(moment(startDate), 'month');
答案 22 :(得分:0)
您也可以考虑使用此解决方案,此 Future showNotification() async {
showDialog<String>(
context: context,
child: new AlertDialog(
title: Text('Note!') ,
contentPadding: const EdgeInsets.all(16.0),
content: //any widget you want to display here
),
);
await new Future.delayed(const Duration(seconds: 5), () {
Navigator.of(context).pop(); // this will dismiss the dialog automatically after five seconds
}
}
返回整数或数字的月份差
将 开始日期 作为第一个或最后一个 showNotificaion();
,这是容错的。这意味着该函数仍将返回相同的值。
function
答案 23 :(得分:0)
在这种情况下,我不必担心完整的月份,部分月份,一个月的时间等等。我只需要知道几个月的时间即可。 与现实世界相关的一个案例是每月应提交一份报告,我需要知道应该提交多少份报告。
示例:
这是一个详细的代码示例,用于显示数字的去向。
让我们以两个时间戳记为例,这些时间戳记应在4个月内产生
可能与您的时区/时间有所不同。日期,分钟和秒无关紧要,可以将其包括在时间戳中,但是在实际计算中我们将忽略它。
let dateRangeStartConverted = new Date(1573621200000);
let dateRangeEndConverted = new Date(1582261140000);
let startingMonth = dateRangeStartConverted.getMonth();
let startingYear = dateRangeStartConverted.getFullYear();
let endingMonth = dateRangeEndConverted.getMonth();
let endingYear = dateRangeEndConverted.getFullYear();
这给了我们
(12 * (endYear - startYear)) + 1
添加到结束的月份。2 + (12 * (2020 - 2019)) + 1 = 15
15 - 11 = 4
;我们得到了四个月的结果。
2019年11月至2022年3月为29个月。如果将它们放入excel电子表格,则会看到29行。
3 + (12 * (2022-2019)) + 1
40-11 = 29
答案 24 :(得分:0)
getMonthDiff(d1, d2) {
var year1 = dt1.getFullYear();
var year2 = dt2.getFullYear();
var month1 = dt1.getMonth();
var month2 = dt2.getMonth();
var day1 = dt1.getDate();
var day2 = dt2.getDate();
var months = month2 - month1;
var years = year2 -year1
days = day2 - day1;
if (days < 0) {
months -= 1;
}
if (months < 0) {
months += 12;
}
return months + years*!2;
}
答案 25 :(得分:0)
任何值都会返回其绝对值。
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;
}
答案 26 :(得分:0)
我不喜欢重新发明轮子,保持简单(我的意思是不关心月中的天数、闰年等)并使用 date-fns
库,因此
npm install -s date-fns
和
const differenceInMonths = require('date-fns/differenceInMonths')
;(() => {
console.log(differenceInMonths(new Date(`2015-12-01`), new Date(`2013-12-01`)))
console.log(differenceInMonths(new Date(1582261140000), new Date(`2014-12-01`)))
console.log(differenceInMonths(new Date(1582261140000), new Date(1573621200000)))
})()
答案 27 :(得分:-6)
一种方法是编写一个使用JODA库的简单Java Web服务(REST / JSON)
http://joda-time.sourceforge.net/faq.html#datediff
计算两个日期之间的差异,并从javascript调用该服务。
这假设您的后端是Java。