web-dev-qa-db-fra.com

Moment.js différence de mois

Cela fait un moment que je me sers de moment.js, et la manipulation des dates a été simplifiée, mais j'ai un cas spécifique qui échoue et je ne vois pas pourquoi.

Lors du calcul du diff entre aujourd'hui (31 octobre 2013) et le 1er février 2014, le diff de mois revient à 2, bien qu'il y ait 3 mois complets et un jour entre les deux dates.

Diff entre le 31 octobre et le 31 janvier fonctionne bien: 3 mois et zéro jours.

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 console enregistre les éléments suivants:

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 je passe vrai comme le booléen à ne pas arrondir, le diff diffère en mois

monthsDiff: 2.983050847457627 

Est-ce juste un bug dans Moment.js.diff ()? Chacun de mes autres cas de test réussit.

31
Khain

Je pense que cela a à voir avec le "traitement spécial" décrit dans The Fine Manual :

Il est optimisé pour garantir que deux mois avec la même date sont toujours un nombre entier à part.

Donc, du 15 janvier au 15 février devrait être exactement 1 mois.

28 février au 28 mars devrait être exactement 1 mois.

28 février 2011 au 28 février 2012 devrait être exactement 1 an.

Moment.js applique ce traitement spécial lorsqu’il s’agit de 31 Jan et 31 Oct (le même jour):

// 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

Donc, la valeur 2.98 est correcte, c'est simplement que le deuxième exemple transforme le résultat en différence de «mois calendaire».

(comme pour arrondir à 2, c'est aussi documenté sur la même page)

39
robertklep

Je suis allé par un chemin différent en essayant de faire la différence entre deux mois

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;

Cela me paraissait logique et comme instant fait des choses étranges avec diff, je viens de décider de préciser le résultat.

10
MrB

Solution simple et facile avec une différence de valeur correcte entre deux mois si vous utilisez moment Library

  const monthDifference =  moment(new Date(endDate)).diff(new Date(startDate), 'months', true);

Si vous voulez ajouter le nombre de jours dans endDate

 const monthDifference = moment(new Date(endDate.add(1, 'days'))).diff(new Date(startDate), 'months', true);
0
Gaurav verma