Differenz zwischen zwei Datumsangaben
- zeit & datum
Hallo zusammen,
ich habe ein Problem, die genaue Differenz zwischen zwei Daten in Jahr, Monat und Tag in javascript genau auszugeben. Der script
<script>
const tEarlier = new Date("2026-02-01");
const tLater = new Date("2026-05-01");
const tMillisecondsElapsed = tLater - tEarlier;
const tELapsed = new Date(tMillisecondsElapsed);
const year = tELapsed.getFullYear();
const elapsedYear = year - 1970;
tELapsed.setFullYear(elapsedYear);
let strDate = tELapsed.toISOString().slice(0, 10); //ISO date is yyyy-mm-dd
strDate = strDate.split("-");
strDate = `${strDate[1]}-${strDate[2]}-${strDate[0]}`;
alert(strDate);
</script>
gibt als Ergebnis 3 Monate und 31 Tage an. Der PHP script
<?php
$datum1 = new DateTime("2026-05-01");
$datum2 = new DateTime("2026-02-01");
$differenz = $datum1->diff($datum2);
echo $differenz->format('%y Jahre, %m Monate, %d Tage');
?>
zeigt hingegen als Ergebnis genau drei Monate an. Und das ist richtig. Wie kann ich javascript dazu bringen, Monate wie z.B. den Februar korrekt zu berechnen?
Vielen Dank im voraus für Eure Hilfe
@@Joergi
const tEarlier = new Date("2026-02-01"); const tLater = new Date("2026-05-01"); const tMillisecondsElapsed = tLater - tEarlier; const tELapsed = new Date(tMillisecondsElapsed);
Das ist Murks. tMillisecondsElapsed gibt keinen Zeitpunkt an, sondern eine Zeitdauer. Es ist unsinnig, eine Zeitdauer als Argument für den Date-Konstruktor zu verwenden.
zeigt hingegen als Ergebnis genau drei Monate an.
„Genau“ und „Monate“ widerspricht sich. Da Monate unterschiedlich lang sind, ist eine Angabe „x Monate“ niemals genau.
Und das ist richtig. Wie kann ich javascript dazu bringen, Monate wie z.B. den Februar korrekt zu berechnen?
Mit einer Bibliothek, die die Berechnung von Zeitdauern und deren Ausgabe in verschiedenen Formaten implementiert hat.
🖖 Live long and prosper
Moin Gunnar,
Und das ist richtig. Wie kann ich javascript dazu bringen, Monate wie z.B. den Februar korrekt zu berechnen?
Mit einer Bibliothek, die die Berechnung von Zeitdauern und deren Ausgabe in verschiedenen Formaten implementiert hat.
Für JavaScript sind das etwa Moment.js, date-fns, Luxon oder day.js.
Mein persönlicher Favorit dabei ist date-fns, weil ich hier nur den Teil einbinden kann, der tatsächlich relevant ist für mein Problem.
Gruß,
Danke für Eure Ratschläge. Ich habe es mal mit day.js probiert und folgende Routine erstellt:
<script type="text/javascript" src="dayjs.min.js"></script>
<script>
const date1 = dayjs('2026-05-03')
a=date1.diff('2026-02-01', 'month')
b=date1.diff('2026-02-01', 'day')
alert (a+" Monate / "+b+" Tage");
</script>
Der script zeigt mir die Differenz in ganzen Monaten oder Tagen an (3 Monate / 91 Tage). Wie bekomme ich es hin, dass er mir neben den Monaten nur die Resttage anzeigt. z.B. hier: 3 Monate / 2 Tage?
Hallo,
Wie bekomme ich es hin, dass er mir neben den Monaten nur die Resttage anzeigt. z.B. hier: 3 Monate / 2 Tage?
Du kannst dir die Dauer als String oder als Objekt geben lassen und da dann das gewünschte rauspfriemln: z. B. toString
Gruß
Kalk
Jau,
danke für den Tip. Werde es direkt ausprobieren 😀
Weil es wieder einmal paßt, ein aktuelles (13.02.26) Beispiel:
Rechne ich zum heutigen Datum 2 Tage, 2 Wochen und 2 Jahre drauf, dann ergibt das den 01.03.28. Zieh ich davon nun 2 Tage, 2 Wochen und 2 Jahre ab, dann lande erst wieder morgen …
Hallo Numbers sagt: Datum-Datum = Dauer!,
Weil es wieder einmal paßt, ein aktuelles (13.02.26) Beispiel:
Rechne ich zum heutigen Datum 2 Tage, 2 Wochen und 2 Jahre drauf, dann ergibt das den 01.03.28. Zieh ich davon nun 2 Tage, 2 Wochen und 2 Jahre ab, dann lande erst wieder morgen …
wie rechnest du?
Und mach dir bitte den Unterschied zwischen Betreff und Autor klar.
Gruß
Jürgen
Rechne ich zum heutigen Datum 2 Tage, 2 Wochen und 2 Jahre drauf, dann ergibt das den 01.03.28. Zieh ich davon nun 2 Tage, 2 Wochen und 2 Jahre ab, dann lande erst wieder morgen …
wie rechnest du?
Wie (hin-)geschrieben. Einfach einen (elektronischen) Kalender benutzen, vom erwähnten Tag zunächst zwei Tage, dann davon zwei Wochen und dann wiederum zwei Jahre „vorwärts“ gehen. Danach von dort in genau der beschriebenen Reihenfolgen wieder „zurück“.
Oder: es kommt sehr darauf an, in welcher Reihenfolge die einzelnen Additionen bzw. Subtraktionen vorgenommen werden.
Hallo Datumsakrobat,
ein Undo soll immer in umgekehrter Reihenfolge stattfinden. Andernfalls kann man Überraschungen erleben, so wie hier.
Nimm Dir das mal schrittweise vor.
13.02.2026
+ 2 Tage: 15.02.2026
+ 2 Wochen: 01.03.2026
+ 2 Jahre: 01.03.2028
Rückgängig machen in falscher Reihenfolge:
01.03.2028
- 2 Tage: 28.02.2028 (Schaltjahr!)
- 2 Wochen: 14.02.2028
- 2 Jahre: 14.02.2026
Rückgängig machen in korrekter Reihenfolge:
01.03.2028
- 2 Jahre: 01.03.2026
- 2 Wochen: 15.02.2026 (2026 ist kein Schaltjahr)
- 2 Tage: 13.02.2026
Rolf
Nur weil’s der Augefälligkeit dient, scheint es sich um ein Undo zu handeln. Tatsächlich ergeben sich Ketten von Berechnungen irgendwo und keineswegs immer an der gleichen Stelle.
Folge: eine so (und dann unbewußt) vorgenommene Fortschreibung scheinbar ganz normaler und einfacher arithmetischer Operationen führt immer wieder mal zu überraschenden Ergebnissen. Überraschend? Nur wenn man’s bemerkt!
Hallo,
ganz normaler und einfacher arithmetischer Operationen
Das ist das Problem. Datumsberechnungen sind weder normale noch einfache Arithmetik. Die additiven Operationen mit Zeitabständen sind nicht kommutativ.
Wegen der Kalenderbesonderheiten ist weder „Monat“ noch „Jahr“ ein konstanter Wert, sondern abhängig von dem Datum, mit dem sie verknüpft werden. Und das muss eben bei jeder Berechnung beachtet werden.
2. März minus 3 Tage ist 27. oder 28. Februar, je nach Jahr.
30. Januar plus 1 Monat ist grundsätzlich ein Problem, weil es den 30.2. nicht gibt.
Es gibt schon gute Gründe, weshalb Banken mit 30 Tagen/Monat und 360 Tagen/Jahr rechnen...
Rolf
Hi,
Wegen der Kalenderbesonderheiten ist weder „Monat“ noch „Jahr“ ein konstanter Wert,
und "Tag" auch nicht (Umstellung Sommer-/Normalzeit, Schaltsekunden)
cu,
Andreas a/k/a MudGuard
@@MudGuard
und "Tag" auch nicht (Umstellung Sommer-/Normalzeit, Schaltsekunden)
Wobei es Schaltsekunden in der Unixzeit nicht gibt.
🖖 Live long and prosper
Und oben drauf kommt dann JS: Monat oder doch Monat-1? Und wenn man ein Datum „zusammenbastelt“ (Date(y,m,d)) erhält man, wenn man das Ergebnis nach ISO transportieren läßt, nicht selten einen anderen Tag. (Vermutung: die eigene, lokale, Zeitzone und vielleicht auch die gerade aktuelle Zeit wird stelllenweise untergeschoben – aber nur stellenweise).
Ganz lustig ist dabei die „eingebaute KI“: aa-bb-cc wird als mm-tt-jj interpretiert, es sei denn, mm > 12 …
Randbemerkung: das mit der Uhrzeit machte, beispielsweise, Numbers: gab man in einen Zelle eine Zeichenfolge ein, die als Datum erkannt wird, dann stand, vom Format verborgen, die Zeit mit drin. — Vergangenheitsform, denn zumindest „mal eben“ konnte ich das vorhin nicht mehr nachvollziehen, das letzte Mal war’s vor vlt. zwei oder drei Updates. Aber: so etwas kann man bestimmt auch ganz schnell „selber programmieren“ …
Hallo,
Von (new Date(2026,2,20)).toISOString() bekommst Du in Deutschland immer 23 oder 22 Uhr des Vortages, weil wir GMT+1 oder +2 sind.
Ja, JavaScript ist hier fehlkonstruiert. Weshalb Temporal gebaut wurde.
Die einfachste Methode für eine YYYY-MM-DD Darstellung ist aber, toLocaleDateString zu verwenden und ein Locale anzugeben, das diese Darstellung verwendet. Beispiel: Kanada.
(new Date(2026,2,20)).toLocaleDateString('en-CA')
Edit: Locate war ein Typo, Locale ist richtig
Ob es einen Locale-Modifikator gibt, der für 'de-DE' eine YYYY-MM-DD Darstellung anfordert, müsste ich nachschauen, habe dafür aber gerade keine Zeit.
Rolf
@@Rolf B
Von
(new Date(2026,2,20)).toISOString()bekommst Du in Deutschland immer 23 oder 22 Uhr des Vortages, weil wir GMT+1 oder +2 sind.Ja, JavaScript ist hier fehlkonstruiert.
So gut wie alle Programmiersprachen sind hier fehlkonstruiert, weil man mit 2026,2,20 nicht den 20. Februar, sondern den 20. März bekommt. Dass man Array-Indizes bei 0 anstatt bei 1 anfängt zu zählen, ist schon schlimm genug; bei Monaten ist es eine Katastrophe.
Aber das mit der Uhrzeit lässt sich in Griff bekommen. Nicht lokale Zeit rein, UTC raus; sondern UTC rein, UTC raus:
(new Date(Date.UTC(2026,2,20))).toISOString() // "2026-03-20T00:00:00.000Z"
Oder ein vernüftiges API verwenden:
Weshalb Temporal gebaut wurde.
🖖 Live long and prosper
Nun, daß man bei den Indexen mit 0 zu zählen beginnt, mag zwar diskutabel sein, ist aber hinnehmbar (und allemal „historisch“ begründet: so manche C-Schleife wurden z.B. bei den 68K zu zwei oder drei Zeilen Mnemonic). Daß man aber einerseits strings als key verwendet, undefined aus unerklärten Gründen ausläßt und dann die Ordnungszahl stillschweigend „verstringt“ …
Jedenfalls habe ich da noch nirgends gelesen, daß Monate ein Array wären. (Dafür aber an sehr vielen stellen, daß alles mögliche und unmögliche keines, bestenfalls array-like, wäre.)
Typisch JS? Ist das da wirklich allein? „WIR“ sind viel schauer als die Anwender. Und auch so ein Programmierier ist nur ein Anwender! Jedenfalls habe ich dieses automatische Konvertieren (ohne explizite Erlaubnis; das Abfangen möglicher Probleme bedeutet allemal mehr Aufwand als z.B. ein 'auto(…)') schon immer und überall zu hassen gelernt. Zunächst vor allem in Tabellenkalkulationen. Aber nicht nur da ist’s eine „interessante“ Frage, ob "a + b" nun ein mathematisches c (resp. hier: §a + b§ ergibt, oder doch ein einfaches "ab" …
Das mit dem „'&' oder '+' ist doch egal“ wäre die angrenzende Baustelle.
BTW: §? Notfall-Ersetzung. Diesmal sollte da der '\u0060' in persona erscheinen …
Kleiner Nachtrag, sozusagen der „Meinungsäußerung von Numbers“ geschuldet:
Die additiven Operationen mit Zeitabständen sind nicht kommutativ.
Doch, das sind sie. Aber: spätestens Monate und natürlich erst recht Jahre sind dabei keine Zahlen in mathematischem Sinn. (Gut, vielleicht welche aus der Menge der, bislang weitgehend unerforschten, Datumszahlen 𝔻? Mit ganz eigener Artithmetik? 🤓)
Um da auf Numbers zurück zu schielen: (etwas JS-lax formuliert) das kennt den Datentyp Dauer und bietet einen Konstruktor an. =Dauer(…) kann mit Wochen, Tagen, Stunden, Minuten, Sekunden und Millisekunden … bestückt werden (z.B. =Dauer(;;1) ergäbe eine Stunde, Datum+Datum füttert =wennfehler() während Datum-Datum ein Dauer ergibt usw.).
Und: dieses Problem, bei dem ich doch (absichtlich) so falsch gerechnet habe, das tritt ja schon „früher“ auf: + 2 Monate + 1 Tag - 1 Monat - 2 Tage - 1 Monat + 1 Tag … \
Nein, das mit dem Muliplinieren fang’ ich garnienich erst an!“ (Hört sich IMO ein wenig nach Bud Spencern an)
Ich habe mal ein paar Babysteps mit Temporal gemacht.
heute1 = Temporal.ZonedDateTime.from("2026-02-24T12:25:00+01:00[CET])"; // sic!
dauer = Temporal.Duration.from({ years: 2, days: 8 });
morgen = heute.add(dauer);
heute2 = morgen.subtract(dauer);
console.log(heute1.equals(heute2));
console.log(heute2.toLocaleString());
Das Ergebnis:
false
'23.2.2026 12:29:00 MEZ'
Mit anderen Worten: das Temporal API rechnet, genau wie Mr. Rant Numbers, ohne nachzudenken. Es addiert Jahre, Monate, Tage, etc, in dieser Reihenfolge, und subtrahiert ebenfalls in dieser Reihenfolge. Weil aber "24. Februar +8 Tage" in 2026 und 2028 unterschiedliche Ergebnisse haben, landet man am Ende bei einem Tag Differenz.
Immerhin kommt in PHP das Gleiche heraus, es scheint wohl eine Norm zu geben, wie man hier vorzugehen hat.
Grundsätzlich würde ich aber von <code>x.add(y).subtract(y)</code> erwarten, dass x herauskommt.
Weiß jemand, wie andere Libs mit diesem Problem umgehen?
Rolf
Ich kann mir nicht vorstellen, daß eine Maschine oder irgend jemand „einfach so“ diese Problematik auflösen könnte. Das Ergebnis ist ja abhängig von der Intention der Problemstellung und nicht von einfachen Operationen.
Dazu kommt ja auch, daß das Beispiel eben ein Beispiel und nicht mehr war: rechnet man beim Hin und Zurück mit unterschiedlichen Zahlen, so landet beim Überschreiten von Schaltjahrs-Grenzen man ebenfalls immer wieder daneben. Dann halt nur gelegentlich um einen Tag „nebenan“. Dann reiben sich die Leute eben die Augen, weil plötzlich aus einem, sagen wir mal, „Mittwoch“ ein „Sonntag“ wird.
Ähnliches gilt ja auch, wiederum ein Beispiel, bei Temperaturen: 20℃ + 10℃ = … hmmm, 20℃ entsprechen 293,15K, 10℃ 283,15K. Frisch addiert wären das 576,3K oder 303,15℃ … — Und dabei gibt es bei Tempearturen, jedenfalls „hierzulande“, nur einen Knackpunt, nicht wie bei Datumsangaben fast alle 4 Jahre einen.
Nein, an eine Software-Lösung kann ich da nicht glauben. Gefragt ist „NI“. Natürliche Intelligenz (als Antipode Künstlicher Idiotie).
20℃ + 10℃ = … hmmm, 20℃ entsprechen 293,15K, 10℃ 283,15K. Frisch addiert wären das 576,3K oder 303,15℃ …
Ebenso haarsträubende Schlüsse werden in den Kommentaren zu dieser Rätselaufgabe gezogen:
Sozusagen als Zusammenfassung:
Da haben wir also unser sprachliches oder, das mathematisch meist (aber nicht immer) einem exklusiv-oder entspricht. Und dann haben wir Zahlen (hier: Zeitdauer), für die gilt:
Tage + Monate + Jahre =͔͐ Jahre + Monate + Tage
mit =͔͐ als „kann sein, muß vielleicht“ o.ä.
Will sagen: sprachliche Additionen und Subtraktionen sind nicht kommutativ! Wer sie dennoch „mathematisch“ ausrechnet, muß also mit … der neuen Zahlenmenge der Vielleicht-Zahlen? … rechnen!
Vielleicht-Zahl?
Die Menge =͔͐, für die aunahmslos gilt, daß zwei beliebige Elemente a und b daraus gilt: a - b ∈ … 𝕀! (oder wie sonst ist diese Rationalität zu benennen?)
ich habe ein Problem, die genaue Differenz zwischen zwei Daten in Jahr, Monat und Tag in javascript genau auszugeben.
Das geht mit der neuen Temporal-API inzwischen sehr einfach:
const jetzt = Temporal.Now.plainDateISO();
const damals = Temporal.PlainDate.from({
year: 2007,
month: 8,
day: 13,
});
const interval = jetzt.since(damals, {
largestUnit: "year",
smallestUnit: "day",
});
console.log(interval.toLocaleString("de", { style: "long", roundingMode: "trunc" }));
@@Gagamehl
ich habe ein Problem, die genaue Differenz zwischen zwei Daten in Jahr, Monat und Tag in javascript genau auszugeben.
Das geht mit der neuen Temporal-API inzwischen sehr einfach:
Sehr nett.
Wobei „inzwischen“ Safari noch ausklammert, also auch alle iPhones und iPads.
Und laut Can I Use auch Opera? Ist das nicht ein Chromium? Ist das in Chromium vorhandene Feature in Opera noch nicht aktiviert?
const damals = Temporal.PlainDate.from({ year: 2007, month: 8, day: 13, });
Und endlich mal ein Stück Software, das mit Datumsangaben richtig umgehen kann. Die 8 steht hier für August, nicht für September.
🖖 Live long and prosper
Hi there,
const damals = Temporal.PlainDate.from({ year: 2007, month: 8, day: 13, });
Ist an diesem Tag ein Fahrrad von Bruce Springsteen umgefallen...?
(scnr)
@@klawischnigg
const damals = Temporal.PlainDate.from({ year: 2007, month: 8, day: 13, });Ist an diesem Tag das Fahrrad von Bruce Springsteen umgefallen...?
Ich weiß nicht, ob es da sowas zum Umfallen gibt. Autos kommen in seinen Lieder öfter vor – Racing in the Street (best version?), Cadillac Ranch, Pink Cadillac (ja, das, was Natalie Cole gecovert hat), Used Cars (hab ich mal auf deutsch gemacht), … – aber Fahrräder?
Auf meiner Spielwiese gibt’s ein anderes Bezugsdatum.
🖖 Live long and prosper
Hi there,
Ist an diesem Tag das Fahrrad von Bruce Springsteen umgefallen...?
Ich weiß nicht, ob es da sowas zum Umfallen gibt. Autos kommen in seinen Lieder öfter vor
Naja, vielleicht hat er an dem Tag einen Platten gehabt...(weil er möglicherweise über ein Fahrrad drübergefahren ist)?
Auf meiner Spielwiese gibt’s ein anderes Bezugsdatum.
Sehr gut. Ein neuer sinnloser Eintrag in meinem intern geführten Lexikon des nutzlosen Wissens - besten Dank...
@@klawischnigg
Ist an diesem Tag das Fahrrad von Bruce Springsteen umgefallen...?
Ich weiß nicht, ob es da sowas zum Umfallen gibt. Autos kommen in seinen Lieder öfter vor
Naja, vielleicht hat er an dem Tag einen Platten gehabt...
Springsteen hat schon viele Platten gemacht.
🖖 Live long and prosper