224 votes

Différence en mois entre deux dates en JavaScript

Comment puis-je calculer la différence entre deux objets Date() en JavaScript, tout en ne renvoyant que le nombre de mois de la différence ?

Toute aide serait la bienvenue :)

0 votes

Un mois n'est pas une unité de mesure très précise, car la durée du mois change en fonction du mois dans lequel on se trouve. Si un intervalle dure 30 jours entre janvier et février, c'est moins d'un mois si l'on raisonne en termes de mois de 31 jours, mais plus d'un mois si l'on considère que février compte 28 ou 29 jours.

8 votes

Question pas très bien définie. Est-ce que le 28 février 23:58 au 1er mars 00:01 est un mois ? Ou juste un jour ? Ou seulement trois minutes ? Ou les trois ?

2 votes

La personne qui doit mettre en œuvre cette mesure n'aura probablement pas de réponse, car son responsable n'a aucune idée de ce qu'elle demande :)

4voto

Michael Blackburn Points 589

Il existe deux approches, l'une mathématique et rapide, mais sujette aux aléas du calendrier, l'autre itérative et lente, mais qui gère toutes les bizarreries (ou du moins délègue leur traitement à une bibliothèque bien testée).

Si on itère dans le calendrier, en incrémentant la date de début d'un mois et en regardant si on dépasse la date de fin. Cette méthode délègue la gestion des anomalies aux classes Date() intégrées, mais elle peut être lente. SI vous faites ça pour un grand nombre de dates. La réponse de James adopte cette approche. Même si je n'aime pas l'idée, je pense que c'est l'approche la plus sûre, et si vous ne faites que de la un la différence de performance est vraiment négligeable. Nous avons tendance à essayer de sur-optimiser les tâches qui ne seront exécutées qu'une seule fois.

Maintenant, si vous calculez cette fonction sur un ensemble de données, vous ne souhaitez probablement pas exécuter cette fonction sur chaque ligne (ou, Dieu nous en préserve, plusieurs fois par enregistrement). Dans ce cas, vous pouvez utiliser n'importe laquelle des autres réponses suivantes sauf la réponse acceptée, qui est tout simplement fausse (différence entre new Date() et new Date() est -1) ?

Voici mon approche mathématique et rapide, qui tient compte des différentes longueurs de mois et des années bissextiles. Vous ne devriez vraiment utiliser une fonction comme celle-ci que si vous devez l'appliquer à un ensemble de données (en effectuant ce calcul plusieurs fois). Si vous n'avez besoin de le faire qu'une fois, utilisez l'approche itérative de James ci-dessus, car vous déléguez la gestion de toutes les (nombreuses) exceptions à l'objet 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;
}

4voto

Shneor Points 1

Calculez la différence entre deux dates en incluant une fraction de mois (jours).


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

Par exemple :
date1 : 24/09/2015 (24 sept 2015)
date2 : 09/11/2015 (9 nov 2015)
la différence : 2,5 (mois)

3voto

Matthew Rideout Points 998

Nombre de mois où le jour et l'heure n'ont pas d'importance

Dans ce cas, je ne me préoccupe pas des mois complets, des mois partiels, de la durée d'un mois, etc. J'ai juste besoin de connaître le nombre de mois. Un cas concret et pertinent serait celui d'un rapport qui doit être remis tous les mois, et j'ai besoin de savoir combien de rapports il doit y avoir.

Exemple :

  • Janvier = 1 mois
  • Janvier - février = 2 mois
  • Novembre - janvier = 3 mois

Il s'agit d'un exemple de code élaboré pour montrer où vont les chiffres.

Prenons 2 horodatages qui devraient donner 4 mois

  • L'horodatage du 13 novembre 2019 : 1573621200000
  • L'horodatage du 20 février 2020 : 1582261140000

Peut être légèrement différent avec votre fuseau horaire / heure tirée. Le jour, les minutes et les secondes n'ont pas d'importance et peuvent être inclus dans l'horodatage, mais nous n'en tiendrons pas compte dans notre calcul.

Étape 1 : convertir le timestamp en une date JavaScript

let dateRangeStartConverted = new Date(1573621200000);
let dateRangeEndConverted = new Date(1582261140000);

Étape 2 : obtenir des valeurs entières pour les mois / années

let startingMonth = dateRangeStartConverted.getMonth();
let startingYear = dateRangeStartConverted.getFullYear();
let endingMonth = dateRangeEndConverted.getMonth();
let endingYear = dateRangeEndConverted.getFullYear();

Cela nous donne

  • Mois de départ : 11
  • Année de démarrage : 2019
  • Mois de fin : 2
  • Année de fin : 2020

Étape 3 : Ajouter (12 * (endYear - startYear)) + 1 au mois de clôture.

  • Cela fait que notre mois de départ reste à 11
  • Notre mois de fin est donc égal à 15 2 + (12 * (2020 - 2019)) + 1 = 15

Étape 4 : Soustraire les mois

15 - 11 = 4 ; nous obtenons le résultat de nos 4 mois.

29 mois Exemple Exemple

De novembre 2019 à mars 2022, cela fait 29 mois. Si vous mettez ces chiffres dans une feuille de calcul Excel, vous verrez 29 lignes.

  • Notre mois de départ est le 11
  • Notre mois de clôture est de 40 3 + (12 * (2022-2019)) + 1

40 - 11 = 29

2voto

ggomeze Points 3024

Ici vous adoptez une autre approche avec moins de boucles :

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

1 votes

Attention à cette méthode : elle modifie (de manière assez évidente quand on la lit attentivement) la première date qui est renvoyée à l'appelant (puisque les dates sont passées par référence).

2voto

Thiago Jordan Points 83

Cela devrait fonctionner correctement :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X