webentwicklung-frage-antwort-db.com.de

Was sind gültige Datums-Zeichenfolgen in JavaScript?

Bei der Verwendung von new Date oder Date.parse in JavaScript kann ich nicht einfach beliebige Datumsformate übergeben. Je nach Format bekomme ich ein anderes Datum als ich wollte oder sogar Invalid Date anstelle eines Datumsobjekts. Einige Datumsformate funktionieren in einem Browser, in anderen jedoch nicht. Welche Datumszeitformate sollte ich verwenden?

Weitere Fragen:

  • Unterstützen alle Browser dieselben Formate? Wie handhaben Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge und Apple Safari Datums-Zeichenfolgen? Was ist mit Node.js?

  • Berücksichtigt es das lokale Datumsformat? Z.B. Wenn ich in der Schweiz wohne und das Datumsformat 30.07.2018 ist, kann ich new Date('30.07.2018') verwenden?

  • Berücksichtigt es die lokale Zeitzone?

  • Wie kann ich eine Datumszeitzeichenfolge von einem Datumsobjekt erhalten?

  • Wie kann ich ungültige Datumszeitzeichenfolgen erkennen?

  • Wie behandeln Datumsbibliotheken wie Moment.js Datumszeichenfolgen?

Falls Sie es nicht bemerkt haben, habe ich meine eigene Frage beantwortet ( warum? ).

8
str

Das Notwendigste

JavaScript unterstützt offiziell eine Vereinfachung des erweiterten ISO 8601-Formats. Das Format ist wie folgt: YYYY-MM-DDTHH:mm:ss.sssZ. Der Buchstabe T ist das Datums-/Zeittrennzeichen und Z ist der Zeitzonenversatz, angegeben als Z (für UTC) oder entweder + oder - gefolgt von einem Zeitausdruck HH:mm. Einige Teile (z. B. die Zeit) dieses Formats können weggelassen werden.

Beachten Sie, dass Jahre müssen mindestens vier Stellen haben, Monat/Tag/Stunden/Minuten/Sekunden müssen genau zwei Stellen haben und Millisekunden müssen genau dreistellig. Beispielsweise ist 99-1-1 keine gültige Datumszeichenfolge.

Dies sind einige Beispiele für gültige Datums- (Uhrzeit-) Zeichenfolgen:

  • 2018-12-30
  • 2018-12-30T20:59
  • 2018-12-30T20:59:00
  • 2018-12-30T20:59:00.000Z
  • 2018-12-30T20:59:00.000+01:00
  • 2018-12-30T20:59:00.000-01:00

Wenn Sie den Zeitzonenoffset weglassen, werden Datums- und Uhrzeitangaben als lokale Benutzerzeit interpretiert. Wenn Sie die Uhrzeit ganz weglassen, werden Datumsangaben als UTC interpretiert.

Wichtig : Alle modernen und einigermaßen alten Browser und Implementierungen unterstützen das Format full-length Datum und Uhrzeit gemäß Spezifikation. Allerdings Es gibt Unterschiede bei der Behandlung von Datums- (Zeit-) Zeichenfolgen ohne Zeitzone (Einzelheiten siehe "Offset für fehlende Zeitzonen" weiter unten). Sie sollten nicht Datum-Zeit-Zeichenfolgen ohne Zeitzone verwenden (Status 2018). Übergeben Sie stattdessen einen - Unix-Zeitstempel in Millisekunden oder separate Argumente für verschiedene Teile des Datums an den Konstruktor Date.

Die meisten Browser unterstützen auch einige andere Formate, diese sind jedoch nicht angegeben und funktionieren daher nicht in allen Browsern auf die gleiche Weise. Wenn überhaupt, sollten Sie nur die oben erläuterten Formate für Datums- und Uhrzeitzeichenfolgen verwenden. Jedes andere Format kann in anderen Browsern oder sogar in anderen Versionen desselben Browsers fehlerhaft sein.

Wenn Sie statt eines Datumsobjekts auf Invalid Date stoßen, verwenden Sie höchstwahrscheinlich eine ungültige Datums-/Uhrzeitzeichenfolge.


Und jetzt mit etwas mehr Details.

Format der Datums- und Uhrzeitzeichenfolge

ECMAScript (die Spezifikation, die die JavaScript-Sprache implementiert) unterstützt seit Jahren Datumszeichenfolgen in new Date ( Spezifikation ) und Date.parse ( Spezifikation ) seit seiner Gründung. In den ersten Versionen wurde jedoch kein Datums- und Uhrzeitformat angegeben. Dies änderte sich 2009, als ES5 mit einer Spezifikation eines Datums- und Uhrzeitformats eingeführt wurde.

Die Grundlagen

ECMAScript spezifiziert das Date Time String Format als Vereinfachung des ISO 8601 Extended Format . Das Format ist wie folgt: YYYY-MM-DDTHH:mm:ss.sssZ.

  • YYYY ist die Dezimalstelle des Jahres 0000 bis 9999 im proleptischen Gregorianischen Kalender.
  • - (Bindestrich) erscheint buchstäblich zweimal in der Zeichenfolge.
  • MM ist der Monat des Jahres von 01 (Januar) bis 12 (Dezember).
  • DD ist der Tag des Monats von 01 bis 31.
  • T wird buchstäblich in der Zeichenfolge angezeigt, um den Beginn des Zeitelements anzugeben.
  • HH ist die Anzahl der vollständigen Stunden, die seit Mitternacht als zwei Dezimalstellen von 00 bis 24 vergangen sind.
  • : (Doppelpunkt) erscheint buchstäblich zweimal in der Zeichenfolge.
  • mm ist die Anzahl der vollständigen Minuten seit dem Beginn der Stunde als zwei Dezimalstellen von 00 bis 59.
  • ss ist die Anzahl der vollständigen Sekunden seit dem Beginn der Minute als zwei Dezimalstellen von 00 bis 59.
  • . (Punkt) erscheint wörtlich in der Zeichenkette.
  • sss ist die Anzahl der vollständigen Millisekunden seit dem Beginn der Sekunde als drei Dezimalstellen.
  • Z ist der Zeitzonenversatz, der als "Z" (für UTC) oder entweder "+" oder "-" angegeben ist, gefolgt von einem Zeitausdruck HH:mm

Die Spezifikation erwähnt dass wenn "der String nicht dem [angegebenen] Format entspricht, die Funktion möglicherweise auf implementierungsspezifische Heuristiken oder implementierungsspezifische Datumsformate zurückgreift" führen zu unterschiedlichen Daten in verschiedenen Browsern.

ECMAScript berücksichtigt keine lokalen Datums- und Uhrzeitformate von Benutzern. Dies bedeutet, dass Sie keine länderspezifischen Datums- und Uhrzeitformate verwenden können.

Kurze Datums- (und Uhrzeit-) Formulare

Die Spezifikation enthält auch kürzere Formate wie folgt.

Dieses Format enthält nur Datumsformulare:

  • YYYY
  • YYYY-MM
  • YYYY-MM-DD

Es enthält auch "Datum-Zeit" -Formulare, die aus einem der oben genannten Nur-Datum-Formulare bestehen, unmittelbar gefolgt von einem der folgenden Zeitformulare, an die ein optionaler Zeitzonenversatz angehängt ist:

  • THH:mm
  • THH:mm:ss
  • THH:mm:ss.sss

Fallback-Werte

[...] Wenn die Felder MM oder DD fehlen, wird "01" als Wert verwendet. Wenn die Felder HH, mm oder ss nicht vorhanden sind, wird "00" als Wert und der Wert eines fehlenden sss verwendet. Das Feld ist "000". Wenn der Zeitzonenoffset fehlt, werden Datumsformulare als UTC-Zeit und Datumsformulare als Ortszeit interpretiert.

Weitere Informationen zur fehlenden Browserunterstützung finden Sie weiter unten unter "Offset für fehlende Zeitzonen".

Out of Bound Values

Unzulässige Werte (out-of-bounds sowie Syntaxfehler) in einer Formatzeichenfolge bedeuten, dass die Formatzeichenfolge keine gültige Instanz dieses Formats ist.

Beispielsweise führen new Date('2018-01-32') und new Date('2018-02-29') zu einem Invalid Date.

Erweiterte Jahre

Das Datum/Uhrzeit-Format von ECMAScript gibt außerdem an, dass Extended Years sechsstellige Jahreswerte sind. Ein Beispiel für ein solches erweitertes Jahreszeichenfolgenformat sieht aus wie +287396-10-12T08:59:00.992Z, das ein Datum im Jahr 287396 angibt. Erweiterte Jahre können entweder positiv oder negativ sein.

Datums-API

ECMAScript gibt eine Vielzahl von Datumsobjekteigenschaften an. Bei einem gültigen Datumsobjekt können Sie Date.prototype.toISOString() verwenden, um eine gültige Datums-/Uhrzeitzeichenfolge abzurufen. Beachten Sie, dass die Zeitzone immer UTC ist.

new Date().toISOString() // "2018-08-05T20:19:50.905Z"

Mit der folgenden Funktion kann auch festgestellt werden, ob ein Datumsobjekt gültig oder ein Invalid Date ist.

function isValidDate(d) {
  return d instanceof Date && !isNaN(d);
}

Quelle und weitere Informationen finden Sie in Ermitteln eines "ungültigen Datums" Datumsinstanz in JavaScript .

Beispiele

Gültige Datums- und Uhrzeitformate

Die folgenden Datums- und Uhrzeitformate sind alle gemäß der Spezifikation gültig und sollten in jedem Browser, Node.js oder einer anderen Implementierung, die ES2016 oder höher unterstützt, funktionieren.

2018
2018-01
2018-01-01
2018-01-01T00:00
2018-01-01T00:00:00
2018-01-01T00:00:00.000
2018-01-01T00:00:00.000Z
2018-01-01T00:00:00.000+01:00
2018-01-01T00:00:00.000-01:00
+002018-01-01T00:00:00.000+01:00

Ungültige Datums- und Uhrzeitformate

Beachten Sie, dass die folgenden Beispiele gemäß der Spezifikation ungültig sind. Dies bedeutet jedoch nicht, dass kein Browser oder eine andere Implementierung sie zu einem Datum interpretiert. Bitte verwenden Sie keines der folgenden Datums-/Uhrzeitformate , da diese nicht dem Standard entsprechen und in einigen Browsern oder Browserversionen möglicherweise fehlschlagen.

2018-1-1 // month and date must be two digits
2018-01-01T0:0:0.0 // hour/minute/second must be two digits, millisecond must be three digits
2018-01-01 00:00 // whitespace must be "T" instead
2018-01-01T00 // shortest time part must have format HH:mm
2018-01-01T00:00:00.000+01 // time zone must have format HH:mm

Browser-Unterstützung

Heutzutage unterstützt jeder moderne und einigermaßen alte Browser das Datum/Uhrzeit-Format , das 2009 mit der ES5-Spezifikation eingeführt wurde. Allerdings gibt es auch heute (Stand 2018) unterschiedliche Implementierungen für Datum/Uhrzeit Zeichenfolgen ohne Zeitzone (siehe "Zeitzonenoffset fehlt" weiter unten). Wenn Sie ältere Browser unterstützen oder Zeichenfolgen ohne Zeitzone verwenden müssen, sollten Sie keine Datums-/Uhrzeitzeichenfolgen verwenden. Übergeben Sie stattdessen eine Anzahl der Millisekunden seit dem 1. Januar 1970, 00:00:00 UTC oder zwei oder mehr Argumente, die die verschiedenen Datumsteile darstellen an den Konstruktor Date.

Fehlender Zeitzonenversatz

ES5.1 falsch gibt an, dass der Wert eines fehlenden Zeitzonenversatzes “Z” ist, was im Widerspruch zu ISO 8601 steht. Dieser Fehler wurde in ) behoben + ES6 (ES2015) und erweitert in ES2016 (siehe "Änderungen an den ECMAScript-Spezifikationen" unten). Ab ES2016 werden Datums- und Uhrzeitzeichenfolgen ohne Zeitzone als Ortszeit und Datumszeichenfolgen als UTC analysiert.

Laut this answer haben einige Implementierungen nie das in ES5.1 festgelegte Verhalten implementiert. Einer von ihnen scheint Mozilla Firefox zu sein. Andere Browser, die anscheinend mit der Spezifikation von ES2016 (und höher) kompatibel sind, sind Google Chrome 65+, Microsoft Internet Explorer 11 und Microsoft Edge. Die aktuelle Version von Apple Safari (11.1.2) ist not kompatibel, da es fälschlicherweise Datums- und Zeitzeichenfolgen ohne Zeitzone (z. B. 2018-01-01T00:00) als UTC anstelle der Ortszeit analysiert.

Legacy Date Time-Formate

ES5 führte 2009 eine Spezifikation für Datums- und Uhrzeitzeichenfolgen ein. Vorher gab es keine bestimmten Formate, die von allen Browsern unterstützt wurden. Infolgedessen fügte jeder Browserhersteller Unterstützung für verschiedene Formate hinzu, die in verschiedenen Browsern (und Versionen) häufig nicht funktionierten. Ein kleines Beispiel der alten Geschichte finden Sie unter Datumsformate .

Die meisten Browser unterstützen weiterhin diese älteren Formate, um die Abwärtskompatibilität älterer Websites nicht zu beeinträchtigen. Es ist jedoch nicht sicher, sich auf diese Nicht-Standardformate zu verlassen, da sie möglicherweise inkonsistent sind oder jederzeit entfernt werden.

Date.prototype.toString() und Date.prototype.toUTCString()

ES2018 hat zum ersten Mal das Datumsformat angegeben, das von Date.prototype.toString() und Date.prototype.toUTCString() zurückgegeben wird . Bereits zuvor erforderte die ECMA-Spezifikation den Konstruktor Date und Date.parse, um die von diesen Methoden zurückgegebenen Formate korrekt zu analysieren (auch wenn vor 2018 kein Format angegeben wurde).

Ein beispielhafter Rückgabewert von Date.prototype.toString() könnte folgendermaßen aussehen:

Sun Feb 03 2019 14:27:49 GMT+0100 (Central European Standard Time)

Beachten Sie, dass der Name der Zeitzone in Klammern optional und der genaue Name "implementierungsabhängig" ist.

Date.prototype.toUTCString() gibt ein Datum in einem ähnlichen Format wie Date.prototype.toString() zurück, jedoch mit einem Zeitzonenversatz von Null. Ein Beispielformat könnte so aussehen:

Sun, 03 Feb 2019 13:27:49 GMT

Beachten Sie, dass nach der Umkehrung von Wochentag und Tag Monat ein Komma , im Vergleich zu Date.prototype.toUTCString() steht.

Da diese Formate erst 2018 festgelegt wurden, sollten Sie sich nicht darauf verlassen, dass sie in verschiedenen Implementierungen (insbesondere in älteren Browsern) gleichermaßen funktionieren.

Node.js

Node.js läuft auf der V8-JavaScript-Engine, die auch in Google Chrome verwendet wird. Es gilt also die gleiche Spezifikation bezüglich des Datum-Zeit-Zeichenfolgenformats. Da der Code jedoch im Backend ausgeführt wird, beeinflusst die lokale Zeit des Benutzers die Zeitzonen nicht, sondern nur die Einstellungen auf dem Server tun. Die meisten PaaS-Anbieter (Platform as a Service), die Host Node.js-Anwendungen verwenden, verwenden UTC als Standardzeitzone.

Datum Zeit Bibliotheken

Moment.js

Moment.js ist eine sehr beliebte Bibliothek, die beim Umgang mit Datumsangaben in JavaScript hilft, und unterstützt mehr Formate als ECMAScript angibt . Darüber hinaus unterstützt Moment.js auch Erstellen von Datumsobjekten basierend auf einer Zeichenfolge und einem beliebigen Format .

Luxon

Luxon unterstützt Parsing von ISO 8601, HTTP, RFC2822, SQL und beliebigen Formaten. Verwenden Sie jedoch nur unterschiedliche Funktionen für unterschiedliche Datums- und Uhrzeitformate.

Änderungen an den ECMAScript-Spezifikationen

Eine Liste bemerkenswerter Änderungen in den ECMAScript-Spezifikationen in Bezug auf Datums- und Uhrzeitzeichenfolgenformate.

Änderungen in ES2018

Führt eine Spezifikation für die Datumsformate ein, die von Date.prototype.toString() und Date.prototype.toUTCString() zurückgegeben werden.

Änderungen in ES2017

Keine nennenswerten Änderungen.

Änderungen in ES2016

Fehlt der Zeitzonenversatz, wird die Datums- und Uhrzeitangabe als Ortszeit interpretiert.

Wenn der Zeitzonenoffset fehlt, werden Datumsformulare als UTC-Zeit und Datumsformulare als Ortszeit interpretiert.

Änderungen in ES6 (ES2015)

Der Wert eines Zeitzonenversatzes bei Abwesenheit ist “Z”.

Fehlt der Zeitzonenversatz, wird die Datums- und Uhrzeitangabe als Ortszeit interpretiert.

Von Korrekturen und Erläuterungen in ECMAScript 2015 mit möglichen Auswirkungen auf die Kompatibilität :

Wenn kein Zeitzonenoffset vorhanden ist, wird die lokale Zeitzone verwendet. In Edition 5.1 wurde fälschlicherweise angegeben, dass eine fehlende Zeitzone als "z" interpretiert werden soll.

Weitere Informationen zu dieser Änderung finden Sie unter Date Time String Format: Standard-Zeitzonenunterschied zu ES5, nicht webfähig .

Änderungen in ES5.1

Wenn die Felder MM oder DD fehlen, wird “01” als Wert verwendet. Wenn die Felder HH, mm oder ss nicht vorhanden sind, wird “00” als Wert und der Wert eines fehlenden sss verwendet. Das Feld ist “000”. Der Wert eines Zeitzonenversatzes bei Abwesenheit ist “Z”.

Änderungen in ES5

Erste Einführung eines Datum-Uhrzeit-Zeichenfolgeformats in die ECMAScript-Spezifikation.

ECMAScript definiert ein Format für den Austausch von Zeichenfolgen für Datums- und Uhrzeitangaben auf der Grundlage einer Vereinfachung des erweiterten ISO 8601-Formats. Das Format ist wie folgt: YYYY-MM-DDTHH:mm:ss.sssZ

Führt auch Date.prototype.toISOString() ein, das eine Datums-/Uhrzeitzeichenfolge im angegebenen Format zurückgibt.

Änderungen in ES3

Veraltet Date.prototype.toGMTString() und ersetzt es durch Date.parse(x.toUTCString()) in dem Abschnitt, in dem erwähnt wird, dass das von diesen Methoden zurückgegebene Format durch Implementierungen von Date.parse korrekt analysiert werden muss. Beachten Sie, dass das von Date.parse(x.toUTCString()) zurückgegebene Format "implementierungsabhängig" ist.

Änderungen in ES2

Keine nennenswerten Änderungen.

Anfangsspezifikation: ES1

ES1 führte Datums- und Uhrzeitzeichenfolgen ein, die in new Date(value) und Date.parse(value) verwendet werden. Es wurde jedoch kein tatsächliches Datums- (Uhrzeit-) Format angegeben, es wird sogar angegeben, dass

[...] der von Date.parse erzeugte Wert ist implementierungsabhängig [...]

Die Spezifikation erwähnt dies auch

Wenn x ein Datumsobjekt ist, [...] sollten alle folgenden Ausdrücke in dieser Implementierung den gleichen numerischen Wert erzeugen:

  • [...]
  • Date.parse(x.toString())
  • Date.parse(x.toGMTString())

Der zurückgegebene Wert von Date.prototype.toString() und Date.prototype.toGMTString() wurde jedoch als "implementierungsabhängig" angegeben.

22
str

Welche Datumszeitformate sollte ich verwenden?

Die allgemeine Empfehlung ist, den integrierten Parser überhaupt nicht zu verwenden, da er unzuverlässig ist. Die Antwort auf "sollte" lautet "none". Siehe Warum gibt Date.parse falsche Ergebnisse aus?

Wie str sagt, können Sie jedoch wahrscheinlich das in ECMA-262 angegebene Format mit einer Zeitzone verwenden: YYYY-MM-DDTHH:mm:ss.sssZ oder YYYY-MM-DDTHH:mm:ss.sss±HH:mm, vertrauen Sie keinem anderen Format.

Unterstützen alle Browser dieselben Formate?

Nein.

Wie handhaben Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge und Apple Safari Datums-Zeichenfolgen?

Anders. Alles andere als das Format in ECMA-262 ist von der Implementierung abhängig. Beim Parsen des ECMA-262-Formats gibt es Fehler.

Was ist mit Node.js?

Wahrscheinlich wieder anders, siehe oben.

Berücksichtigt es das lokale Datumsformat? Z.B. Wenn ich in der Schweiz wohne und das Datumsformat 30.07.2018 ist, kann ich das neue Datum ('30 .07.2018 ') verwenden?

Könnte sein. Da es sich nicht um das Standardformat handelt, ist das Parsen von der Implementierung abhängig, daher möglicherweise nicht.

Berücksichtigt es die lokale Zeitzone?

Es verwendet den Host-Zeitzonen-Offset, bei dem die Zeichenfolge als lokal analysiert wird, und um die unter Verwendung der Ortszeiten angezeigte Zeichenfolge zu generieren. Ansonsten wird UTC verwendet (und der interne Zeitwert ist UTC).

Wie kann ich eine Datumszeitzeichenfolge von einem Datumsobjekt erhalten?

Date.parse.toString oder siehe Wo finde ich Dokumentation zum Formatieren eines Datums in JavaScript?

Wie kann ich ungültige Datumszeitzeichenfolgen erkennen?

Eine der ersten 3 Antworten hier sollte das beantworten.

Wie behandeln Datumsbibliotheken wie Moment.js Datumszeichenfolgen?

Sie analysieren sie entweder anhand eines Standardformats oder eines bereitgestellten Formats. Lesen Sie die Quelle (z. B. fecha.js ist ein einfacher Parser und Formatierer mit gut geschriebenem, leicht verständlichem Code). 

Ein Parser ist nicht schwer zu schreiben, aber der Versuch, das Eingabeformat zu erraten (wie dies bei eingebauten Parsern der Fall ist), ist bei Implementierungen schwierig, unzuverlässig und inkonsistent. Daher muss der Parser das Format angeben, es sei denn, die Eingabezeichenfolge hat das Standardformat des Parsers.

PS

Es gibt Änderungen an den Formaten von Strings, die Implementierungen für die Analyse und Formatierung in ECMAScript 2019 (derzeit in Entwurf) unterstützen müssen. Ich denke jedoch, dass der allgemeine Rat, den eingebauten Parser zu vermeiden, noch einige Zeit bestehen wird.

1
RobG