Разница в месяцах между двумя датами в JavaScript

Как бы я определил разницу для двух объектов Date () в JavaScript, а возвращал только количество месяцев в разнице?

Любая помощь будет большой :)

javascript,date,datediff,

97

Ответов: 21


182 ов принято

Определение «количество месяцев в разнице» подлежит многому толкованию. :-)

Вы можете получить год, месяц и день месяца из объекта даты 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 начинаются с возврата DisplayTo.getMonth () - DisplayFrom.getMonth () + (12 * (DisplayTo.getFullYear () - DisplayFrom.getFullYear ())); = Январь.)

Включение дробных месяцев в вышеперечисленное намного сложнее, потому что три дня в типичном феврале составляют большую часть этого месяца (~ 10,714%), чем три дня в августе (~ 9,677%), и, конечно, даже февраль - движущаяся цель в зависимости от того, является ли это високосным годом.

Существуют также библиотеки времени и времени для JavaScript, которые, вероятно, упрощают эту задачу.


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

26

Иногда вы можете получить только количество месяцев между двумя датами, полностью игнорирующими дневную часть. Так, например, если у вас были две даты - 2013/06/21 и 2013/10/18 - и вы заботились только о частях 2013/06 и 2013/10, вот сценарии и возможные решения:

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

1.Если вы хотите просто количество месяцев между двумя датами, исключая как month1, так и month2

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

2.Если вы хотите включить один из месяцев

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

3.Если вы хотите включить оба месяца

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

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

21

Если вам нужно рассчитывать полные месяцы, независимо от того, в течение месяца 28, 29, 30 или 31 дня. Ниже должно работать.

roundUpFractionalMonths

Это расширенная версия ответа 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 месяц)

19 ов

Вот функция, которая точно определяет количество месяцев между двумя датами.
По умолчанию поведение учитывается только в течение нескольких месяцев, например, 3 месяца и 1 день приведет к разнице в 3 месяца. Вы можете предотвратить это, установив trueпараметр как monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015')), поэтому разница в 3 месяца и 1 день будет возвращена как 4 месяца.

Принятый ответ выше (ответ TJ Crowder) неточен, иногда он возвращает неправильные значения.

Например, 0возвращается, 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, дата, DateDiff,
Похожие вопросы