Question

Comment puis-je travailler la différence pour deux Date () des objets en JavaScript, alors que seulement retourner le nombre de mois dans la différence?

Toute aide serait grande:)

Était-ce utile?

La solution

La définition de « le nombre de mois dans la différence » est soumise à beaucoup d'interprétation. : -)

Vous pouvez obtenir l'année, le mois et le jour du mois à partir d'un objet Date JavaScript. Selon les informations que vous cherchez, vous pouvez les utiliser pour savoir combien de mois sont entre deux points dans le temps.

Par exemple, hors le brassard, ce trouve combien de mois complets sont compris entre deux dates, sans compter les mois partiels (par exemple, à l'exclusion du mois chaque date est):

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

(Notez que les valeurs de mois en JavaScript commencent par 0 = Janvier.)

Y compris les mois fractions dans ce qui précède est beaucoup plus compliquée, parce que trois jours dans un cadre typique Février est une fraction plus importante de ce mois (~ 10,714%) que trois jours en Août (~ 9,677%), et bien sûr, même Février est une cible mobile selon que ce soit une année bissextile.

Il y a aussi quelques date et les bibliothèques temps disponibles pour JavaScript qui font sans doute ce genre de chose plus facile.

Autres conseils

Si vous ne considérez pas le jour du mois, c'est de loin la solution plus 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

Sachez que l'indice mois est base 0. Cela signifie que January = 0 et December = 11.

Parfois, vous pouvez obtenir seulement la quantité des mois entre deux dates en ignorant totalement la partie de la journée. Ainsi, par exemple, si vous aviez deux 21.06.2013 et 2013 DATES / 10 / 18- et vous ne teniez sur les parties 2013/06 et 2013/10, voici les scénarios et les solutions possibles:

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 vous voulez juste le nombre de mois entre les deux dates excluant les deux mois1 et month2

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

2. Si vous voulez inclure soit des mois

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

3. Si vous voulez inclure les deux mois

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

Voici une fonction qui fournit avec précision le nombre de mois entre 2 dates.
Le comportement par défaut ne compte que des mois entiers, par exemple 3 mois et 1 jour se traduira par une différence de 3 mois. Vous pouvez éviter cela en réglant le roundUpFractionalMonths param true, donc une différence de 3 mois et 1 jour sera retourné en 4 mois.

La réponse acceptée ci-dessus (la réponse de Crowder T.J.) n'est pas exacte, elle renvoie des valeurs erronées parfois.

Par exemple, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015')) retourne 0 ce qui est évidemment faux. La différence correcte est 1 mois entier ou 2 mois-up arrondi.

Voici la fonction que j'ai écrit:

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 vous avez besoin de compter mois complets, quel que soit le mois étant de 28, 29, 30 ou 31 jours. devrait fonctionner ci-dessous.

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

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

Ceci est une version étendue de la réponse https://stackoverflow.com/a/4312956/1987208 mais fixe le cas où il calcule 1 mois pour le cas du 31 de Janvier au 1er Février (1 jour).

Cela couvrira les points suivants:

  • 1 janvier-31 janvier ---> 30 jours ---> se traduira par 0 (logique puisque ce n'est pas un mois)
  • 1 février au 1 mars ---> 28 ou 29 jours ---> se traduira par 1 (logique car il est un mois)
  • 15 février au 15 mars ---> 28 ou 29 jours ---> entraînera 1 (logique depuis un mois passé)
  • 31 janvier au 1 février ---> 1 jour ---> entraînera 0 (évident, mais la réponse mentionnée dans les résultats de poste en 1 mois)

Différence en mois entre deux dates 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)

mois au total entre date_début et date_fin:

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

Je sais que c'est vraiment en retard, mais l'affichage de toute façon juste au cas où il aide les autres. Voici une fonction que je suis venu avec qui semble faire un bon travail des différences de comptage dans les mois entre deux dates. Certes, il est beaucoup raunchier que Mr.Crowder de, mais fournit des résultats plus précis en marchant à travers l'objet de la date. Il est en AS3, mais vous devez simplement être en mesure de laisser tomber le typage fort et vous aurez JS. Ne hésitez pas à le rendre plus agréable en regardant quelqu'un là-bas!

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

Considérez chaque jour en termes de mois, puis soustrayez pour trouver la différence.

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

vous obtiendrez la différence des mois entre les deux dates, en ignorant les jours.

Pour développer @ la réponse de T.J., si vous cherchez des mois simples, au lieu de mois civils complets, vous pouvez simplement vérifier si la date de d2 est supérieure ou égale à d1 que celui. Autrement dit, si d2 est plus tard dans son mois que d1 est en mois, puis il y a 1 mois de plus. Donc, vous devriez être en mesure de faire ceci:

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

Cela ne compte tout à fait pour des questions de temps (par exemple de 3 Mars à 16h00 et le 3 Avril à 15h00), mais il est plus précis et pour seulement quelques lignes de code.

Il existe deux approches, mathématiques et rapides, mais sous réserve des aléas du calendrier, ou itératives et lent, mais gère toutes les bizarreries (ou au moins les délégués qui les manipulent à une bibliothèque bien testée).

Si vous itérer le calendrier, incrémenter la date de début d'un mois et voir si nous passons la date de fin. Cette délégués de traitement anomalie la date intégrée () des classes, mais pourrait être lent IF vous faites cela pour un grand nombre de dates. La réponse de James prend cette approche. Autant que je déteste l'idée, je pense que c'est l'approche « plus sûre », et si vous faites seulement un calcul, la différence de performance est vraiment négligeable. Nous avons tendance à essayer de trop optimiser les tâches qui ne seront réalisées qu'une seule fois.

si vous calculez cette fonction sur un ensemble de données, vous ne voulez probablement pas d'exécuter cette fonction sur chaque ligne (ou à Dieu ne plaise, plusieurs fois par dossier). Dans ce cas, vous pouvez utiliser presque toutes les autres réponses ici sauf la réponse acceptée, ce qui est tout simplement faux (différence entre new Date() et new Date() est -1)?

Voici mon coup de couteau à une approche mathématique et rapide, ce qui représente différentes longueurs des mois et des années bissextiles. Vous devriez vraiment seulement utiliser une fonction comme celui-ci si vous postulez à un ensemble de données (faire ce calcul sur et plus). Si vous avez juste besoin de le faire une fois, utilisez l'approche itérative de James ci-dessus, vous déléguez traiter 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;
}

Ici vous allez autre approche avec moins mise en boucle:

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

Calculer la différence entre deux dates comprennent 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 septembre 2015)
   date2 : 11/09/2015 (9 novembre 2015)
  la différence: 2,5 (mois)

Cela devrait bien:

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

Vous pouvez aussi envisager cette solution, cette function retourne la différence de mois en nombre entier ou

Passage date de début comme premier ou dernier param, est tolérant aux pannes. Signification, la fonction retournerait toujours la même valeur.

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

Après le code retourne mois complet entre deux dates en prenant de nombre de jours de mois partiels en compte.

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;

}

ci-dessous logique va chercher la différence dans les mois

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

Voyez ce que j'utilise:

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

Il compte aussi les jours et les convertir en mois.

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 

Pour la prospérité,

Moment.js vous pouvez y parvenir en faisant:

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

Une approche serait d'écrire simple Java Web Service (REST / JSON) qui utilise la bibliothèque JODA

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

pour calculer la différence entre deux dates et appeler ce service de javascript.

Cela suppose votre arrière est en Java.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top