Warum liefert Date.parse falsche Ergebnisse?

344

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?

user121196
quelle
30
Die zweite Analyse ist per se nicht falsch, sondern nur, dass die erste in Ortszeit und die zweite in UTC analysiert wird. Beachten Sie, dass "Do 07.07.2005 17:00:00 GMT-0700 (PST)" mit "2005-07-08 00:00" identisch ist.
Jches
18
ISO 8601 xkcd.
Ulidtko
1
Falls jemand hierher gekommen ist, um herauszufinden, warum ein Datum NaNin 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.
Jazzy
Um Jasons Kommentar oben zu ergänzen: Wenn Sie in Firefox eine NaN erhalten, könnte ein weiteres Problem darin bestehen, dass Firefox und Safari keine getrennten Daten mögen. Nur Chrome. Verwenden Sie stattdessen einen Schrägstrich.
Bangkokian

Antworten:

451

Bis zur Veröffentlichung der Spezifikation für die 5. Ausgabe war die Date.parseMethode vollständig implementierungsabhängig ( new Date(string)entspricht der Date.parse(string)Ausnahme, dass letztere eine Zahl anstelle von a zurückgibt Date). 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, was Date.parse/ new Date(string)sollte akzeptieren, außer dass sie irgendeine Date#toStringAusgabe akzeptieren mussten (ohne zu sagen, was das war).

Ab ECMAScript 2017 (Ausgabe 8) mussten Implementierungen ihre Ausgabe für Date#toStringund analysieren Date#toUTCString, das Format dieser Zeichenfolgen wurde jedoch nicht angegeben.

Ab ECMAScript 2019 (Ausgabe 9) wurde das Format für Date#toStringund Date#toUTCStringwie folgt angegeben:

  1. TTM MMM TT JJJJ HH:
    MM: SS ZZ [(Zeitzonenname)] zB Di 10.07.2018 18:39:58 GMT + 0530 (IST)
  2. TTT, TT MMM JJJJ HH: mm: ss Z,
    z. Di 10 Jul 2018 13:09:58 GMT

Bereitstellung von zwei weiteren Formaten, Date.parsedie 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:

// parse a date in yyyy-mm-dd format
function parseDate(input) {

  let parts = input.split('-');

  // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
  return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}
CMS
quelle
Ausgezeichnet, ich musste dies verwenden, da Date.parseich mich aus irgendeinem Grund nicht mit britischen Datumsformaten verhielt , die ich nicht trainieren konnte
Ben
1
Zeitteile werden im @ CMS-Code dokumentiert. Ich habe diesen Code mit dem Datumsformat "2012-01-31 12:00:00" verwendet. return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);Funktioniert perfekt, danke!
Richard Rout
1
@CMS was meinst du mit implementierungsabhängig ?
Royi Namir
3
@RoyiNamir bedeutet, dass die Ergebnisse davon abhängen, welcher Webbrowser (oder eine andere JavaScript-Implementierung) Ihren Code ausführt.
Samuel Edwin Ward
1
Ich hatte auch Probleme mit dem neuen Datum (Zeichenfolge) in verschiedenen Browsern, die sich unterschiedlich verhalten. Es geht nicht einmal darum, dass es in alten IE-Versionen kaputt geht, die verschiedenen Browser sind einfach nicht konsistent. Verwenden Sie niemals Date.parse oder neues Datum (Zeichenfolge).
Hoffmann
195

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:

Date.parse('1/1/1970'); // 1 January, 1970

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 :

Date.parse('1970-01-01T00:00:00Z');       // Chrome: 0         FF: 0
Date.parse('1970-01-01T00:00:00-0500');   // Chrome: 18000000  FF: 18000000
Date.parse('1970-01-01T00:00:00');        // Chrome: 0         FF: 18000000
  • Im ersten Fall zeigt der "Z" -Spezifizierer an, dass sich die Eingabe in UTC-Zeit befindet, also nicht von der Epoche versetzt ist und das Ergebnis 0 ist
  • Im zweiten Fall gibt der Bezeichner "-0500" an, dass sich die Eingabe in GMT-05: 00 befindet und beide Browser die Eingabe als in der Zeitzone -05: 00 interpretierend interpretieren. Dies bedeutet, dass der UTC-Wert von der Epoche versetzt ist, was bedeutet, dass dem internen Zeitwert des Datums 18000000 ms hinzugefügt werden.
  • Der dritte Fall, in dem kein Spezifizierer vorhanden ist, sollte für das Hostsystem als lokal behandelt werden. FF behandelt die Eingabe korrekt als Ortszeit, während Chrome sie als UTC behandelt, wodurch unterschiedliche Zeitwerte erzeugt werden. Für mich ergibt sich ein Unterschied von 5 Stunden im gespeicherten Wert, was problematisch ist. Andere Systeme mit unterschiedlichen Offsets erzielen unterschiedliche Ergebnisse.

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.

Date.parse('1970-01-01T00:00:00');       // 18000000
Date.parse('1970-01-01');                // 0

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:

console.log(new Date(Date.parse("Jul 8, 2005")).toString()); // Local
console.log(new Date(Date.parse("2005-07-08")).toString());  // UTC

Das macht:

console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());

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):

console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());

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:

console.log(Date.parse("1/1/1970"));
console.log(Date.parse("1/1/1970 12:00:00 AM"));
console.log(Date.parse("Thu Jan 01 1970"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));

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:

let m = moment('1/1/1970', 'M/D/YYYY'); 

Die Ausgangsseite

Auf der Ausgabeseite übersetzen alle Browser Zeitzonen auf dieselbe Weise, behandeln die Zeichenfolgenformate jedoch unterschiedlich. Hier sind die toStringFunktionen und was sie ausgeben. Beachten Sie die toUTCStringund toISOStringFunktionen, 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

 - toString
 - toDateString
 - toTimeString
 - toLocaleString
 - toLocaleDateString
 - toLocaleTimeString

Druckt die gespeicherte UTC-Zeit direkt

 - toUTCString
 - toISOString 

In Chrome
toString            Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString        Thu Jan 01 1970
toTimeString        00:00:00 GMT-05:00 (Eastern Standard Time)
toLocaleString      1/1/1970 12:00:00 AM
toLocaleDateString  1/1/1970
toLocaleTimeString  00:00:00 AM

toUTCString         Thu, 01 Jan 1970 05:00:00 GMT
toISOString         1970-01-01T05:00:00.000Z

In Firefox
toString            Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString        Thu Jan 01 1970
toTimeString        00:00:00 GMT-0500 (Eastern Standard Time)
toLocaleString      Thursday, January 01, 1970 12:00:00 AM
toLocaleDateString  Thursday, January 01, 1970
toLocaleTimeString  12:00:00 AM

toUTCString         Thu, 01 Jan 1970 05:00:00 GMT
toISOString         1970-01-01T05:00:00.000Z

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:

  "12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"

Ich hoffe diese Antwort war hilfreich.

drankin2112
quelle
3
Zunächst einmal als fantastische Zusammenfassung. Ich wollte jedoch auf eine Abhängigkeit hinweisen. In Bezug auf Zeitzonenspezifizierer haben Sie Folgendes angegeben: "Das Fehlen eines Spezifizierers sollte eine lokale Zeiteingabe voraussetzen." Glücklicherweise beseitigt der ECMA-262-Standard jegliche Vermutung. Darin heißt es : "Der Wert eines fehlenden Zeitzonenversatzes ist" Z "." Daher wird angenommen, dass eine Datums- / Zeitzeichenfolge ohne Angabe einer Zeitzone eher eine UTC als eine Ortszeit ist. Natürlich scheint es, wie bei so vielen JavaScript-Dingen, wenig Übereinstimmung zwischen den Implementierungen zu geben.
Daniel
2
... einschließlich der am häufigsten verwendeten Formate '1/1/1970' und '1/1/1970 00:00:00 AM'. - wo am häufigsten verwendet ? Das ist sicher nicht in meinem Land.
Ulidtko
2
@ulidtko - Entschuldigung, ich bin in den USA. Wow ... du bist genau dort in Kiew. Ich hoffe, dass Sie und Ihre Familie in Sicherheit bleiben und sich die Dinge dort bald stabilisieren. Pass auf dich auf und viel Glück bei allem.
drankin2112
Nur eine Anmerkung hier. Es scheint, dass dies für Safari-Browser (dh iOS oder OSX) nicht funktioniert. Das oder ich habe ein anderes Problem.
Keyneom
1
@ Daniel - Glücklicherweise haben die ECMAScript-Autoren ihren Fehler in Bezug auf die fehlende Zeitzone für Datums- und Zeitdarstellungen behoben. Jetzt verwenden Datums- und Zeitzeichenfolgen ohne Zeitzone den Host-Zeitzonenversatz (dh "lokal"). Verwirrenderweise werden Formulare nur mit ISO 8601-Datum als UTC behandelt (obwohl dies aus der Spezifikation nicht besonders klar hervorgeht), während ISO 8601 sie als lokal behandelt, sodass nicht alles behoben wurde.
RobG
70

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.

danvk
quelle
3
" Wenn ein Browser ein Datum als ISO-8601 interpretieren kann, wird dies in der Regel nicht unterstützt." "2020-03-20 13:30:30" wird von vielen Browsern als ISO 8601 und lokal behandelt, von Safari jedoch als ungültiges Datum. Es gibt viele ISO 8601-Formate, die von den meisten Browsern nicht unterstützt werden, z. B. 2004-W53-7 und 2020-092.
RobG
7

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:

    mydate='01.02.12 10:20:43':
    myformat='dd/mm/yy HH:MM:ss';


    dtsplit=mydate.split(/[\/ .:]/);
    dfsplit=myformat.split(/[\/ .:]/);

    // creates assoc array for date
    df = new Array();
    for(dc=0;dc<6;dc++) {
            df[dfsplit[dc]]=dtsplit[dc];
            }

    // uses assc array for standard mysql format
    dstring[r] = '20'+df['yy']+'-'+df['mm']+'-'+df['dd'];
    dstring[r] += ' '+df['HH']+':'+df['MM']+':'+df['ss'];
Guido Rizzi
quelle
5

Verwenden Sie moment.js , um Daten zu analysieren:

var caseOne = moment("Jul 8, 2005", "MMM D, YYYY", true).toDate();
var caseTwo = moment("2005-07-08", "YYYY-MM-DD", true).toDate();

Das dritte Argument bestimmt das strikte Parsen (verfügbar ab 2.3.0). Ohne es kann moment.js auch falsche Ergebnisse liefern.

Lukasz Wiktor
quelle
4

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.

Juan Lanus
quelle
Vielleicht möchten Sie die Antwort des Autors sehen .
Brad Koch
Ich würde sagen, dass die Lösung mit dem Beispiel in jsFiddle gut genug funktioniert, wenn Sie jQuery verwenden, da es den Datepicker-Parser verwendet. In meinem Fall liegt das Problem bei jqGrid, es wurde jedoch die parseDate-Methode gefunden. Aber trotzdem hat mir das Beispiel geholfen, indem es mir eine Idee gegeben hat, also +1 dafür, danke.
Vasil Popov
2
Dieser Artikel über Dygraphs ist falsch und das erste Beispiel auf der Seite zeigt deutlich, warum die Verwendung von Schrägstrichen anstelle von Bindestrichen wirklich ein schlechter Rat ist. Zum Zeitpunkt der Erstellung des Artikels führte die Verwendung von "2012/03/13" dazu, dass der Browser ihn anstelle von UTC als lokales Datum analysierte. Die ECMAScript-Spezifikation definiert die explizite Unterstützung für die Verwendung von "JJJJ-MM-TT" (ISO8601). Verwenden Sie daher immer Bindestriche. Es sollte beachtet werden, dass Chrome zum Zeitpunkt des Schreibens dieses Kommentars gepatcht wurde, um Schrägstriche als UTC zu behandeln.
Lachlan Hunt
4

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.

Peller
quelle
1
Das Parsen von Datumszeichenfolgen wurde in ECMAScript 2015 erneut geändert, sodass "2005-07-08" lokal und nicht UTC ist. Übrigens war ES5 bis Juni 2011 nicht der Standard (und derzeit ist ECMAScript 2015). ;-)
RobG
1
Um die Dinge zu verwirren, entschied TC39 im Oktober (nur einen Monat nach meinem vorherigen Beitrag), dass "2005-07-08" UTC sein sollte , "" 2005-07-08T00: 00: 00 "jedoch lokal sein sollte. Beide sind ISO 8601 konforme Formate, beide sind ohne Zeitzone, werden aber unterschiedlich behandelt. Go figure.
RobG
2

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:

var caseOne = Date.parseDate("Jul 8, 2005", "M d, Y");
var caseTwo = Date.parseDate("2005-07-08", "Y-m-d");

Und Formatierung zurück in Zeichenfolge (Sie werden feststellen, dass beide Fälle genau das gleiche Ergebnis liefern):

console.log( caseOne.dateFormat("M d, Y") );
console.log( caseTwo.dateFormat("M d, Y") );
console.log( caseOne.dateFormat("Y-m-d") );
console.log( caseTwo.dateFormat("Y-m-d") );
Nux
quelle
2

Hier ist ein kurzes, flexibles Snippet, mit dem Sie eine datetime-Zeichenfolge browserübergreifend konvertieren können, wie von @ drankin2112 beschrieben.

var inputTimestamp = "2014-04-29 13:00:15"; //example

var partsTimestamp = inputTimestamp.split(/[ \/:-]/g);
if(partsTimestamp.length < 6) {
    partsTimestamp = partsTimestamp.concat(['00', '00', '00'].slice(0, 6 - partsTimestamp.length));
}
//if your string-format is something like '7/02/2014'...
//use: var tstring = partsTimestamp.slice(0, 3).reverse().join('-');
var tstring = partsTimestamp.slice(0, 3).join('-');
tstring += 'T' + partsTimestamp.slice(3).join(':') + 'Z'; //configure as needed
var timestamp = Date.parse(tstring);

Ihr Browser sollte das gleiche Zeitstempelergebnis liefern wie Date.parse:

(new Date(tstring)).getTime()
Lorenz Lo Sauer
quelle
Ich würde vorschlagen, T zur Regex hinzuzufügen, um auch bereits JS-formatierte Daten abzufangen: inputTimestamp.split (/ [T \ /: -] / g)
andig
Wenn Sie die Zeichenfolge in Komponenten aufteilen, besteht der zuverlässigste nächste Schritt darin, diese Teile als Argumente für den Date-Konstruktor zu verwenden. Wenn Sie eine weitere Zeichenfolge für den Parser erstellen, kehren Sie zu Schritt 1 zurück. "2014-04-29 13:00:15" sollte als lokal analysiert werden. Ihr Code formatiert sie als UTC neu. :-(
RobG
2

Beide sind korrekt, werden jedoch als Datumsangaben mit zwei unterschiedlichen Zeitzonen interpretiert. Sie haben also Äpfel und Orangen verglichen:

// local dates
new Date("Jul 8, 2005").toISOString()            // "2005-07-08T07:00:00.000Z"
new Date("2005-07-08T00:00-07:00").toISOString() // "2005-07-08T07:00:00.000Z"
// UTC dates
new Date("Jul 8, 2005 UTC").toISOString()        // "2005-07-08T00:00:00.000Z"
new Date("2005-07-08").toISOString()             // "2005-07-08T00:00:00.000Z"

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:

new Date(2005, 7-1, 8)           // "2005-07-08T07:00:00.000Z"
new Date(Date.UTC(2005, 7-1, 8)) // "2005-07-08T00:00:00.000Z"

Trotzdem empfehle ich Moment.js, das so einfach und doch so mächtig ist :

// parse string
moment("2005-07-08").format()       // "2005-07-08T00:00:00+02:00"
moment.utc("2005-07-08").format()   // "2005-07-08T00:00:00Z"
// year, month, day, etc.
moment([2005, 7-1, 8]).format()     // "2005-07-08T00:00:00+02:00"
moment.utc([2005, 7-1, 8]).format() // "2005-07-08T00:00:00Z"
DJDaveMark
quelle
0

Die akzeptierte Antwort von CMS ist korrekt. Ich habe gerade einige Funktionen hinzugefügt:

  • Eingaberäume kürzen und reinigen
  • Analysieren Sie Schrägstriche, Bindestriche, Doppelpunkte und Leerzeichen
  • hat Standardtag und -zeit

// parse a date time that can contains spaces, dashes, slashes, colons
function parseDate(input) {
    // trimes and remove multiple spaces and split by expected characters
    var parts = input.trim().replace(/ +(?= )/g,'').split(/[\s-\/:]/)
    // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
    return new Date(parts[0], parts[1]-1, parts[2] || 1, parts[3] || 0, parts[4] || 0, parts[5] || 0); // Note: months are 0-based
}
Stephane L.
quelle