Temporal API

Die JavaScript Temporal API: ein moderner Ersatz für Date

JavaScript Date ist seit Jahrzehnten auf bekannte Weise kaputt. TC39 Temporal — seit Anfang 2025 Stage 4, ausgeliefert in modernen Browsern und Node.js — trennt sauber Zeitpunkte, Wanduhr-Daten und zonierte Datum-Zeit-Werte. Dieser Leitfaden erklärt die neuen Typen, wie sie auf Unix-Zeitstempel abbilden, und wie man migriert.

Temporal vs. Date auf einen Blick

JavaScripts eingebautes Date ist seit Jahrzehnten eine bekannte Fehlerquelle: es ist veränderlich, kennt nur die lokale Zeitzone und UTC, seine Monate sind nullbasiert und sein Parsing ist lose spezifiziert. Temporal ist der standardisierte Ersatz — Stage 4 und Teil von ECMAScript 2026 — und behebt jedes dieser Probleme mit zweckgebauten, unveränderlichen Typen. Die Tabelle unten ist der grobe Kontrast; der Rest dieses Leitfadens behandelt die Typen und wie sie auf Unix-Zeitstempel abbilden.

AspektDate (alt)Temporal
VeränderlichkeitVeränderlichUnveränderlich
PräzisionMillisekundenNanosekunden
ZeitzonenNur lokal + UTCJede IANA-Zone (ZonedDateTime)
Monatsindizierung0-basiert (0 = Januar)1-basiert (1 = Januar)
ParsingNachsichtig, implementierungsabhängigStriktes ISO 8601 / RFC 9557
Instant vs. WanduhrIn einem Typ vermischtGetrennte Typen

Warum es Temporal gibt

JavaScript Date vermischt mehrere unterschiedliche Konzepte: einen exakten Zeitpunkt, eine Wanduhrzeit und ein zoniertes Datum-Zeit. Date hat außerdem bekannte Parsing-Eigenheiten, eine einzige Zeitzone (die des Nutzers) und Millisekunden-Präzision. Temporal stellt die zugrunde liegenden Konzepte als getrennte Typen bereit und unterstützt Nanosekunden-Präzision, beliebige IANA-Zeitzonen und explizite Kalendersysteme.

  • Stage 4 seit Anfang 2025; zuerst standardmäßig in Firefox 139 ausgeliefert
  • Jetzt verfügbar in Chrome 144+, Firefox 139+ und Node.js 26+
  • Polyfills (@js-temporal/polyfill) funktionieren in jeder modernen Umgebung
  • Auf Koexistenz mit Date ausgelegt — Interop-Methoden existieren in beide Richtungen

Die zentralen Temporal-Typen

Ein kleiner Satz von Typen deckt das Datum-Zeit-Problem sauber ab. Jeder hat eine kanonische String-Form (ISO 8601, für den zonierten Typ erweitert durch RFC 9557):

TypRepräsentiertBeispiel-String
Temporal.InstantEin exakter Zeitpunkt, wie ein Unix-Zeitstempel (ns-Präzision)2026-01-01T00:00:00Z
Temporal.ZonedDateTimeZeitpunkt + IANA-Zeitzone + Kalender2026-01-01T09:00:00+09:00[Asia/Tokyo]
Temporal.PlainDateTimeDatum + Zeit, ohne Zeitzone2026-01-01T09:00:00
Temporal.PlainDateEin Kalenderdatum (z. B. ein Geburtstag)2026-01-01
Temporal.PlainTimeEine Wanduhrzeit09:00:00
Temporal.DurationEine Zeitspanne, einheitenbewusstP3DT4H10M

Mit Unix-Zeitstempeln arbeiten

Temporal.Instant ist der Unix-Zeitstempel-Typ. Die ausgelieferte API bietet nur Millisekunden- und Nanosekunden-Epoch-Konvertierungen — die früheren Methoden fromEpochSeconds und fromEpochMicroseconds wurden vor Stage 4 entfernt — konvertiere Unix-Sekunden also durch Multiplikation mit 1000. Nutze Instant für Speicherung und Transport und ZonedDateTime, wenn du eine Wanduhr-Sicht in einer bestimmten Zeitzone brauchst.

  • Temporal.Now.instant() — der aktuelle exakte Moment
  • Temporal.Instant.fromEpochMilliseconds(Date.now()) — aus einem JS-Millisekunden-Zeitstempel
  • Temporal.Instant.fromEpochMilliseconds(1700000000 * 1000) — aus Unix-Sekunden (× 1000)
  • Temporal.Instant.fromEpochNanoseconds(1700000000000000000n) — aus Nanosekunden (BigInt)
  • instant.epochMilliseconds und instant.epochNanoseconds — den Epoch-Wert zurücklesen
  • instant.toZonedDateTimeISO("America/New_York") — eine Wanduhr-Sicht in einer Zone

Zeitzonen und DST korrekt behandelt

ZonedDateTime trägt eine IANA-Zeitzone, daher werden DST-Umstellungen, Lückenzeiten und Überlappungszeiten alle explizit behandelt. Die Disambiguierungs-Option lässt dich eine Richtlinie für mehrdeutige lokale Zeiten wählen, und das kanonische String-Format ist RFC 9557 (ein ISO-8601-Zeitstempel mit Zone in Klammern).

  • zdt.timeZoneId — der IANA-Name (z. B. America/Los_Angeles)
  • zdt.add({ hours: 1 }) — DST-bewusste Arithmetik in Wanduhr-Begriffen
  • zdt.until(zdt2) — Abstand zwischen zwei zonierten Datum-Zeit-Werten
  • Disambiguierungs-Optionen: "earlier", "later", "compatible" (Standard — später bei Lücke, früher bei Überlappung), "reject"
  • Hin und zurück: Instant ↔ zoniertes Datum-Zeit ist verlustfrei

Migrationsmuster von Date

Die einfachste Migrationsstrategie ist, Temporal zuerst an den Grenzen einzuführen (Eingabe parsen, Ausgabe formatieren) und die interne Logik schrittweise zu verschieben.

  • Date → Instant: Temporal.Instant.fromEpochMilliseconds(date.getTime())
  • Instant → Date: new Date(instant.epochMilliseconds)
  • Für neuen Code überall Temporal bevorzugen und nur an API-Rändern zu Date konvertieren
  • date-fns und Luxon haben beide Temporal-bewusste Modi / Adapter
  • JSON: Temporal.Instant.prototype.toJSON gibt einen ISO-8601-String zurück

Browser- und Runtime-Unterstützung

Temporal wurde 2025 ausgeliefert und die native Unterstützung ist inzwischen breit, aber noch nicht universell. Der Polyfill ist der sicherste Weg, solange ältere Browser und Safari stable noch im Einsatz sind.

  • Firefox 139+: als erster ausgeliefert, standardmäßig aktiviert (Mai 2025)
  • Chrome 144+: standardmäßig aktiviert (Januar 2026)
  • Node.js 26+: standardmäßig aktiviert (Mai 2026)
  • Safari: in der Technology Preview verfügbar, noch nicht in einem stabilen Release
  • Polyfill: @js-temporal/polyfill oder temporal-polyfill — gleiche API, jede moderne Umgebung

Verwandte Referenzen

FAQ

Ist Temporal ein Ersatz für Date?
Ja — Temporal ist darauf ausgelegt, Date für neuen Code vollständig zu ersetzen. Date bleibt aus Gründen der Abwärtskompatibilität in der Sprache, und beide arbeiten über Epoch-Millisekunden zusammen.
Wie konvertiere ich einen Unix-Zeitstempel zu Temporal?
Verwende Temporal.Instant.fromEpochMilliseconds(). Für Unix-Sekunden mit 1000 multiplizieren: Temporal.Instant.fromEpochMilliseconds(seconds * 1000). Die ausgelieferte API hat nur fromEpochMilliseconds und fromEpochNanoseconds — die ältere Methode fromEpochSeconds wurde entfernt, bevor Temporal Stage 4 erreichte.
Unterstützt Temporal Nanosekunden?
Ja. Temporal.Instant hat intern Nanosekunden-Präzision und stellt epochNanoseconds als BigInt bereit.
Kann ich Temporal heute in Node.js nutzen?
In Node.js 26+ ist Temporal standardmäßig aktiviert. In älteren Node-Versionen installiere @js-temporal/polyfill — die API-Oberfläche ist identisch.
Welche Browser unterstützen Temporal?
Firefox 139+ (Mai 2025), Chrome 144+ (Januar 2026) und Node.js 26+ (Mai 2026) liefern Temporal standardmäßig aus. Safari hat es in der Technology Preview. Für ältere Umgebungen nutze den @js-temporal/polyfill.
Wie behandelt Temporal die DST-Lücke?
ZonedDateTime-Konstruktoren und -Arithmetik akzeptieren eine Disambiguierungs-Option. "compatible" (Standard) wählt für Lücken den späteren Zeitpunkt und für Überlappungen den früheren; "reject" wirft einen Fehler, wenn die lokale Zeit mehrdeutig ist.