web-dev-qa-db-de.com

Differenz in Monaten zwischen zwei Datumsangaben in JavaScript

Wie würde ich den Unterschied für zwei Date () - Objekte in JavaScript ermitteln und dabei nur die Anzahl der Monate im Unterschied zurückgeben?

Jede Hilfe wäre toll :)

107
williamtroup

Die Definition der "Anzahl der Monate im Unterschied" unterliegt viel Interpretation. :-)

Sie können Jahr, Monat und Tag des Monats von einem JavaScript-Datumsobjekt abrufen. Abhängig von den gesuchten Informationen können Sie anhand dieser Informationen ermitteln, wie viele Monate zwischen zwei Zeitpunkten liegen.

Off-the-cuff ermittelt dies beispielsweise, wie viele volle Monate zwischen zwei Datumsangaben liegen, wobei Teilmonate nicht gezählt werden (z. B. ohne den Monat, in dem sich jedes Datum befindet):

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

(Beachten Sie, dass die Monatswerte in JavaScript mit 0 = Januar beginnen.)

Es ist viel komplizierter, einen Bruchteil von Monaten in das obige einzubeziehen, da drei Tage in einem typischen Februar ein größerer Bruchteil dieses Monats sind (~ 10,714%) als drei Tage im August (~ 9,677%), und natürlich ist selbst der Februar ein bewegendes Ziel abhängig davon, ob es ein Schaltjahr ist.

Es gibt auch einige Datums- und Zeitbibliotheken , die für JavaScript verfügbar sind und wahrscheinlich diese Art der Dinge erleichtern.

195
T.J. Crowder
return DisplayTo.getMonth() - DisplayFrom.getMonth()
       + (12 * (DisplayTo.getFullYear() - DisplayFrom.getFullYear()));
56
Tom Gullen

Manchmal möchten Sie vielleicht nur die Menge der Monate zwischen zwei Datumsangaben erhalten, wobei der Tag-Teil völlig ignoriert wird. Wenn Sie beispielsweise zwei Termine hatten (2013/06/21 und 2013/10/18-) und sich nur um die Teile von 2013/06 und 2013/10 kümmerten, sind hier die Szenarien und möglichen Lösungen:

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.Wenn Sie nur die Anzahl der Monate zwischen den beiden Datumsangaben wünschen, ausgenommen Monat1 und Monat2

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

2.Wenn Sie einen der Monate einschließen möchten

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

3.Wenn Sie beide Monate einbeziehen möchten

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

Wenn Sie volle Monate zählen müssen, unabhängig davon, ob der Monat 28, 29, 30 oder 31 Tage ist. Unten sollte funktionieren. 

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

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

Dies ist eine erweiterte Version der Antwort https://stackoverflow.com/a/4312956/1987208 , behebt jedoch den Fall, in dem ein Monat für den Fall vom 31. Januar bis 1. Februar (1 Tag) berechnet wird.

Dies wird das Folgende abdecken;

  • 1. Januar bis 31. Januar ---> 30days ---> ergibt 0 (logisch, da es kein voller Monat ist)
  • 1. Februar bis 1. März ---> 28 oder 29 Tage ---> ergibt 1 (logisch, da es ein voller Monat ist)
  • 15. Februar bis 15. März ---> 28 oder 29 Tage ---> ergibt 1 (logisch seit einem Monat)
  • 31. Januar bis 1. Februar ---> 1 Tag ---> führt zu 0 (offensichtlich, aber die erwähnte Antwort in den Beiträgen ergibt einen Monat)
22
harun

Hier ist eine Funktion, die die Anzahl der Monate zwischen zwei Daten genau angibt.
Das Standardverhalten zählt nur ganze Monate, z. 3 Monate und 1 Tag ergeben einen Unterschied von 3 Monaten. Sie können dies verhindern, indem Sie den Parameter roundUpFractionalMonths auf true setzen. Eine Differenz von 3 Monaten und 1 Tag wird als 4 Monate zurückgegeben.

Die oben akzeptierte Antwort (Antwort von T.J. Crowder) ist nicht genau, sie liefert manchmal falsche Werte.

Zum Beispiel gibt monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))0 zurück, was offensichtlich falsch ist. Der korrekte Unterschied beträgt entweder 1 ganzen Monat oder 2 Monate aufgerundet.

Hier ist die Funktion, die ich geschrieben habe:

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

Differenz in Monaten zwischen zwei Datumsangaben in 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)

gesamtmonate zwischen start_date und end_date:

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

Ich weiß, dass das wirklich spät ist, aber es trotzdem zu veröffentlichen, nur für den Fall, dass es anderen hilft. Hier ist eine Funktion, die ich mir ausgedacht habe und die Unterschiede zwischen zwei Terminen in Monaten gut zu zählen scheint. Es ist zwar viel schlüpfriger als das von Mr.Crowder, liefert jedoch genauere Ergebnisse, indem er durch das Datumsobjekt geht. Es ist in AS3, aber Sie sollten in der Lage sein, das starke Tippen einfach zu löschen und Sie haben JS. Fühlen Sie sich frei, um es schöner zu machen, wenn Sie jemanden da draußen suchen!

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

Betrachten Sie jedes Datum in Monaten und ziehen Sie es dann ab, um die Differenz zu ermitteln.

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

Dadurch erhalten Sie die Differenz der Monate zwischen den beiden Datumsangaben und ignorieren die Tage.

5
internet-nico

Um die Antwort von @ T.J. zu erweitern, können Sie, wenn Sie nach einfachen Monaten und nicht nach vollen Kalendermonaten suchen, einfach prüfen, ob das Datum von d2 größer oder gleich dem von d1 ist. Das heißt, wenn d2 später in seinem Monat ist als d1 in seinem Monat, dann gibt es einen weiteren Monat. Sie sollten also in der Lage sein, dies einfach zu tun:

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

Zeitprobleme (z. B. der 3. März um 16:00 Uhr und der 3. April um 15:00 Uhr) sind nicht unbedingt berücksichtigt, aber es ist genauer und nur für ein paar Zeilen Code.

4
calvin

Es gibt zwei Ansätze: mathematisch und schnell, jedoch mit Unstimmigkeiten im Kalender oder iterativ und langsam, jedoch mit allen Eigenheiten (oder zumindest Delegierten, die sie in einer bewährten Bibliothek verwalten).

Wenn Sie den Kalender durchlaufen, erhöhen Sie das Startdatum um einen Monat und prüfen, ob das Enddatum überschritten wird. Dies delegiert die Behandlung von Anomalien an die integrierten Date () - Klassen, könnte aber LANGSAM SEIN, WENN dies für eine große Anzahl von Datumsangaben ausführt. James Antwort nimmt diesen Ansatz. So sehr ich die Idee nicht mag, denke ich, dass dies der "sicherste" Ansatz ist, und wenn Sie nur one -Kalkulationen durchführen, ist der Leistungsunterschied wirklich vernachlässigbar. Wir neigen dazu, Aufgaben zu überoptimieren, die nur einmal ausgeführt werden.

Nun, falls Sie diese Funktion für ein Dataset berechnen, möchten Sie diese Funktion wahrscheinlich nicht für jede Zeile ausführen (oder, wenn es mehrmals pro Datensatz verboten ist). In diesem Fall können Sie fast alle anderen Antworten hier verwenden mit Ausnahme von der akzeptierten Antwort, die einfach falsch ist (Unterschied zwischen new Date() und new Date() ist -1)? 

Hier ist mein Ansatz bei einem mathematisch-schnellen Ansatz, der unterschiedliche Monatslängen und Schaltjahre berücksichtigt. Sie sollten eine solche Funktion nur dann verwenden, wenn Sie diese auf ein Dataset anwenden (diese Berechnung wird immer wieder ausgeführt). Wenn Sie es nur einmal tun müssen, verwenden Sie James 'iterativen Ansatz (siehe oben), da Sie die Behandlung aller (vielen) Ausnahmen für das Date () - Objekt delegieren.

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

Hier Sie gehen andere Wege mit weniger Looping:

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

Das sollte gut funktionieren:

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

Der folgende Code gibt volle Monate zwischen zwei Terminen zurück, wobei auch die Anzahl der Tage von Teilmonaten berücksichtigt wird.

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
1
Delorean
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;

}

1
Tariq

unterhalb der Logik wird die Differenz in Monaten abgerufen

(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
1
Anoop Isaac

Berechnen Sie die Differenz zwischen zwei Datumsangaben einschließlich des Bruchteils des Monats (Tage).


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

Zum Beispiel:
Datum1 : 24/09/2015 (24. September 2015)
date2 : 09/11/2015 (9. Nov 2015)
der Unterschied: 2.5 (Monate)

1
Shneor
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);
}
1
shoaib fazlani
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;
}
1
Abbas Siddiqi

Für Wohlstand

Mit Moment.js können Sie dies erreichen, indem Sie Folgendes tun: 

const monthsLeft = moment(endDate).diff(moment(startDate), 'month');
0
The224

Es zählt auch die Tage und rechnet sie in Monaten um.

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 
0
Gaurav Jain

anyVar = ((((DisplayTo.getFullYear () * 12) + DisplayTo.getMonth ()) - ((DisplayFrom.getFullYear () * 12) + DisplayFrom.getMonth ()));

0
Aris Dela Rea

Sie können diese Lösung auch in Betracht ziehen. Diese function gibt die Monatsdifferenz in Ganzzahl oder Zahl zurück 

Das Übergeben desStartdatumsals erste oder letzte param ist fehlertolerant. Das heißt, die Funktion würde immer noch denselben Wert zurückgeben.

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

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

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

0
Hamzeen Hameem

Sehen Sie, was ich benutze:

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;
}
0
Fayez Zalloum