Einleitung: Warum Zeit der Kopfschmerz jedes Entwicklers ist
\n\nHaben Sie schon einmal einen Bug erwischt, bei dem ein Benutzer aus Wladiwostok das Datum von morgen sieht, obwohl heute auf dem Kalender steht? Oder wenn ein Server in AWS us-east-1 eine Zeit sendet, die Ihr Client in Kaliningrad als 3 Uhr morgens interpretiert? Willkommen in der Welt der Zeitzonen in TypeScript.
\n\nDas Problem ist, dass JavaScript (und TypeScript als seine Erweiterung) ursprünglich für Browser entwickelt wurde. Das eingebaute Date-Objekt ist im Grunde ein getarnter UTC-Zeitstempel. Es kann nicht so mit Zeitzonen arbeiten, wie wir es brauchen. Und wenn Sie eine ernsthafte Anwendung in TypeScript schreiben – sei es ein Admin-Panel in React, ein Backend in Node.js oder eine mobile App in React Native – kommen Sie ohne eine fundierte Arbeit mit Zeitzonen nicht aus.
In diesem Artikel zeige ich Ihnen, wie Sie die Zeit zähmen. Wir werden uns mit grundlegenden Konzepten befassen, lernen, moderne Bibliotheken zu nutzen und typische Fallstricke vermeiden. Los geht's!
\n\nWas Sie über Zeitzonen wissen müssen, bevor Sie Code schreiben
\n\nBevor wir in TypeScript eintauchen, lassen Sie uns die Dinge klarstellen. Es gibt zwei Arten von Zeit: absolute Zeit (UTC) und lokale Zeit (das, was der Benutzer sieht).
\n\n- \n
- UTC (Coordinated Universal Time) – das ist der Standard. Server, Datenbanken und APIs sollten die Zeit in UTC speichern. Das ist eine eiserne Regel. \n
- IANA Time Zone Database – das ist ein Wörterbuch der Zeitzonen im Format
Europe/Moscow,Asia/Vladivostok. Diese Zeichenfolgen, nicht Abkürzungen wie MSK oder PST, sollten im Code verwendet werden. \n - Offset (Verschiebung) – das ist die Differenz zu UTC, z.B. +03:00. Aber denken Sie daran: Der Offset kann sich aufgrund der Sommerzeit (DST) ändern. Daher ist es eine schlechte Idee, den Offset anstelle der IANA-Zone zu speichern. \n
\n\n\nGoldene Regel: Speichern in UTC, konvertieren auf dem Client, IANA-Zeichenfolgen zur Identifizierung von Zonen verwenden.
\n
Warum das native Date nicht ausreicht: Schmerz und Leid
\n\nSehen wir der Wahrheit ins Auge: new Date() in TypeScript ist wie ein Schweizer Taschenmesser mit kaputter Klinge. Es kann nur einen Zeitstempel speichern und ihn in der lokalen Zone des Browsers oder Servers anzeigen. Versuchen Sie etwas Komplexeres:
// Schlechtes Beispiel: Versuch, mit nativen Mitteln mit Zonen zu arbeiten\nconst date = new Date('2024-03-10T12:00:00');\nconsole.log(date.toLocaleString('ru-RU', { timeZone: 'Europe/Moscow' }));\n// Ausgabe: "10.03.2024, 15:00:00" – aber das ist nur ein String, kein Objekt!\n\n// Was, wenn man ein Date in einer anderen Zone benötigt?\n// Hoppla... natives JS kann kein Date mit Zonenbindung erstellen.\n\n\nDas Problem ist, dass Date die Zeit immer in UTC speichert. Alle Methoden wie getHours() konvertieren UTC einfach in die lokale Zeit des Browsers. Sie können kein Date-Objekt erhalten, das "denkt", es sei in New York.
Deshalb verwenden wir Bibliotheken. Im TypeScript-Ökosystem gibt es zwei Hauptkandidaten: Luxon und date-fns-tz.
\n\nLuxon: Schwere Artillerie für die Arbeit mit Daten
\n\nLuxon ist eine moderne Bibliothek vom Ersteller von Moment.js (das bereits deprecated ist). Sie wurde von Grund auf neu geschrieben, verwendet natives Intl.DateTimeFormat und ist für TypeScript hervorragend typisiert.
Installation von Luxon
\n\nnpm install luxon\nnpm install --save-dev @types/luxon\n\n\nErstellen eines Datums in einer bestimmten Zeitzone
\n\nimport { DateTime } from 'luxon';\n\n// Erstellen eines Datums in der Zone Europe/Moscow\nconst moscowTime = DateTime.fromObject(\n { year: 2024, month: 3, day: 10, hour: 12 },\n { zone: 'Europe/Moscow' }\n);\nconsole.log(moscowTime.toISO());\n// Ausgabe: "2024-03-10T12:00:00.000+03:00"\n\n// Konvertieren in eine andere Zone\nconst nyTime = moscowTime.setZone('America/New_York');\nconsole.log(nyTime.toISO());\n// Ausgabe: "2024-03-10T05:00:00.00