change - javascript meta tag




Momento.js mes de diferencia (2)

He estado usando moment.js por un corto tiempo, y ha facilitado mucho la manipulación de fechas, pero tengo un caso específico que está fallando y no puedo ver por qué.

Al calcular la diferencia entre el día de hoy (31 de octubre de 2013) y el 1 de febrero de 2014, la diferencia de meses vuelve a ser 2, aunque hay 3 meses completos y un día entre las dos fechas.

La diferencia entre el 31 de octubre y el 31 de enero funciona bien: 3 meses y cero días.

var mStartDate = moment([ periodStartDate.getFullYear(), periodStartDate.getMonth(), periodStartDate.getDate() ]);
var mTermDate = moment([ someDate.getFullYear(), someDate.getMonth(), someDate.getDate() ]);

console.log('periodStartDate: ' + periodStartDate);
console.log('someDate: ' + someDate);

// Years
var yearsDiff = mTermDate.diff(mStartDate, 'years');

// Months
var monthsDiff = mTermDate.diff(mStartDate, 'months', true);

La consola registra lo siguiente:

periodStartDate: Thu Oct 31 2013 11:13:51 GMT+0000 (GMT)
someDate: Sat Feb 01 2014 11:13:51 GMT+0000 (GMT)
monthsDiff: 2

Si paso verdadero como el booleano para no redondear, los meses difieren

monthsDiff: 2.983050847457627 

¿Es esto solo un error en Moment.js.diff ()? Todos y cada uno de mis otros casos de prueba pasan con éxito.


Creo que esto tiene que ver con el 'manejo especial' como se describe en The Fine Manual :

Está optimizado para garantizar que dos meses con la misma fecha siempre tengan un número entero aparte.

Así que del 15 de enero al 15 de febrero debe ser exactamente 1 mes.

Del 28 de febrero al 28 de marzo debe ser exactamente 1 mes.

Del 28 de febrero de 2011 al 28 de febrero de 2012 debe ser exactamente 1 año.

Moment.js aplica este tratamiento especial cuando se trata del 31 Jan y el 31 Oct (con el mismo día):

// 31 Oct 2013 - 1 Feb 2014
> moment([2014, 1, 1]).diff(moment([2013, 9, 31]), 'months', true)
2.983050847457627

// 31 Oct 2013 - 31 Jan 2014
> moment([2014, 0, 31]).diff(moment([2013, 9, 31]), 'months', true)
3

// 31 Oct 2013 - 30 Jan 2014
> moment([2014, 0, 30]).diff(moment([2013, 9, 31]), 'months', true)
2.967741935483871

Entonces, el valor de 2.98 es correcto, es solo que el segundo ejemplo convierte el resultado en una diferencia de 'meses calendario'.

(en cuanto a redondear a 2, eso también está documentado en la misma página)


Tomé una ruta diferente tratando de obtener la diferencia entre dos meses.

function getAbsoulteMonths(momentDate) {
  var months = Number(momentDate.format("MM"));
  var years = Number(momentDate.format("YYYY"));
  return months + (years * 12);
}

var startMonths = getAbsoulteMonths(start);
var endMonths = getAbsoulteMonths(end);

var monthDifference = endMonths - startMonths;

Esto tenía sentido para mí y desde el momento en que hago cosas extrañas con dificultad, simplemente decidí aclarar cuál será mi resultado.







momentjs