2016-12-22 2 views
2

Warum passiert -JavaScript date.setMilliseconds seltsames Verhalten?

var date = new Date('2015-10-24T23:31:04.181Z'); 
date.toISOString(); // "2015-10-24T23:31:04.181Z" 
date.setMilliseconds(date.getMilliseconds() + 1); 
date.toISOString(); // "2015-10-24T22:31:04.182Z" 
  • Die Stunde einen zurück bewegt hat (23 -> 22)
  • Adaequat mit anderen Terminen

Ist es eine Zeitzone Ausgabe ? Warum passiert das nicht bei allen Datumswerten?

Dank

+0

Chrome & Node.js, Meine Zeitzone ist +2, versuche dies: https://jsfiddle.net/eeqo9ke9/1/ – AvnerSo

+0

Ich bin auf Chrome 54.0.2840.100 (64-Bit)/Linux – AvnerSo

+1

Repliziert mit Chrome unter Windows mit Jerusalem als meine Zeitzone. Interessanterweise geht der TZ-Offset nach dem Hinzufügen dieser Millisekunde von -120 auf -180: https://jsfiddle.net/eeqo9ke9/2/ –

Antwort

2

Es ist Sommerzeit, in eine wirklich nicht offensichtlichen Art und Weise. :-)

2015-10-24T23: 31: 04.181Z in Jerusalem ist 25. Oktober 2015 01:31:04 GMT + 0200 (Jerusalem Standard Time) am Datum/Uhrzeit, an dem die Sommerzeit endet und die Uhren zurückgehen (reference). Genauer gesagt, es ist in der Groundhog Hour: Es gibt zwei 01: 31: 04s an diesem Tag, zuerst der eine im Sommer, dann der eine Stunde später in der Standardzeit.

Sie verwenden setMilliseconds, das ist eine Ortszeit Funktion. Wie Sie wahrscheinlich wissen, ist JavaScript Date schlau über die Handhabung von Rollover zwischen Datumsfeldern (obwohl es in diesem speziellen Fall kein Rollover gibt), und so die Logik von setMilliseconds muss für mögliche Rollover zu behandeln. Das ist detailed in the specification, aber im Grunde nimmt es den aktuellen Zeitwert (Millisekunden seit The Epoch), macht ein lokales Datum/Zeit daraus, erledigt die Arbeit und muss dann dieses lokale Datum/Zeit in einen neuen Zeitwert zurückdrehen.

Aber hier ist, wo das Problem beginnt: Diese beiden 01: 31: 04s an diesem Tag. V8 muss bei der Bestimmung des realen Datums/der Uhrzeit eine auswählen. Es wählt die eine im Sommer, die eine Stunde früher als Ihr ursprüngliches Datum/Uhrzeit ist.

Wenn Sie setUTCMilliseconds verwenden, geschieht dies nicht, da es keinen Hin- und Rückweg zur Ortszeit gibt.

Moral der Geschichte: Wenn Sie in UTC arbeiten, arbeiten Sie ausschließlich in UTC. :-)