406 Stimmen

Warum liefert Date.parse falsche Ergebnisse?

Fall eins:

new Date(Date.parse("Jul 8, 2005"));

Sortie :

Fri Jul 08 2005 00:00:00 GMT-0700 (PST)

Fall 2:

new Date(Date.parse("2005-07-08"));

Sortie :

Thu Jul 07 2005 17:00:00 GMT-0700 (PST)


Warum ist das zweite Parsing falsch?

5voto

peller Punkte 4435

Während CMS ist korrekt dass die Übergabe von Zeichenketten an die Parse-Methode generell unsicher ist, ist die neue ECMA-262 5. Auflage (auch bekannt als ES5) Spezifikation in Abschnitt 15.9.4.2 schlägt vor, dass Date.parse() sollte eigentlich ISO-formatierte Daten verarbeiten. In der alten Spezifikation war das nicht der Fall. Natürlich bieten alte und einige aktuelle Browser diese ES5-Funktionalität immer noch nicht.

Ihr zweites Beispiel ist nicht falsch. Es ist das angegebene Datum in UTC, wie durch Date.prototype.toISOString() , wird aber in Ihrer lokalen Zeitzone dargestellt.

5voto

Juan Lanus Punkte 2185

Nach Angaben von http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html das Format "jjjj/mm/tt" löst die üblichen Probleme. Er sagt: "Halten Sie sich, wann immer möglich, an "JJJJ/MM/TT" für Ihre Datumsangaben. Es wird von allen unterstützt und ist eindeutig. Mit diesem Format sind alle Zeiten lokal." Ich habe Tests durchgeführt: http://jsfiddle.net/jlanus/ND2Qg/432/ Dieses Format: + vermeidet die Mehrdeutigkeit der Reihenfolge von Tag und Monat durch Verwendung der Reihenfolge y m d und einer 4-stelligen Jahreszahl + vermeidet durch die Verwendung von Schrägstrichen das Problem zwischen UTC und lokalem Format, das nicht mit dem ISO-Format übereinstimmt + danvk, der dygraphs sagt, dass dieses Format in allen Browsern gut ist.

3voto

Lorenz Lo Sauer Punkte 22044

Hier ist ein kurzes, flexibles Snippet zur Konvertierung einer datetime-string in einer cross-browser-sicheren Art und Weise, 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 denselben Zeitstempel liefern wie Date.parse mit:

(new Date(tstring)).getTime()

2voto

Nux Punkte 7922

Diese leichtgewichtige Bibliothek zur Datumsauswertung sollte alle ähnlichen Probleme lösen. Ich mag die Bibliothek, weil sie recht einfach zu erweitern ist. Es ist auch möglich, i18n es (nicht sehr geradlinig, aber nicht so schwer).

Parsing-Beispiel:

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

Und Formatierung zurück zu String (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") );

2voto

DJDaveMark Punkte 2193

Beides ist richtig, aber sie werden als Daten mit zwei verschiedenen Zeitzonen interpretiert. Sie haben also Äpfel mit Birnen 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 die Date.parse() Aufruf, da er automatisch für ein String-Argument verwendet wird. Ich habe auch die Daten verglichen, indem ich ISO8601-Format damit Sie die Daten zwischen Ihren lokalen Daten und den UTC-Daten visuell vergleichen können. Die Zeiten liegen 7 Stunden auseinander. Das ist der Unterschied zwischen den Zeitzonen und der Grund, warum bei Ihren Tests zwei verschiedene Daten angezeigt wurden.

Die andere Möglichkeit, die gleichen 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"

Aber ich empfehle trotzdem dringend Moment.js was soviel heißt wie einfach aber wirkungsvoll :

// 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"

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X