Разница в месяцах между двумя датами в JavaScript
Как бы я разработал разницу для двух объектов Date () в JavaScript, в то время как возвращаю только количество месяцев в разнице?
любая помощь будет большое :)
21 ответ:
определение "количество месяцев в разнице" подлежит большому количеству интерпретаций. : -)
вы можете получить год, месяц и день месяца из объекта Date в 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 = январь.)
включение дробных месяцев в вышеизложенное намного сложнее, потому что три дня в типичном феврале-это большая часть этого месяца (~10.714%), чем три дня в августе (~9.677%), и, конечно же, даже февраль является движущейся целью в зависимости от того, является ли это високосным годом.
есть также некоторые дата и время библиотеки доступно для JavaScript, что, вероятно, делает такие вещи проще.
return DisplayTo.getMonth() - DisplayFrom.getMonth() + (12 * (DisplayTo.getFullYear() - DisplayFrom.getFullYear()));
иногда вы можете получить только количество месяцев между двумя датами, полностью игнорируя дня. Так, например, если у вас было две даты-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;
Если вам нужно считать полные месяцы, независимо от того, месяц 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 января по 1 февраля (1 день).
Это будет охватывать следующее;
- С 1 января по 31 января - - - > 30days - - - > приведет к 0 (логично, так как это не полный месяц)
- 1 февраля до 1 марта - - - > 28 или 29 дней - - - > приведет к 1 (логично, так как это полный месяц)
- 15 февраля по 15 марта - - - > 28 или 29 дней - - - > приведет к 1 (логично, так как прошел месяц)
- 31 января по 1 февраля - - - > 1 день - - - > приведет к 0 (очевидно, но упомянутый ответ в сообщении приводит к 1 месяцу)
вот функция, которая определяет точное количество месяцев между 2 датами.
Поведение по умолчанию учитывает только целые месяцы, например, 3 месяца и 1 день приведет к разнице в 3 месяца. Вы можете предотвратить это, установивroundUpFractionalMonths
param astrue
, поэтому разница в 3 месяца и 1 дня будет возвращена как 4 месяца.принятый ответ выше (ответ Ти Джей Краудер) не является точным, он возвращает неправильные значения иногда.
для например,
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); };
разница в месяцах между двумя датами в 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())
Я знаю, что это действительно поздно, но все равно отправляю его на всякий случай, если это поможет другим. Вот функция, которую я придумал, которая, похоже, хорошо справляется с подсчетом различий в месяцах между двумя датами. Это, по общему признанию, намного грубее, чем у г-на Краудера, но обеспечивает более точные результаты, проходя через объект даты. Он находится в 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; }
рассмотрим каждую дату в терминах месяцев, а затем вычесть, чтобы найти разницу.
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());
Это даст вам разницу месяцев между двумя датами, игнорируя дни.
чтобы расширить ответ @T. J., Если вы ищете простые месяцы, а не полные календарные месяцы, вы можете просто проверить, больше ли дата d2 или равна дате 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 марта в 4: 00 вечера и 3 апреля в 3: 00 вечера), но это более точно и всего за пару строк код.
есть два подхода, математический и быстрый, но подверженный капризам в календаре, или итерационный и медленный, но обрабатывает все странности (или, по крайней мере, делегирует их в хорошо протестированную библиотеку).
Если вы повторяете через календарь, увеличивая дату начала на один месяц и видя, если мы передаем дату окончания. Это делегирует обработку аномалий встроенным классам Date (), но может быть медленным если вы делаете это для большого количества дат. Джеймс ответ принимает такой подход. Как бы мне не нравилась эта идея, я думаю, что это "самый безопасный" подход, и если вы только делаете один расчет, разница в производительности действительно незначительна. Мы склонны пытаться чрезмерно оптимизировать задачи, которые будут выполняться только один раз.
Теперь если вы вычисляете эту функцию в наборе данных, вы, вероятно, не хотите запускать эту функцию в каждой строке (или, не дай бог, несколько раз на запись). В этом случае, вы можете использовать почти любой из других ответов здесь за исключением принятый ответ, который просто неверен (разница между
new Date()
иnew Date()
Это -1)?вот мой удар по математическому и быстрому подходу, который учитывает различные длины месяцев и високосные годы. Вы действительно должны использовать только такую функцию, если вы будете применять это к набору данных (делая этот расчет снова и снова). Если вам просто нужно сделать это один раз, используйте итеративный подход Джеймса выше, когда вы делегируете обработка всех (многих) исключений для объекта 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; }
здесь вы идете другой подход с меньшим зацикливание:
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; }
Это должно работать нормально:
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); }
вычислите разницу между двумя датами, включая долю месяца (дней).
var difference = (date2.getDate() - date1.getDate()) / 30 + date2.getMonth() - date1.getMonth() + (12 * (date2.getFullYear() - date1.getFullYear()));
например:
date1: 24/09/2015 (24 сентября 2015)
date2: 09/11/2015 (9 ноября 2015)
разница: 2.5 (месяцев)
следующий код возвращает полные месяцы между двумя датами, принимая во внимание также 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
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;
}
ниже логика будет получать разницу в месяцах
(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
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; }
Он также считает дни и конвертировать их в месяцев.
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
одним из подходов было бы написать простой веб-сервис Java (REST/JSON), который использует библиотеку JODA
http://joda-time.sourceforge.net/faq.html#datediff
чтобы вычислить разницу между двумя датами и вызвать эту службу из javascript.
Это предполагает, что ваша задняя часть находится в Java.