Zeitzonenkorrektes Datumsformat in JavaScript ohne Bibliotheken
Das eingebaute Intl.DateTimeFormat von JavaScript bewältigt IANA-Zeitzonen-Formatierung ohne moment.js oder date-fns. Lerne explizite timeZone-Optionen, sommerzeitsichere Anzeige, formatToParts, die Grenzen der Wanduhr-Umwandlung und wann Temporal oder eine Zeitzonen-Bibliothek noch nützlich ist.
Warum Date keine Zeitzonen-Eigenschaft hat
Ein JavaScript-Date ist immer ein UTC-Millisekundenzähler. Im Objekt ist keine Zeitzone gespeichert. Wenn du .toString() oder .toLocaleString() ohne Optionen aufrufst, nutzt JavaScript die lokale Zeitzone des Runtimes vom Betriebssystem. Derselbe Code erzeugt auf einem Server in New York andere Ausgaben als auf einem Laptop in Tokio, obwohl der zugrunde liegende Timestamp identisch ist.
Mit Intl.DateTimeFormat formatieren
Intl.DateTimeFormat ist die eingebaute API für locale- und zeitzonenbewusstes Formatieren. Sie unterstützt IANA-Zeitzonen-Identifier, behandelt Sommerzeit-Umstellungen automatisch und ist in modernen Browsern und Node.js verfügbar. Der Schlüssel ist, die timeZone-Option explizit zu übergeben, statt sich auf den Runtime-Standard zu verlassen.
- new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'long' }).format(date)
- date.toLocaleString('en-GB', { timeZone: 'Europe/London', hour12: false })
- date.toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' })
- new Intl.DateTimeFormat('en-US', { timeZone: 'UTC', hour12: false }).format(date)
Einzelne Teile mit formatToParts extrahieren
Nutze formatToParts(), um die einzelnen Datumskomponenten als {type, value}-Objekte für eigene Datums-Strings zu erhalten. Das ist besser, als einen lokalisierten Datums-String zu zerteilen, weil Zeichensetzung, Reihenfolge und Schriften je nach Locale variieren.
- const parts = new Intl.DateTimeFormat('en-US', { timeZone: 'America/Chicago', year: 'numeric', month: '2-digit', day: '2-digit' }).formatToParts(date)
- parts.find(p => p.type === 'year').value → '2023'
- parts.find(p => p.type === 'month').value → '11'
- Object.fromEntries(parts.map(p => [p.type, p.value])) → { year, month, day, hour, minute, second }
Wanduhrzeit in UTC umwandeln (die schwierige Richtung)
Von einer Wanduhrzeit in einer gegebenen Zeitzone zu UTC zu gelangen ist mit der klassischen Date-API schwieriger. Einen Moment in America/New_York zu formatieren ist einfach; den durch 2026-03-08 02:30 in America/New_York dargestellten Moment zu konstruieren ist es nicht, weil diese lokale Zeit bei Sommerzeit-Umstellungen übersprungen oder wiederholt werden kann.
- Temporal erreichte 2026 Stufe 4, aber native Browser-Unterstützung ist noch nicht universell
- Für den Produktionseinsatz in allen Browsern heute sind der Temporal-Polyfill oder date-fns-tz toDate() weiterhin praktische Optionen
- Vermeide manuelle UTC-Offset-Arithmetik — Sommerzeit-Umstellungen passieren in verschiedenen Jahren zu verschiedenen lokalen Zeiten
- Das zonedToEpochMs() dieser Seite nutzt eine Offset-Korrektur mit einer Iteration — siehe src/timeUtils.ts
Den richtigen Zeitzonen-Identifier wählen
Nutze IANA-Zeitzonennamen wie America/New_York, Europe/London, Asia/Tokyo oder UTC. Vermeide feste Offsets wie UTC-5 für nutzerseitige Zeiten, denn Offsets ändern sich mit der Sommerzeit. America/New_York kann im Januar UTC-5 und im Juli UTC-4 sein; der IANA-Name lässt die Plattform die korrekte historische Regel für das gewählte Datum anwenden.
- Gut: America/Los_Angeles — enthält historische und zukünftige Sommerzeit-Regeln
- Gut: Europe/Berlin — behandelt die mitteleuropäische Sommerzeit automatisch
- Gut: Asia/Shanghai — stabile UTC+8-Anzeige ohne Sommerzeit
- Nutze UTC für Logs, API-Speicherung, Datenbank-Timestamps und regionenübergreifenden Vergleich
- Nutze die IANA-Zeitzone des Nutzers für die finale Anzeige in der Produkt-UI
FAQ zur Zeitzonen-Formatierung
- Kann JavaScript ein Datum ohne Bibliothek in einer anderen Zeitzone formatieren?
- Ja. Nutze Intl.DateTimeFormat oder toLocaleString mit einer timeZone-Option wie America/New_York oder Asia/Tokyo.
- Behandelt Intl.DateTimeFormat die Sommerzeit?
- Ja. Wenn du einen IANA-Zeitzonen-Identifier nutzt, wendet das Runtime den korrekten Offset für diese Zeitzone und dieses Datum an.
- Soll ich Zeitzonen-Offsets oder Zeitzonennamen speichern?
- Speichere UTC für Ereignis-Momente. Wenn du den lokalen Kontext des Nutzers brauchst, speichere einen IANA-Zeitzonennamen wie America/New_York, nicht nur einen numerischen Offset.
- Wie bekomme ich die Zeitzone des Nutzers in JavaScript?
- Nutze Intl.DateTimeFormat().resolvedOptions().timeZone, das einen IANA-Namen wie America/New_York zurückgibt. Speichere diesen Namen, nicht einen numerischen Offset, wenn du später die lokale Zeit des Nutzers rekonstruieren musst.