Date verschwindet, Temporal kommt
(piccalil.li)- Die bestehende Unvollständigkeit und Inkonsistenz des
Date-Objekts in JavaScript wird aufgezeigt, und als Ersatz wird die Temporal API vorgestellt Datearbeitet als veränderbares Objekt (mutable object) und weicht damit vom eigentlichen Datumsbegriff ab; zudem gibt es Parsing-Fehler und Grenzen bei der Zeitzonenverarbeitung als strukturelle Probleme- Temporal bietet ein neues Modell zur Datums- und Zeitverarbeitung auf Basis von Unveränderlichkeit und umfasst fein aufgeteilte Klassen wie
PlainDate,ZonedDateTimeundDuration - Die Methoden von Temporal verändern bestehende Objekte nicht, sondern geben neue Objekte zurück, wodurch klare und sichere Chaining-Operationen möglich werden
- Temporal befindet sich derzeit in Standardisierungsstufe 3 (Stage 3) und wird in modernen Browsern wie Chrome und Firefox experimentell unterstützt
Probleme mit dem Date-Objekt in JavaScript
- Der
Date-Konstruktor sorgt mit uneinheitlichen Parsing-Regeln und nicht intuitiver Indizierung für Verwirrung- Beispiel: Der Monat beginnt bei 0, während Tag und Jahr bei 1 beginnen
- Die Zeichenkette
"99"wird als Jahr 1999 interpretiert,"100"dagegen als Jahr 0100 — es fehlt also an Konsistenz
Dateist auf Zeit (time) zentriert und speichert intern einen Unix-Timestamp (in Millisekunden)- Die Unterstützung für Zeitzonen (time zones) ist eingeschränkt; Sommerzeit (DST) oder nicht-gregorianische Kalender werden nicht erkannt
- Aufgrund dieser Grenzen ist die Abhängigkeit von großen Drittanbieter-Bibliotheken wie Moment.js oder date-fns verbreitet, was zu Leistungseinbußen führt
Konflikt zwischen Unveränderlichkeit und Referenzkonzept
- Primitive Werte in JavaScript sind unveränderlich und werden als Werte selbst gespeichert, während Objekte (objects) als Referenzen gespeichert und veränderbar sind
Dateist ein über einen Konstruktor (constructor) erzeugtes Objekt und daher veränderbar- Beispiel: Bei Aufrufen von
setMonth()odersetDate()wird das Originalobjekt direkt verändert
- Beispiel: Bei Aufrufen von
- Dadurch kommt es zwischen Variablen, die auf dasselbe Objekt verweisen, zu unerwarteten Wertänderungen
- Beispiel: Wenn eine Funktion
todayals Argument erhält und intern das Datum verändert, wird auch das ursprünglichetodayverändert
- Beispiel: Wenn eine Funktion
Temporal: eine neue Datums- und Zeit-API
Temporalist kein Konstruktor, sondern ein Namespace-Objekt (namespace object) mit einerMathähnlichen Struktur- Wichtige Bestandteile:
PlainDate,PlainDateTime,PlainTime,ZonedDateTime,Duration,Nowusw.
- Wichtige Bestandteile:
Temporal.Nowliefert den aktuellen Zeitpunkt in verschiedenen Formen zurückplainDateISO()→ Datum im ISO-FormatzonedDateTimeISO()→ Zeitpunkt inklusive Zeitzone
- Temporal-Objekte bieten ein klar definiertes Methodensystem
- Mit
add({ days: 1 }),subtract({ years: 2 })usw. lassen sich Operationen mit expliziten Einheiten ausführen - Bestehende Objekte werden nicht verändert, stattdessen wird ein neues Objekt zurückgegeben, wodurch die Unveränderlichkeit erhalten bleibt
- Mit
Funktionsweise und Vorteile von Temporal
- Temporal-Objekte sind weiterhin Objekte, folgen aber einem beabsichtigt unveränderlichen Nutzungsmuster
- Beispiel:
today.add({ days: 1 })gibt ein neues Datumsobjekt zurück, während das ursprünglichetodayunverändert bleibt
- Beispiel:
- Gegenüber
Datebietet Temporal eine knappere und klarere Syntax- Beispiel:
const today = Temporal.Now.plainDateISO(); console.log(`Tomorrow will be ${ today.add({ days: 1 }) }. Today is ${ today }.`); // 결과: Tomorrow will be 2026-01-01. Today is 2025-12-31.
- Beispiel:
- Anforderungen wie Angabe von Zeitzonen, Berechnung von Zeitspannen und Beibehaltung des ISO-Formats werden modern umgesetzt
- Mit Method Chaining über
add,subtract,since,untilusw. lassen sich komplexe Datumsberechnungen kompakt ausdrücken
Stand der Standardisierung und Ausblick
Temporalhat Stufe 3 (Stage 3) des ECMAScript-Vorschlagsprozesses erreicht, ein Zustand, in dem Browser-Implementierungen empfohlen werden- In Chrome und Firefox hat die experimentelle Unterstützung bereits begonnen; andere Browser sollen folgen
- Entwickler können sich schon jetzt durch Tests und Feedback an der Verbesserung der Spezifikation beteiligen
Datewird zwar weiterhin existieren, doch künftig dürfte sich Temporal als Standard für die Datumsverarbeitung etablieren- Der Artikel schließt mit dem Hinweis, man hätte es „1995 ersetzen sollen, aber selbst jetzt ist Temporal.Now der richtige Zeitpunkt“
1 Kommentare
Hacker-News-Kommentare
Dieser Artikel behandelt mehrere absurde Verhaltensweisen des JavaScript-Date-Konstruktors
Insbesondere wird erklärt, dass das Format
'YYYY-MM-DD'als UTC-Mitternacht interpretiert wird, wodurch sich das Datum in lokalen Zeitzonen um einen Tag verschieben kannNach ISO 8601 sollte eine Angabe ohne Zeitzone ursprünglich als lokale Zeit gelten, aber bei der Ausarbeitung der ES5-Spezifikation wurde sie irrtümlich als „Z“ (UTC) behandelt
Später wollte man das in ES2015 korrigieren, nahm die Änderung jedoch aus Gründen der Web-Kompatibilität wieder zurück, weil unzählige Websites vom bisherigen falschen Verhalten abhingen
Details dazu finden sich im Abschnitt Broken Parser
'use strict'eine Direktive'strict datetime'gegeben hätteDamit hätte man korrektes Verhalten selektiv aktivieren können, ohne Inkompatibilitäten mit bestehendem Code zu verursachen
Alternativ wäre auch ein Ansatz denkbar gewesen, bei dem man über ein internes Modul wie
import Date from 'browser:date'ein korrigiertes globales Objekt lädtBei Werten wie Geburtstagen, die einfach nur ein Datum bedeuten, ist es unsinnig, dass sie sich wegen der Zeitzone ändern
Ich erinnere mich, dass Outlook Geburtstage früher mit Zeitzone gespeichert hat, sodass sie sich beim Umzug in ein anderes Land jedes Mal um einen Tag verschoben haben
Aber hätte es überhaupt eine Alternative gegeben? Wie früher zu IE5-Zeiten browserversionsspezifische Verzweigungen zu erzwingen, wäre wohl noch schlimmer gewesen
Ich beneide Rails und Ruby wirklich um ihre Art der Zeitverarbeitung
APIs wie
Time.current.in_time_zone('America/Los_Angeles') + 3.days - 4.months + 1.hoursind intuitiv und mächtigRuby überlädt Time als ein einziges konsistentes Objekt, sodass man sich kaum Gedanken über Konvertierungen oder Casts machen muss
Ich denke oft, wie schön es wäre, wenn man in JS einfach so etwas wie
new Date().add({ days: 1 })schreiben könnteAuch darüber, ob das Überladen der Core-Library wirklich ein guter Ansatz ist, lässt sich streiten
Schade, dass Safari die Temporal API noch nicht unterstützt
Hoffentlich kommt die Unterstützung nächstes Jahr
Date in JavaScript hat viele Probleme, aber ich glaube nicht, dass die Tatsache, dass es ein Objekt ist, an sich eines der großen Probleme ist
Ein unveränderliches Objekt wäre besser gewesen, aber dass ein veränderbares Objekt verändert wird, ist an sich keine Überraschung
Die eigentliche Gefahr von Mutabilität entsteht nicht lokal, sondern durch nichtlokale Änderungen
Es ist unpraktisch, dass die Temporal API Schaltsekunden (leap seconds) überhaupt nicht behandelt
Ich möchte ein JS-Tool für astronomische Berechnungen bauen, dafür werden für UTC-Umrechnungen Daten zu Schaltsekunden benötigt
Es gibt zwar Umwege wie
temporal-tai, aber dann muss man clientseitig eine Schaltsekunden-Datei pflegen, was umständlich istWegen SOP (CORS-Richtlinie) kann man die Datei auch nicht einfach direkt von externen Websites holen
Browser werden regelmäßig aktualisiert, daher frage ich mich, warum sie Informationen zu Schaltsekunden nicht eingebaut haben
Wenn der Server den Header
Access-Control-Allow-Originsetzt oder die Daten als JS-Datei bereitstellt, ist das möglichAllerdings kann es aufwendig sein, wenn Browser Schaltsekundendaten selbst mitliefern und pflegen sollen
UTC ist ursprünglich eine Zeitskala, die Schaltsekunden einschließt, daher wäre es korrekter zu sagen, dass tatsächlich nur mit POSIX-Zeit gearbeitet wird
Im Codebeispiel müsste es statt
"33"eigentlich ab"50"heißen, wenn es um die Zuordnung zum 20. Jahrhundert geht — ein einfacher Hinweis auf einen TippfehlerIch verwende das Temporal-Polyfill und bin bisher sehr zufrieden
Für Server oder große Apps ist das in Ordnung, für kleine Apps kann es aber belastend sein
Merkwürdigerweise erwähnt der Artikel
Date.now()überhaupt nichtFür einen Vergleich mit Temporal hätte man die Erklärung an
Date.now()aufhängen sollenDiese Funktion gibt die vergangene Zeit in Millisekunden seit dem 1. Januar 1970 zurück
Temporal bietet zwar die benutzerfreundlichere API, aber im Kern geht es darum, die relative Entfernung in der Zeit auszudrücken
Dann stellt sich die Frage, wie man in das gewünschte Format konvertiert, ohne den Umweg über Date zu nehmen
Es wird noch die kleine, aber wichtige Korrektur angemerkt, dass es nicht „daylight savings time“, sondern „daylight saving time“ heißt
Mir war bis jetzt nicht klar, wie kaputt JS Date eigentlich ist
Wäre man damals nur etwas vorsichtiger gewesen, wären unzählige Entwickler nicht in diese Fallen getappt