Pregunta

¿Cómo iba a trabajar la diferencia para dos Date () objetos en JavaScript, mientras que sólo devolverá el número de meses en la diferencia?

Cualquier ayuda sería grande:)

¿Fue útil?

Solución

La definición de "el número de meses en la diferencia" está sujeta a una gran cantidad de interpretación. : -)

Se puede obtener el año, mes y día del mes de una fecha objeto de JavaScript. En función de la información que está buscando, puede usarlos para averiguar cuántos meses son entre dos puntos en el tiempo.

Por ejemplo, fuera de la manga, esta descubre cuántos meses completos se encuentran entre dos fechas, sin contar meses parciales (por ejemplo, excluyendo el mes en cada fecha, es en):

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

(Tenga en cuenta que los valores de mes en JavaScript empiezan con 0 = Enero.)

Incluyendo meses fraccionarios en lo anterior es mucho más complicado, porque tres días en un típico febrero es una fracción más grande de ese mes (~ 10,714%) de tres días en agosto (~ 9,677%), y por supuesto, incluso Febrero es un objetivo en movimiento en función de si se trata de un año bisiesto.

También hay algunos bibliotecas de fecha y hora disponible para JavaScript que probablemente hacen este tipo de cosas más fácil.

Otros consejos

Si no tenemos en cuenta el día del mes, esto es, con mucho, la solución más simple

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

Tenga en cuenta que el índice de mes se basa-0. Esto significa que January = 0 y December = 11.

A veces es posible que desee obtener sólo la cantidad de meses entre dos fechas ignorando por completo la parte del día. Así, por ejemplo, si usted tenía dos fechas-06/21/2013 y 2013/10 / 18- y sólo se preocupaba por los 2013/06 y 2013/10 partes, aquí están los problemas y las posibles soluciones:

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. Si usted quiere sólo el número de los meses entre las dos fechas excluyendo tanto mes1 y MONTH2

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

2. Si desea incluir cualquiera de los meses

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

3. Si desea incluir tanto de los meses

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

Esta es una función que proporciona precisión el número de meses transcurridos entre 2 fechas.
El comportamiento por defecto sólo cuenta meses enteros, por ejemplo, 3 meses y 1 día darán lugar a una diferencia de 3 meses. Esto se puede evitar ajustando el parámetro roundUpFractionalMonths como true, por lo que de 3 meses y 1 día de diferencia que se obtiene es de 4 meses.

La respuesta aceptada anteriormente (la respuesta de T. J. Crowder) no es exacta, a veces devuelve valores incorrectos.

Por ejemplo, devoluciones monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015')) 0 que es obviamente erróneo. La diferencia correcta es o bien 1 mes entero o 2 meses redondeados-up.

Esta es la función que escribí:

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

Si necesita contar meses completos, sin importar el mes de ser 28, 29, 30 o 31 días. A continuación debería funcionar.

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

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

Esta es una versión extendida de la respuesta https://stackoverflow.com/a/4312956/1987208 pero correcciones el caso en que se calcula 1 mes para el caso del 31 de enero al 1 de febrero (1 día).

Esto cubrirá la siguiente;

  • 1 enero a 31 enero ---> 30 días ---> se traducirá en 0 (lógico ya que no es un mes completo)
  • 1 febrero-1 marzo ---> 28 o 29 días ---> se traducirá en 1 (lógico ya que es un mes completo)
  • 15 febrero-15 marzo ---> 28 o 29 días ---> resultará en 1 (lógico ya pasó un mes)
  • 31 enero-1 febrero ---> 1 día ---> resultará en 0 (obvio, pero la respuesta se menciona en el post resultados en 1 mes)

La diferencia de meses entre dos fechas en 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)

totales meses entre fecha_inicial y fecha_final:

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

Sé que es muy tarde, pero la publicación de todos modos en caso de que ayuda a los demás. Aquí es una función que se me ocurrió que parece hacer un trabajo bien de diferencias de recuento de meses entre dos fechas. Es cierto que es un gran trato que raunchier Mr.Crowder de, pero proporciona resultados más precisos paso a paso por el objeto de fecha. Es en AS3, sino que sólo debe ser capaz de soltar el tipado fuerte y que tendrá JS. Siéntase libre para que sea más agradable buscando alguien por ahí!

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

Considere cada fecha en términos de meses, luego resta para encontrar la diferencia.

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

Esto le dará la diferencia de meses entre las dos fechas, haciendo caso omiso de los días.

Para ampliar la respuesta de @ T. J., si usted está buscando mes simples, en lugar de meses completos, usted podría comprobar si la fecha de d2 es mayor que o igual a d1 de que. Es decir, si d2 es más tarde en su mes que d1 está en su mes, entonces no hay más de 1 mes. Por lo que debe ser capaz de simplemente hacer esto:

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

Esto no tiene en cuenta totalmente por cuestiones de tiempo (por ejemplo, 3 de marzo a las 4:00 pm y 3 de abril a 15:00), pero es más preciso y por sólo un par de líneas de código.

Hay dos enfoques, matemáticos y rápidos, pero sujetas a los caprichos del calendario, o iterativos y lentos, pero se ocupa de todas las rarezas (o al menos la manipulación de una biblioteca bien probado delegados).

Si una iteración en el calendario, incrementando la fecha de inicio en un mes y ver si se pasa la fecha de finalización. Esta anomalía delegados de manejo a las clases incorporadas (Fecha), pero podría ser lenta que estás haciendo esto por un gran número de fechas. respuesta de James toma este enfoque. Por mucho que me gusta la idea, creo que este es el enfoque más "segura", y si sólo está haciendo un cálculo, la diferencia de rendimiento realmente es insignificante. Tenemos la tendencia a tratar de optimizar el exceso de tareas que sólo se realiza una vez.

Ahora, si que estés calcular esta función en un conjunto de datos, es probable que no quieren correr esa función en cada fila (o dios no lo quiera, varias veces por registro). En ese caso, puede utilizar casi cualquier de las otras respuestas aquí excepto la respuesta aceptada, que es simplemente incorrecto (diferencia entre new Date() y new Date() es -1)?

Aquí está mi puñalada en un enfoque rápido matemática-and-, que representa las diferentes duraciones de los meses y años bisiestos. Que realmente sólo se debe utilizar una función como esta, si se le solicita a un conjunto de datos (hacer este cálculo una y otra). Si sólo tiene que hacerlo una vez, utilice James' iterativo enfoque anterior, ya que estás delegar el manejo de todos los (muchos) excepciones al objeto 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;
}

aquí ir otro enfoque con menos de bucle:

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

Calcular la diferencia entre dos fechas incluyen fracción de mes (día).


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

Por ejemplo:
   fecha1 : 24/09/2015 (24 de Sept 2015)
   la fecha 2 : 09/11/2015 (del 9 Nov 2015)
  la diferencia: 2,5 (meses)

Esto debería funcionar bien:

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

También podría considerar esta solución, este function devuelve la diferencia en el mes entero o número

Al pasar el Fecha empezar como la primera o la última param, es tolerante a fallos. Esto quiere decir que la función aún sería devolver el mismo valor.

const diffInMonths = (end, start) => {
   var timeDiff = Math.abs(end.getTime() - start.getTime());
   return Math.round(timeDiff / (2e3 * 3600 * 365.25));
}

const result = diffInMonths(new Date(2015, 3, 28), new Date(2010, 1, 25));

// shows month difference as integer/number
console.log(result);

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

Tras código vuelve meses completos entre dos fechas tomando Nº de días de meses parciales en cuenta también.

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;

}

debajo de la lógica buscará diferencia en meses

(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
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;
}

Ver lo que yo uso:

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

También cuenta los días y las convierte en meses.

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 

Para la prosperidad,

Moment.js puede lograr esto haciendo:

const monthsLeft = moment(endDate).diff(moment(startDate), 'month');
anyVar = (((DisplayTo.getFullYear() * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear() * 12) + DisplayFrom.getMonth()));

Un enfoque sería escribir un simple servicio web Java (REST / JSON) que utiliza la biblioteca JODA

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

para calcular la diferencia entre dos fechas y llamadas que el servicio de JavaScript.

Esto supone que su extremo posterior es en Java.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top