Wie würde ich die Differenz für zwei Date () -Objekte in JavaScript berechnen und dabei nur die Anzahl der Monate in der Differenz zurückgeben?
Jede Hilfe wäre toll :)
Wie würde ich die Differenz für zwei Date () -Objekte in JavaScript berechnen und dabei nur die Anzahl der Monate in der Differenz zurückgeben?
Jede Hilfe wäre toll :)
Antworten:
Die Definition von "Anzahl der Monate in der Differenz" wird vielfach interpretiert. :-)
Sie können das Jahr, den Monat und den Tag des Monats aus einem JavaScript-Datumsobjekt abrufen. Je nachdem, nach welchen Informationen Sie suchen, können Sie anhand dieser Informationen herausfinden, wie viele Monate zwischen zwei Zeitpunkten liegen.
Zum Beispiel von der Stange:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth();
months += d2.getMonth();
return months <= 0 ? 0 : months;
}
(Beachten Sie, dass Monatswerte in JavaScript mit 0 = Januar beginnen.)
Das Einbeziehen von Bruchmonaten in das oben Gesagte ist viel komplizierter, da drei Tage in einem typischen Februar einen größeren Bruchteil dieses Monats (~ 10,714%) darstellen als drei Tage im August (~ 9,677%), und natürlich ist sogar der Februar ein bewegliches Ziel je nachdem ob es ein Schaltjahr ist.
Es gibt auch einige Datums- und Zeitbibliotheken für JavaScript, die diese Art von Dingen wahrscheinlich einfacher machen.
Hinweis : Hier war früher ein + 1
:
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
// −−−−−−−−−−−−−−−−−−−−^^^^
months += d2.getMonth();
Das liegt daran, dass ich ursprünglich gesagt habe:
... dies findet heraus, wie viele volle Monate zwischen zwei Daten liegen, ohne Teilmonate (z. B. ohne den Monat, in dem sich jedes Datum befindet).
Ich habe es aus zwei Gründen entfernt:
Teilmonate nicht zu zählen, stellt sich als nicht das heraus, was viele (die meisten?) Leute, die zur Antwort kommen, wollen, also dachte ich, ich sollte sie trennen.
Selbst nach dieser Definition hat es nicht immer funktioniert. :-D (Entschuldigung.)
Wenn Sie den Tag des Monats nicht berücksichtigen, ist dies bei weitem die einfachere Lösung
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
Beachten Sie, dass der Monatsindex auf 0 basiert. Dies bedeutet, dass January = 0
und December = 11
.
Manchmal möchten Sie vielleicht nur die Anzahl der Monate zwischen zwei Daten erhalten, ohne den Tagesteil zu beachten. Wenn Sie beispielsweise zwei Daten hatten - 2013/06/21 und 2013/10 / 18- und sich nur um die Teile 2013/06 und 2013/10 gekümmert haben, sind hier die Szenarien und möglichen Lösungen aufgeführt:
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 Daten ohne Monat1 und Monat2 möchten
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;
2.Wenn Sie einen der Monate einbeziehen möchten
numberOfMonths = (year2 - year1) * 12 + (month2 - month1);
3.Wenn Sie beide Monate einbeziehen möchten
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;
numberOfMonths=(year2-year1)*12+(month2-month1)+1;
was das gleiche tut, aber für mich semantisch korrekter ist
Hier ist eine Funktion, die die Anzahl der Monate zwischen zwei Daten genau angibt.
Das Standardverhalten zählt nur ganze Monate, z. B. 3 Monate und 1 Tag ergibt eine Differenz von 3 Monaten. Sie können dies verhindern, indem Sie den roundUpFractionalMonths
Parameter auf festlegen true
, sodass eine Differenz von 3 Monaten und 1 Tag als 4 Monate zurückgegeben wird.
Die oben akzeptierte Antwort (die Antwort von TJ Crowder) ist nicht korrekt und gibt manchmal falsche Werte zurück.
Zum Beispiel monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))
Rückgaben, 0
die offensichtlich falsch sind. Die korrekte Differenz 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);
};
Wenn Sie volle Monate zählen müssen, unabhängig davon, ob der Monat 28, 29, 30 oder 31 Tage beträgt. 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 1 Monat für den Fall vom 31. Januar bis 1. Februar (1 Tag) berechnet wird.
Dies wird Folgendes abdecken:
Unterschied in Monaten zwischen zwei Daten 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 Startdatum und Enddatum:
total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())
Ich weiß, dass dies wirklich spät ist, aber es trotzdem zu posten, nur für den Fall, dass es anderen hilft. Hier ist eine Funktion, die ich mir ausgedacht habe und die anscheinend die Unterschiede in Monaten zwischen zwei Daten gut zählt. Es ist zwar viel schlüpfriger als das von Mr. Crowder, liefert jedoch genauere Ergebnisse, indem es durch das Datumsobjekt geht. Es ist in AS3, aber Sie sollten nur in der Lage sein, die starke Eingabe zu löschen, und Sie werden JS haben. Fühlen Sie sich frei, 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;
}
Betrachten Sie jedes Datum in Monaten und subtrahieren Sie es, um den Unterschied 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 Daten, wobei die Tage ignoriert werden.
Um die Antwort von @ TJ zu erweitern: Wenn Sie nach einfachen Monaten anstatt nach vollen Kalendermonaten suchen, können Sie einfach überprüfen, ob das Datum von d2 größer oder gleich d1 ist. Das heißt, wenn d2 später in seinem Monat ist als d1 in seinem Monat, dann gibt es 1 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
Dies berücksichtigt Zeitprobleme nicht vollständig (z. B. 3. März um 16:00 Uhr und 3. April um 15:00 Uhr), ist jedoch genauer und gilt nur für ein paar Codezeilen.
Es gibt zwei Ansätze: mathematisch und schnell, jedoch mit Abweichungen im Kalender oder iterativ und langsam, die jedoch alle Kuriositäten behandeln (oder zumindest Delegierte, die sie bearbeiten, in eine gut getestete Bibliothek).
Wenn Sie den Kalender durchlaufen, erhöhen Sie das Startdatum um einen Monat und prüfen, ob das Enddatum überschritten wird. Diese Delegierten Anomalie-Behandlung auf die integrierte Date () Klassen, aber langsam sein könnte IF Sie dies für eine große Anzahl von Terminen tun. James 'Antwort folgt diesem Ansatz. So sehr ich die Idee nicht mag, denke ich, dass dies der "sicherste" Ansatz ist, und wenn Sie nur eine Berechnung durchführen, ist der Leistungsunterschied wirklich vernachlässigbar. Wir neigen dazu, Aufgaben zu optimieren, die nur einmal ausgeführt werden.
Jetzt, wenn Sie diese Funktion auf einem Datensatz sind zu berechnen, werden Sie wahrscheinlich nicht wollen , dass die Funktion in jeder Zeile (oder Gott bewahre, mehrmals pro Datensatz) laufen. In diesem Fall können Sie fast jede der anderen Antworten hier verwenden, außer der akzeptierten Antwort, die einfach falsch ist (Unterschied zwischen new Date()
und new Date()
ist -1).
Hier ist mein Versuch eines mathematisch-schnellen Ansatzes, der unterschiedliche Monatslängen und Schaltjahre berücksichtigt. Sie sollten eine solche Funktion wirklich nur verwenden, wenn Sie sie auf einen Datensatz anwenden (diese Berechnung immer wieder durchführen). Wenn Sie dies nur einmal tun müssen, verwenden Sie den oben beschriebenen iterativen Ansatz von James, da Sie die Behandlung aller (vielen) Ausnahmen an 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;
}
Hier gehen Sie einen anderen Ansatz mit weniger Schleifen:
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;
}
Sie können diese Lösung auch in Betracht ziehen. Dies function
gibt die monatliche Differenz in Ganzzahl oder Zahl zurück
Das Übergeben des Startdatums als erstes oder letztes param
ist fehlertolerant. Das heißt, die Funktion würde immer noch den gleichen Wert zurückgeben.
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);
Berechnen Sie die Differenz zwischen zwei Daten 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)
Datum2 : 09/11/2015 (9. November 2015)
die Differenz: 2,5 (Monate)
Dies sollte gut funktionieren:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months += d2.getMonth() - d1.getMonth();
return months;
}
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);
}
Der folgende Code gibt volle Monate zwischen zwei Daten 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
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;
}}
Die folgende Logik wird die Differenz in Monaten ermitteln
(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;
}
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;
}
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
In diesem Fall geht es mir nicht um volle Monate, Teilmonate, wie lange ein Monat ist usw. Ich muss nur die Anzahl der Monate kennen. Ein relevanter Fall in der realen Welt wäre, wenn jeden Monat ein Bericht fällig wird und ich wissen muss, wie viele Berichte es geben sollte.
Beispiel:
Dies ist ein ausgearbeitetes Codebeispiel, um zu zeigen, wohin die Zahlen gehen.
Nehmen wir 2 Zeitstempel, die 4 Monate ergeben sollten
Kann mit Ihrer Zeitzone / Zeit etwas anders sein. Der Tag, die Minuten und die Sekunden spielen keine Rolle und können in den Zeitstempel aufgenommen werden, aber wir werden ihn bei unserer tatsächlichen Berechnung nicht berücksichtigen.
let dateRangeStartConverted = new Date(1573621200000);
let dateRangeEndConverted = new Date(1582261140000);
let startingMonth = dateRangeStartConverted.getMonth();
let startingYear = dateRangeStartConverted.getFullYear();
let endingMonth = dateRangeEndConverted.getMonth();
let endingYear = dateRangeEndConverted.getFullYear();
Das gibt uns
(12 * (endYear - startYear)) + 1
Zum Endmonat hinzufügen.2 + (12 * (2020 - 2019)) + 1 = 15
15 - 11 = 4
;; Wir bekommen unser 4-Monats-Ergebnis.
November 2019 bis März 2022 sind 29 Monate. Wenn Sie diese in eine Excel-Tabelle einfügen, werden 29 Zeilen angezeigt.
3 + (12 * (2022-2019)) + 1
40 - 11 = 29
anyVar = (((DisplayTo.getFullYear() * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear() * 12) + DisplayFrom.getMonth()));
Ein Ansatz wäre, einen einfachen Java-Webdienst (REST / JSON) zu schreiben, der die JODA-Bibliothek verwendet
http://joda-time.sourceforge.net/faq.html#datediff
um die Differenz zwischen zwei Daten zu berechnen und diesen Dienst über Javascript aufzurufen.
Dies setzt voraus, dass sich Ihr Backend in Java befindet.