2017-03-14 1 views
1

Ich habe eine zwei Stränge 2017-03-15 (date) und 12:26 (time). Ich möchte ein lokalisiertes Datumsobjekt daraus erstellen, ohne eine Bibliothek zu verwenden.Create date from string

Daran erinnernd, dass hier jetzt ist: Tue Mar 14 2017 12:26:33 GMT+0800 (AWST), wenn ich es tue:

new Date(date + 'T' + time) 

ich das falsche Ergebnis wie das Datum UTC gilt:

Wed Mar 15 2017 20:26:00 GMT+0800 (AWST) 

Wenn ich einen Raum nutzen:

new Date(date + ' ' + time) 

Das Ergebnis ist korrekt:

Wed Mar 15 2017 12:26:00 GMT+0800 (AWST) 

Dies funktioniert jedoch NICHT mit Safari (nicht ohne T). Safari wird tatsächlich einen Fehler (!) Auslösen.

Ich weiß, dass das Parsen von Strings als Datum von der Implementierung abhängt. Also, der einzige Weg, es "richtig" zu tun wäre:

var timeSplit = time.split(':'); 
var dateSplit = date.split('-'); 

new Date(dateSplit[0], dateSplit[1] - 1, dateSplit[2], timeSplit[ 0 ], timeSplit[ 1 ]) 

Aber es ist nur. Damit. Hässlich. Gibt es eine bessere Lösung, die für alle Browser funktioniert?

+1

Nicht so hässlich. Stell es einfach in eine Funktion und du bist gut zu gehen. – Ryan

+1

Mögliche dupe - [__Ungültiges Datum in Safari__] (http://stackoverflow.com/questions/4310953/invalid-date-in-safari) – Rayon

Antwort

2

ich das falsche Ergebnis als das Datum UTC gilt:

, die tatsächlich ein Fehler in der ES5-Spezifikation war, die in ES2015 des spec korrigiert wurde; Aber leider haben wir jetzt eine Mischung von JavaScript-Engines, die das alte ES5-Verhalten verwenden (was im Widerspruch zu ISO-8601 standard steht, für das es eine Untermenge sein sollte) und dem (korrekten) ES2015/ISO-8601-Verhalten. Während ich dies schreibe, verwendet Chrome beispielsweise das ES5-Verhalten (bug report here) und Firefox das ES2015-Verhalten.

Es sollte behandeln eine Datums-/Uhrzeitzeichenfolge ohne Zeitzone Specifier als lokale Zeit. Und vielleicht wird es irgendwann, zuverlässig, Cross-Browser. :-)

Aber warten, es wird schlimmer: Die ES2016-Spezifikation aktualisiert Dinge weiter zu sagen, dass eine Datum-Zeichenfolge ohne Zeitzone (zB "2017-03-14") in UTC interpretiert werden sollte, obwohl eine Datum/Uhrzeit-Zeichenfolge ohne eins (zB "2017-03-14T06:19") ist Ortszeit. Warum? Da die meisten Browser dies bereits seit Jahren mit den "implementierungsspezifischen Heuristiken oder implementierungsspezifischen Datumsformaten" machen, können sie nach Spezifikation auf zurückgreifen. Die Änderung hätte einen großen Teil des Codes zerstört, daher mussten sie diese spezielle (und nicht ISO-8601) Regel hinzufügen.

Allerdings funktioniert dies nicht auf Safari (nicht ohne das T).

Richtig. Das nur Datum/Uhrzeit-Format, das eine JavaScript-Engine unterstützen muss, ist die ISO-8601-Teilmenge defined here (und auch was auch immer es von toString zurückgibt, aber das ist nicht in der Spezifikation definiert, es muss nur zwei-Wege sein).

Aber es ist nur. Damit. Hässlich.Gibt es eine bessere Lösung, die in allen Browsern funktioniert?

Es ist überhaupt nicht hässlich. Das ist schließlich, was der Date Konstruktor tun muss, um es herauszufinden. Legen Sie es in Ihre Standardbibliothek und Sie können loslegen.

+0

Autsch ... so sollte die Zeit als Ortszeit behandelt werden, aber einige Browser grundsätzlich es falsch verstehen?!? – Merc

+0

@Merc: Hängt von Ihrer Definition von falsch ab. :-) Einige JavaScript-Engines haben das Verhalten nicht an die ES2015-Spezifikation angepasst und verwenden stattdessen weiterhin die ES5-Definition (die fehlerhaft war).Andere verwenden das Verhalten der ES2015 (entweder weil sie es aktualisiert haben oder weil sie sich weigerten, die falsche Definition von ES5 ursprünglich zu implementieren). Ich glaube, Firefox hat es immer so gemacht, wie es früher hieß ein Fehler in der ES5-Spezifikation). –

+0

@ TJCrowder-und das aktuelle Verhalten der Behandlung der ISO-8601-Date-only-Formular als UTC ist inkonsistent mit ISO 8601. ;-) – RobG

2

ich das falsche Ergebnis wie das Datum UTC gilt:

Gegeben:

new Date('2017-03-15T12:26') 

IE 8 behandelt bis zur Version es als eine ungültige Zeichenfolge, IE 9+ es behandelt als UTC. Firefox 38 behandelt es als lokal.

Wenn ich einen Raum nutzen ... Das Ergebnis ist korrekt

Bis Sie Safari versuchen und ein ungültiges Datum.

Allerdings funktioniert dies nicht auf Safari (nicht ohne das T). Safari wird tatsächlich einen Fehler (!) Auslösen.

Ja, und beide Ergebnisse stimmen mit allen Versionen von ECMAScript überein. Safari sagt "Dies ist keine gültige ISO 8601-Zeichenfolge", daher wird ein ungültiges Datum zurückgegeben. Die anderen sagen dasselbe, aber dann greifen sie auf implementierungsspezifische Heuristiken zurück (was ihnen erlaubt ist).

Die untere Zeile ist Strings nicht mit dem Konstruktor Datum (oder Date.parse, sie sind für das Parsen gleichwertig) zu analysieren.

Also, der einzige Weg, es "richtig" zu tun wäre ...

Ja, manuell die Bits Parsen. Sie können eine Bibliothek aus Bequemlichkeit verwenden, aber sie werden genau das gleiche tun.

Gibt es eine bessere Lösung, die über Browser funktioniert?

Nr Fahren Sie auf die ECMA TC39 committee und sie über den Kopf schlagen, bis sie sich entscheiden, ein Date-Objekt zu definieren, die einen anständigen Parser und Formatierer hat. Es gibt viele sehr gute vorhandene Implementierungen zur Auswahl, einschließlich vorhandener Javascript-Bibliotheken und anderer Sprachen.

Leider wurde Parsing praktisch ignoriert und die Verantwortung für die Formatierung wurde an ECMA-402 übergeben, was für die Datumsformatierung sehr üblich ist und wirklich nicht geeignet ist.