Fall Eins:
new Date(Date.parse("Jul 8, 2005"));
Ausgabe:
Fri Jul 08 2005 00:00:00 GMT-0700 (PST)
Fall zwei:
new Date(Date.parse("2005-07-08"));
Ausgabe:
Do 07.07.2005 17:00:00 GMT-0700 (PST)
Warum ist die zweite Analyse falsch?
javascript
date
user121196
quelle
quelle
NaN
in Firefox zurückkehrt, habe ich festgestellt, dass die meisten anderen Browser (und Node.js) ein Datum ohne Tag analysieren, z. B. "April 2014" als 1. April 2014, aber Firefox gibt NaN zurück. Sie müssen ein ordnungsgemäßes Datum übergeben.Antworten:
Bis zur Veröffentlichung der Spezifikation für die 5. Ausgabe war die
Date.parse
Methode vollständig implementierungsabhängig (new Date(string)
entspricht derDate.parse(string)
Ausnahme, dass letztere eine Zahl anstelle von a zurückgibtDate
). In der Spezifikation der 5. Ausgabe wurde die Anforderung hinzugefügt, eine vereinfachte (und leicht falsche) ISO-8601 zu unterstützen (siehe auch Was sind gültige Datums- / Zeitzeichenfolgen in JavaScript? ). Aber anders als das gab es keine Anforderung für das, wasDate.parse
/new Date(string)
sollte akzeptieren, außer dass sie irgendeineDate#toString
Ausgabe akzeptieren mussten (ohne zu sagen, was das war).Ab ECMAScript 2017 (Ausgabe 8) mussten Implementierungen ihre Ausgabe für
Date#toString
und analysierenDate#toUTCString
, das Format dieser Zeichenfolgen wurde jedoch nicht angegeben.Ab ECMAScript 2019 (Ausgabe 9) wurde das Format für
Date#toString
undDate#toUTCString
wie folgt angegeben:MM: SS ZZ [(Zeitzonenname)] zB Di 10.07.2018 18:39:58 GMT + 0530 (IST)
z. Di 10 Jul 2018 13:09:58 GMT
Bereitstellung von zwei weiteren Formaten,
Date.parse
die in neuen Implementierungen zuverlässig analysiert werden sollten (unter Hinweis darauf, dass die Unterstützung nicht allgegenwärtig ist und nicht konforme Implementierungen noch einige Zeit verwendet werden).Ich würde empfehlen, Datumszeichenfolgen manuell zu analysieren und den Datumskonstruktor mit Argumenten für Jahr, Monat und Tag zu verwenden, um Mehrdeutigkeiten zu vermeiden:
quelle
Date.parse
ich mich aus irgendeinem Grund nicht mit britischen Datumsformaten verhielt , die ich nicht trainieren konntereturn new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
Funktioniert perfekt, danke!Während meiner jüngsten Erfahrung beim Schreiben eines JS-Dolmetschers habe ich mich intensiv mit dem Innenleben von ECMA / JS-Daten auseinandergesetzt. Also werde ich hier meine 2 Cent einwerfen. Hoffentlich hilft das Teilen dieses Materials anderen bei Fragen zu den Unterschieden zwischen Browsern im Umgang mit Datumsangaben.
Die Eingangsseite
Alle Implementierungen speichern ihre Datumswerte intern als 64-Bit-Zahlen, die die Anzahl der Millisekunden (ms) seit 1970-01-01 UTC darstellen (GMT ist dasselbe wie UTC). Dieses Datum ist die ECMAScript-Epoche, die auch von anderen Sprachen wie Java und POSIX-Systemen wie UNIX verwendet wird. Daten, die nach der Epoche auftreten, sind positive Zahlen und Daten vor der Epoche sind negativ.
Der folgende Code wird in allen aktuellen Browsern als dasselbe Datum interpretiert, jedoch mit dem lokalen Zeitzonenversatz:
In meiner Zeitzone (EST, -05: 00) ist das Ergebnis 18000000, da so viele ms in 5 Stunden sind (in den Sommermonaten sind es nur 4 Stunden). Der Wert ist in verschiedenen Zeitzonen unterschiedlich. Dieses Verhalten wird in ECMA-262 angegeben, sodass alle Browser es auf die gleiche Weise tun.
Zwar gibt es einige Abweichungen bei den Eingabezeichenfolgenformaten, die von den wichtigsten Browsern als Datumsangaben analysiert werden, sie interpretieren sie jedoch im Wesentlichen in Bezug auf Zeitzonen und Sommerzeit gleich, obwohl die Analyse weitgehend von der Implementierung abhängt.
Das ISO 8601-Format unterscheidet sich jedoch. Dies ist eines von nur zwei in ECMAScript 2015 (ed 6) beschriebenen Formaten, die von allen Implementierungen auf die gleiche Weise analysiert werden müssen (das andere ist das für Date.prototype.toString angegebene Format ).
Aber selbst für Zeichenfolgen im ISO 8601-Format ist bei einigen Implementierungen ein Fehler aufgetreten. Hier ist eine Vergleichsausgabe von Chrome und Firefox, als diese Antwort ursprünglich für den 1.1.1970 (die Epoche) auf meinem Computer mit Zeichenfolgen im ISO 8601-Format geschrieben wurde, die in allen Implementierungen auf genau denselben Wert analysiert werden sollten :
Dieser Unterschied wurde ab 2020 behoben, aber beim Parsen von Zeichenfolgen im ISO 8601-Format bestehen zwischen den Browsern andere Besonderheiten.
Aber es wird schlimmer. Eine Besonderheit von ECMA-262 ist, dass das Nur-Datum-Format nach ISO 8601 (JJJJ-MM-TT) als UTC analysiert werden muss, während es nach ISO 8601 als lokal analysiert werden muss. Hier ist die Ausgabe von FF mit den langen und kurzen ISO-Datumsformaten ohne Zeitzonenspezifizierer.
Der erste wird als lokal analysiert, da es sich um Datum und Uhrzeit nach ISO 8601 ohne Zeitzone handelt, und der zweite wird als UTC analysiert, da es sich nur um das Datum nach ISO 8601 handelt.
Um die ursprüngliche Frage direkt zu beantworten,
"YYYY-MM-DD"
muss ECMA-262 als UTC interpretiert werden, während die andere als lokal interpretiert wird. Deshalb:Dies führt nicht zu gleichwertigen Ergebnissen:
Das macht:
Unter dem Strich werden Datumszeichenfolgen analysiert. Die EINZIGE ISO 8601-Zeichenfolge, die Sie sicher über Browser hinweg analysieren können, ist die lange Form mit einem Versatz (entweder ± HH: mm oder "Z"). Wenn Sie dies tun, können Sie sicher zwischen lokaler und UTC-Zeit hin und her gehen.
Dies funktioniert in allen Browsern (nach IE9):
Die meisten aktuellen Browser behandeln die anderen Eingabeformate gleich, einschließlich der häufig verwendeten Formate "01.01.1970" (M / T / JJJJ) und "01.01.1970 00:00:00" (M / T / JJJJ hh) : mm: ss ap) Formate. Alle folgenden Formate (mit Ausnahme des letzten) werden in allen Browsern als Ortszeiteingabe behandelt. Die Ausgabe dieses Codes ist in allen Browsern in meiner Zeitzone gleich. Der letzte wird unabhängig von der Host-Zeitzone als -05: 00 behandelt, da der Offset im Zeitstempel festgelegt ist:
Da das Parsen selbst der in ECMA-262 angegebenen Formate nicht konsistent ist, wird empfohlen, sich niemals auf den integrierten Parser zu verlassen und Zeichenfolgen immer manuell zu analysieren, z. B. mithilfe einer Bibliothek, und das Format dem Parser bereitzustellen.
ZB in moment.js könnten Sie schreiben:
Die Ausgangsseite
Auf der Ausgabeseite übersetzen alle Browser Zeitzonen auf dieselbe Weise, behandeln die Zeichenfolgenformate jedoch unterschiedlich. Hier sind die
toString
Funktionen und was sie ausgeben. Beachten Sie dietoUTCString
undtoISOString
Funktionen, die 5:00 Uhr morgens auf meinem Computer ausgegeben werden. Der Zeitzonenname kann auch eine Abkürzung sein und in verschiedenen Implementierungen unterschiedlich sein.Konvertiert vor dem Drucken von UTC in Ortszeit
Druckt die gespeicherte UTC-Zeit direkt
Normalerweise verwende ich das ISO-Format nicht für die Eingabe von Zeichenfolgen. Die Verwendung dieses Formats ist für mich nur dann von Vorteil, wenn Datumsangaben als Zeichenfolgen sortiert werden müssen. Das ISO-Format kann unverändert sortiert werden, die anderen nicht. Wenn Sie browserübergreifend kompatibel sein müssen, geben Sie entweder die Zeitzone an oder verwenden Sie ein kompatibles Zeichenfolgenformat.
Der Code
new Date('12/4/2013').toString()
durchläuft die folgende interne Pseudotransformation:Ich hoffe diese Antwort war hilfreich.
quelle
Der Wahnsinn hat eine Methode. Wenn ein Browser ein Datum als ISO-8601 interpretieren kann, wird dies in der Regel der Fall sein. "2005-07-08" fällt in dieses Lager und wird daher als UTC analysiert. "8. Juli 2005" kann nicht, und so wird es in der Ortszeit analysiert.
Siehe JavaScript und Daten, was für ein Durcheinander! für mehr.
quelle
Eine andere Lösung besteht darin, ein assoziatives Array mit Datumsformat zu erstellen und dann die Daten neu zu formatieren.
Diese Methode ist nützlich für unformatierte Datumsformatierungen.
Ein Beispiel:
quelle
Verwenden Sie moment.js , um Daten zu analysieren:
Das dritte Argument bestimmt das strikte Parsen (verfügbar ab 2.3.0). Ohne es kann moment.js auch falsche Ergebnisse liefern.
quelle
Laut http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html löst das Format "JJJJ / MM / TT" die üblichen Probleme. Er sagt: "Halten Sie sich, wann immer möglich, an" JJJJ / MM / TT "für Ihre Datumszeichenfolgen. Es wird allgemein unterstützt und ist eindeutig. Bei diesem Format sind alle Zeiten lokal." Ich habe Tests festgelegt: http://jsfiddle.net/jlanus/ND2Qg/432/ Dieses Format: + vermeidet die Mehrdeutigkeit der Tages- und Monatsreihenfolge durch Verwendung der ymd-Reihenfolge und ein 4-stelliges Jahr + vermeidet das Problem UTC vs. lokal nicht Die Einhaltung des ISO-Formats durch Verwendung von Schrägstrichen + Danvk, der Dygraphs- Typ, sagt, dass dieses Format in allen Browsern gut ist.
quelle
Während CMS richtig ist, dass das Übergeben von Zeichenfolgen an die Analysemethode im Allgemeinen unsicher ist, schlägt die neue Spezifikation ECMA-262 5th Edition (auch bekannt als ES5) in Abschnitt 15.9.4.2 vor,
Date.parse()
ISO-formatierte Daten tatsächlich zu verarbeiten. Die alte Spezifikation machte keinen solchen Anspruch geltend. Natürlich bieten alte Browser und einige aktuelle Browser diese ES5-Funktionalität immer noch nicht an.Ihr zweites Beispiel ist nicht falsch. Dies ist das in UTC angegebene Datum, wie von impliziert
Date.prototype.toISOString()
, wird jedoch in Ihrer lokalen Zeitzone dargestellt.quelle
Diese leichte Datumsanalysebibliothek sollte alle ähnlichen Probleme lösen. Ich mag die Bibliothek, weil sie ziemlich einfach zu erweitern ist. Es ist auch möglich, es zu tun (nicht sehr einfach, aber nicht so schwer).
Analysebeispiel:
Und Formatierung zurück in Zeichenfolge (Sie werden feststellen, dass beide Fälle genau das gleiche Ergebnis liefern):
quelle
Hier ist ein kurzes, flexibles Snippet, mit dem Sie eine datetime-Zeichenfolge browserübergreifend konvertieren können, wie von @ drankin2112 beschrieben.
Ihr Browser sollte das gleiche Zeitstempelergebnis liefern wie
Date.parse
:quelle
Beide sind korrekt, werden jedoch als Datumsangaben mit zwei unterschiedlichen Zeitzonen interpretiert. Sie haben also Äpfel und Orangen verglichen:
Ich habe den
Date.parse()
Aufruf entfernt , da er automatisch für ein Zeichenfolgenargument verwendet wird. Ich habe die Daten auch im ISO8601-Format verglichen, damit Sie die Daten zwischen Ihren lokalen Daten und den UTC-Daten visuell vergleichen können. Die Zeiten liegen 7 Stunden auseinander. Dies ist der Zeitzonenunterschied und warum Ihre Tests zwei verschiedene Daten zeigten.Die andere Möglichkeit, dieselben lokalen / UTC-Daten zu erstellen, wäre:
Trotzdem empfehle ich Moment.js, das so einfach und doch so mächtig ist :
quelle
Die akzeptierte Antwort von CMS ist korrekt. Ich habe gerade einige Funktionen hinzugefügt:
quelle