16 Punkte von GN⁺ 2024-08-25 | 5 Kommentare | Auf WhatsApp teilen
  • Zu den bemerkenswertesten jüngsten Änderungen in ECMAScript gehört der Temporal-Vorschlag
    • Diese API kann bereits über ein vom FullCalendar-Team bereitgestelltes Polyfill verwendet werden
    • Einer der größten Vorteile dieser API ist, dass es endlich ein natives Objekt zur Darstellung von "Zoned Date Time" gibt

Was ist Zoned Date Time?

  • Wenn wir mit menschlichen Datumsangaben arbeiten, lassen wir die Zeitzone normalerweise weg und sprechen einfach von Datum und Uhrzeit
  • Das JavaScript-Objekt Date arbeitet jedoch nur mit Zahlen, wodurch die ursprüngliche Bedeutung des Datums verloren geht
  • Wenn man zum Beispiel den Zeitpunkt einer Kartenzahlung erfassen möchte, würden viele Leute möglicherweise folgenden Code verwenden
    const paymentDate = new Date('2024-07-20T10:30:00');  
    
  • Dabei berechnet der Browser die Millisekunden anhand der Zeitzone des Nutzers (CET). Die gespeicherten Informationen können jedoch je nach Zeitzone unterschiedlich interpretiert werden
  • Neben der sehr wichtigen Tatsache, dass Datumswerte in JavaScript nicht UTC verwenden, sondern POSIX, bei dem Schaltsekunden vollständig ignoriert werden, gibt es noch das Problem, dass bei bloßen Zahlen die ursprüngliche Bedeutung des Datums verloren geht
  • Viele glauben, dass man auf der sicheren Seite ist, wenn man mit UTC arbeitet oder Datumswerte im ISO-Format übergibt, doch auch dabei können weiterhin Informationen verloren gehen

UTC reicht nicht aus

  • Selbst wenn man mit dem ISO-Format arbeitet, fehlen beim Anzeigen eines Datums weiterhin Informationen zur Zeitzone
  • Eine Funktion, die einen Zeitstempel in ein menschenlesbares Datum umwandelt, ist nicht injektiv
  • Wenn man zum Beispiel nach Sydney reist und anschließend nach Madrid zurückkehrt, kann die Zeitzonenproblematik in den Banktransaktionen für Verwirrung sorgen

Einführung in die Temporal API

  • Die Temporal API führt das Objekt Temporal.ZonedDateTime ein, das Datum und Uhrzeit zusammen mit einer Zeitzone darstellen kann
  • Sie schlägt eine Erweiterung von RFC 3339 vor und definiert damit einen Standard zum Serialisieren und Deserialisieren von Datumswerten als Strings
  • 1996-12-19T16:39:57-08:00[America/Los_Angeles]
    • Dieser String steht für den 19. Dezember 1996 um 16:39:57
    • Der Offset zu UTC beträgt -08:00 (Pacific Standard Time, PST, zu der Los Angeles gehört)
    • Zusätzlich wird die zugehörige Standardzeitzone ("Pacific Standard Time") angegeben, damit zeitzonenbewusste Anwendungen sie berücksichtigen können
  • Unterstützt verschiedene Kalendersysteme (z. B. buddhistisch, chinesisch, Dangi, gregorianisch, islamisch, persisch, japanisch usw.)

Grundlegende Operationen

Datum erstellen
  • Die Temporal API bietet leistungsstarke Werkzeuge für den Umgang mit Zeitzonen
  • Beim Erstellen eines Temporal.ZonedDateTime-Objekts wird die Zeitzone zum Beispiel korrekt berücksichtigt:
    const zonedDateTime = Temporal.ZonedDateTime.from({  year: 2024,  month: 8,  day: 16,  hour: 12,  minute: 30,  second: 0,  timeZone: 'Europe/Madrid'});  
    
  • Dadurch bleibt die Zeit auch bei Zeitzonenwechseln oder lokalen Zeitanpassungen wie DST korrekt erhalten
Datum vergleichen
  • Das Objekt ZonedDateTime bietet die Methode compare, mit der zwei ZonedDateTime-Werte verglichen werden können:
    const one = Temporal.ZonedDateTime.from('2020-11-01T01:45-07:00[America/Los_Angeles]');  
    const two = Temporal.ZonedDateTime.from('2020-11-01T01:15-08:00[America/Los_Angeles]');  
    Temporal.ZonedDateTime.compare(one, two);  // => -1  
    
Nützliche eingebaute Funktionen
  • Die Eigenschaft hoursInDay gibt die tatsächliche Anzahl von Stunden an diesem Tag zurück:
    Temporal.ZonedDateTime.from('2020-03-08T12:00-07:00[America/Los_Angeles]').hoursInDay;  // => 23  (Beginn der DST)  
    
Zeitzonenumwandlung
  • Mit der Methode withTimeZone lässt sich die Zeitzone eines ZonedDateTime ändern:
    zdt = Temporal.ZonedDateTime.from('1995-12-07T03:24:30+09:00[Asia/Tokyo]');  
    zdt.withTimeZone('Africa/Accra').toString(); // => '1995-12-06T18:24:30+00:00[Africa/Accra]'  
    
Grundlegende arithmetische Operationen
  • Mit der Methode .add können Datumswerte unter Berücksichtigung der DST-Regeln addiert oder subtrahiert werden:
    zdt = Temporal.ZonedDateTime.from('2020-03-08T00:00-08:00[America/Los_Angeles]');  
    laterDay = zdt.add({ days: 1 });  // => 2020-03-09T00:00:00-07:00[America/Los_Angeles]  
    
Unterschied zwischen Datumswerten berechnen
  • Die Methode .until berechnet die Differenz zwischen zwei Zeitpunkten und gibt sie als Temporal.Duration-Objekt zurück
    • Sie kann zum Beispiel als zdt.until(other) verwendet werden

Fazit

  • Die Temporal API verändert die Art und Weise, wie in JavaScript mit Zeit umgegangen wird, grundlegend
  • In diesem Artikel wurden der Unterschied zwischen menschenlesbaren Datumsangaben und UTC-Daten sowie die korrekte Darstellung mit Temporal.ZonedDateTime behandelt
  • Im nächsten Artikel sollen weitere interessante Objekte wie Instant, PlainDate und Duration untersucht werden

Meinung von GN⁺

  • Das Problem der Datums- und Zeitverarbeitung, das JavaScript-Entwicklern lange Schwierigkeiten bereitet hat, dürfte mit der Temporal API gelöst werden
  • Da Zeitzonen- und DST-Probleme automatisch verarbeitet werden können, ist sie für die Entwicklung globaler Anwendungen sehr nützlich
  • Die Kompatibilität mit dem bestehenden Date-Objekt sowie Migrationsfragen bleiben Punkte, die berücksichtigt werden müssen
  • Die Temporal-API ist klar und intuitiv gestaltet und überzeugt auch bei der Internationalisierung, etwa durch die Unterstützung verschiedener Kalendersysteme
  • Es ist zu erwarten, dass diese Änderung die Produktivität von JavaScript-Entwicklern deutlich steigern wird

5 Kommentare

 
kyc1682 2024-08-26

Endlich!

 
huiya 2024-08-26

Krass, beim Design globaler Services hatte ich wegen Datumsangaben immer Kopfzerbrechen.
Das würde ich gern mal ausprobieren.

 
jjpark78 2024-08-26

Wirklich, heißt das endlich, dass man weder moment noch dayjs verwenden muss?

 
GN⁺ 2024-08-25
Hacker-News-Kommentare
  • Der Umgang mit Datum und Uhrzeit in JavaScript ist sehr schwierig

    • Die Bibliothek Moment verwechselt Datum und Uhrzeit und verursacht dadurch viele Probleme
    • Auch die Python-Bibliothek Arrow macht denselben Fehler
    • Die Rust-Bibliothek Chrono ist vorhersehbar und weniger fehleranfällig
    • JS Date und Moment sind schwer zu benutzen
  • Es wird erwartet, dass die neue API die Zeitzonenprobleme von JS löst

    • Sie parst bestimmte Zeitzonen erfolgreich, nimmt in anderen Fällen aber UTC an
    • Im vorherigen Job hatte ich deswegen große Schwierigkeiten
  • Eine Funktion, die einen Zeitstempel in ein menschenlesbares Datum umwandelt, ist nicht injektiv

    • Dabei werden die Konzepte von Injektivität und Wohldefiniertheit verwechselt
    • Für einen Zeitstempel t existiert kein eindeutiges menschenlesbares Datum x
  • Ein Witz über die Lernkurve bei der Zeitverarbeitung

    • Anfänger verwenden nur UTC-Zeitstempel
    • Fortgeschrittene behaupten, man müsse Zeitzonen speichern und umrechnen
    • Profis verwenden wieder nur UTC-Zeitstempel
  • Mehr Beispiele mit zukünftigen Daten würden den Artikel überzeugender machen

    • Beim Aufzeichnen von Zeitstempeln braucht man nur UTC und den Ort
    • Das Bankenbeispiel ist nur ein UX-Problem, kein Informationsverlust
  • Ein Nutzer ist verunsichert, weil er die Zeitverarbeitung nicht versteht

    • Bitte um Empfehlung für eine gute Einführung, um Probleme der Zeitverarbeitung in Sprachen wie Python zu verstehen
  • Ein guter datetime-Standard ist die halbe Miete

    • Die andere Hälfte ist die breite Akzeptanz
    • Für die Kompatibilität mit anderen Systemen ist die Umwandlung in ISO-Strings oder Unix-Zeitstempel sicher
  • ISO-Datumsstrings sollten die exakten Informationen erfassen

    • Es wird infrage gestellt, ob JavaScript oder andere Sprachen eingebaute Strukturen benötigen
    • Temporal und Date lösen einfache Probleme auf komplizierte Weise
  • Frage, wie man dieses Problem in Postgres behandeln sollte

  • Es gibt zu wenig Belege dafür, dass Temporal tatsächlich eingeführt wird

    • Wie viele andere vielversprechende JS-Vorschläge wird es seit langer Zeit nur diskutiert