Bei JavaScript-Dates ging es eigentlich nie wirklich um Datumsangaben

Sieh diesen Blogpost einfach als kurzes Update dazu, was Temporal eigentlich ist, warum wir es brauchen und warum du vielleicht schon heute darüber nachdenken solltest, es zu nutzen – auch wenn es (zum Zeitpunkt des Schreibens) noch nicht in allen großen Browsern verfügbar ist. Wenn du dich schon mal an Zeitzonen verbrannt hast und die Erfahrung eher uncool fandest, ist das hier vielleicht genau das Richtige für dich.

Datumsangaben sind fieser, als sie aussehen

Das JavaScript-Date war schon immer nur ein schicker Unix-Timestamp mit ein paar angeflanschten Tools, um irgendwelche menschenlesbaren Daten daraus zu quetschen.

Als Entwickler neigen wir dazu, Datumsangaben als etwas zu betrachten, das sich easy durch Zahlen darstellen lässt. In der Realität ist das Ganze allerdings deutlich komplexer.

Datum und Uhrzeit gehören zu den Problemen, die trivial wirken, bis man sich in einer echten Anwendung damit herumschlagen muss. Die meisten von uns denken bei Zeit an "einfach einen Timestamp", aber User tun das selten.

User interessieren sich eher für Konzepte wie:

  • Morgen um 9 Uhr

  • Der letzte Tag des Monats

  • Jeden Montag

  • Die gleiche Uhrzeit in einer anderen Zeitzone

  • Ein Geburtstag, völlig unabhängig von der Zeitzone

Diese Konzepte unterscheiden sich grundlegend von einem einzelnen Zeitpunkt, der in Millisekunden seit dem 1. Januar 1970 gemessen wird.

Tatsächlich ist das Handling von Zeitangaben historisch gesehen für eine beeindruckende Anzahl von Software-Bugs verantwortlich. Es gibt auf Wikipedia sogar eine eigene Liste prominenter Fehler im Zusammenhang mit Zeitformatierung und -speicherung.

Leider hat auch JavaScripts eigene Date-API so einige Macken abbekommen. Viele dieser Probleme sind ziemlich verwirrend und werden – dank JavaScripts eiserner Disziplin bei der Abwärtskompatibilität – wohl auch nie behoben werden.

Falls du dir die Skurrilitäten von Date noch nie angeschaut hast, wirf ruhig mal einen Blick auf jsdate.wtf

Das ist gleichermaßen lehrreich wie dezent verstörend.

Was läuft bei Date eigentlich schief?

Das größte Problem mit Date ist, dass es versucht, mehrere völlig unterschiedliche Konzepte auf einmal abzubilden:

  • Einen Timestamp

  • Ein Kalenderdatum

  • Eine lokale Datums-/Uhrzeitangabe

  • Eine UTC-Datums-/Uhrzeitangabe

Das führt dazu, dass dasselbe Objekt Methoden wie diese hier bereitstellt:

date.getMonth(); date.getUTCMonth(); date.toLocaleString(); date.toISOString();

Lokale und UTC-Operationen versehentlich zu vermischen, ist eine der häufigsten Ursachen für datumsbezogene Bugs.

Ein gutes Beispiel dafür ist das hier:

new Date("2025-01-01");

Auf den ersten Blick sieht das nach "1. Januar 2025" aus.

In Wirklichkeit hast du damit aber einen ganz bestimmten Zeitpunkt erzeugt. Je nach Zeitzone des Users wird beim Anzeigen dieses Wertes unter Umständen sogar der 31. Dezember 2024 ausgegeben.

Dieses Verhalten ist technisch gesehen zwar korrekt, aber selten das, was wir Entwickler erwarten.

Das Problem ist nicht unbedingt, dass Date komplett kaputt ist. Das Problem ist, dass ein einziges Objekt versucht, zu viele verschiedene Probleme gleichzeitig zu lösen.

Wir haben schon früher versucht, das zu reparieren

Im Laufe der Jahre gab es jede Menge Versuche, die Situation durch Community-gepflegte Libraries zu verbessern.

Das bekannteste Beispiel war wahrscheinlich Moment.js. Als ich mit dem Programmieren anfing, dachte ich quasi, Moment sei der absolute Goldstandard für das Handling von Datumsangaben.

Natürlich brachten all diese Libraries ihre eigenen Trade-offs mit, aber sie waren dem nativen Date-API in der Regel haushoch überlegen.

Andere Libraries wie Luxon und date-fns haben das Ökosystem weiter vorangebracht und der Community kollektiv gezeigt, wie eine gute Date-API eigentlich aussehen sollte.

Glücklicherweise haben diese Erkenntnisse irgendwann ihren Weg direkt in die Sprache selbst gefunden.

Vorhang auf für Temporal

Temporal ist eine neue standardisierte Date- und Time-API für JavaScript und ein würdiger Nachfolger für Date.

Besonders spannend daran: Temporal bringt nicht primär neue Features mit. Stattdessen behebt es einen Designfehler, der seit den Anfängen von JavaScript existiert.

Anstatt zu versuchen, jedes Konzept mit einem einzigen Objekt abzufedern, teilt Temporal die Verantwortlichkeiten in dedizierte Typen auf.

Ein paar Beispiele:

Temporal.Instant

Repräsentiert einen präzisen Zeitpunkt.

Temporal.Instant.from("2025-01-01T12:00:00Z");

Das ist das, wofür viele Entwickler aktuell noch Date nutzen.

Temporal.PlainDate

Repräsentiert ein Kalenderdatum ohne Uhrzeit- oder Zeitzoneninformationen.

Temporal.PlainDate.from("2025-01-01");

Perfekt für Geburtstage, Feiertage, Fristen und ähnliche Konzepte.

Temporal.PlainTime

Repräsentiert eine Uhrzeit ohne Datum.

Temporal.PlainTime.from("09:30");

Nützlich für wiederkehrende Zeitpläne oder Öffnungszeiten.

Temporal.ZonedDateTime

Repräsentiert ein Datum und eine Uhrzeit, die an eine bestimmte Zeitzone gebunden sind.

Temporal.ZonedDateTime.from( "2025-01-01T09:30:00[Europe/Berlin]" );

Das macht zeitzonenabhängige Berechnungen deutlich sicherer und verständlicher.

Mehr als nur bessere Typen

Temporal bringt außerdem einige Quality-of-Life-Verbesserungen mit.

Zum Beispiel sind Temporal-Objekte immutable (unveränderlich).

Bei Date mutieren Operationen oft das ursprüngliche Objekt:

const date = new Date(); date.setMonth(12);

Bei Temporal geben Operationen stattdessen einen neuen Wert zurück:

const nextMonth = date.add({ months: 1 });

Das passt viel besser zu modernen JavaScript-APIs und eliminert eine komplette Kategorie von versehentlichen Mutationen.

Auch die Datumsarithmetik ist um einiges angenehmer.

const tomorrow = date.add({ days: 1 }); const nextYear = date.add({ years: 1 });

Vergleiche das mal mit der traditionellen Date-Arithmetik inklusive Timestamp-Berechnungen und Edge-Cases rund um die Zeitumstellung (Sommer-/Winterzeit).

Temporal führt außerdem echten Kalender-Support ein, während Date nur den gregorianischen Kalender unterstützt.

Wenn du die API genauer unter die Lupe nehmen willst, bietet die MDN-Dokumentation einen hervorragenden Überblick:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal

Kann ich Temporal heute schon nutzen?

(Dafür gibt es übrigens caniuse)

Temporal ist aktuell noch nicht "Baseline", hauptsächlich weil Safari noch hinterherhinkt.

Abgesehen davon ist der Browser-Support bereits überraschend gut.

Zum Zeitpunkt des Schreibens unterstützen rund 67 % der von Endusern genutzten Browser Temporal bereits:

In der Praxis warten wir eigentlich nur noch auf den Safari-Support, bevor man Temporal bedenkenlos für so gut wie jedes Projekt empfehlen kann.

Wenn du schon heute damit loslegen willst, gibt es einen Polyfill:

https://www.npmjs.com/package/temporal-polyfill

Für Greenfield-Projekte ist der Einsatz von Temporal via Polyfill schon jetzt eine absolut valide Option. Bei bestehenden Anwendungen ist eine schrittweise Einführung wohl der realistischste Weg.

Meine persönliche Meinung zu Temporal

Ich bin durch einen Kollegen auf Temporal aufmerksam geworden, nachdem ich mich mit ein paar Zeitzonen-Problemen herumgeschlagen und vorgeschlagen hatte, Moment.js zu einem bestehenden Projekt hinzuzufügen.

Und ja, das ist mir 2025 passiert. Schön blöd von mir.

Seitdem weiß ich zu schätzen, was Temporal auf den Tisch bringt.

Mir war gar nicht so recht bewusst, wie verdammt schwierig das Handling von Datum und Uhrzeit sein kann, bis ich in Production auf ein paar echt fiese Zeitzonen-Bugs gestoßen bin. Die größte Errungenschaft von Temporal ist vielleicht schlicht und ergreifend, dass es einem viel schwerer gemacht wird, solche Bugs überhaupt erst zu bauen.

Für mich fühlt sich Temporal an wie die Quintessenz aus jahrelangen Learnings von Moment.js, Luxon, date-fns und dem gesamten JavaScript-Ökosystem. All diese Lektionen direkt in der Sprache selbst zu standardisieren, ist eine ziemlich beeindruckende Leistung.

Ich glaube nicht, dass Date so schnell verschwinden wird (Abwärtskompatibilität verpflichtet schließlich), aber für neue Anwendungen kann ich mir absolut vorstellen, dass Temporal zum Standard wird, sobald der Browser-Support nachzieht.