Das neue Datum () für den 31. Dezember 2014 lautet stattdessen 1. Dezember

80

Ich versuche, eine Zeichenfolge in ein Datumsobjekt zu konvertieren, und es funktioniert für alle Tage außer für den 31. Dezember, wo nach Objekt der 1. Dezember anstelle des 31. Dezember angezeigt wird. Ich habe keine Idee warum. Hier ist mein JavaScriptCode:

var dt = new Date();
dt.setDate("31");
dt.setMonth("11");
dt.setFullYear("2014");

aber mein variabler Wert ist:

Mon Dec 01 2014 11:48:08 GMT+0100 (Paris, Madrid)

Wenn ich dasselbe für ein anderes Datum mache, kehrt mein Objekt zum entsprechenden Wert zurück. Hast du eine Ahnung, was ich falsch gemacht habe?

user2859409
quelle
7
Sie sollen Ganzzahlen an setMonth usw. übergeben, keine Zeichenfolgen.
Funkybro
15
Sie können die DateParameter des Konstruktors direkt verwenden:new Date(2014, 11, 31)
Pomeh
9
Übrigens. ist nicht der 11. Monat November?
Jnovacho
5
@JuhaUntinen Nein, wird das Datum verwechselt , weil der Monat jetzt nur 30 Tage hat.
Herr Lister

Antworten:

84

setMonth sollte vorher setDate: ( nicht sicher für Monate unter 31 Tagen )

var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11);
dt.setDate(31);

Und setMonth‚s zweiter Parameter könnte auch auf eingestellte Datum verwendet werden.

var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11, 31);


Wenn für den Konstruktor keine Argumente angegeben werden, werden das aktuelle Datum und die aktuelle Uhrzeit gemäß den Systemeinstellungen verwendet.

Die Verwendung von setMonthund setDateseparat würde also immer noch zu unerwarteten Ergebnissen führen.

Wenn die eingestellten Werte größer als ihr logischer Bereich sind , wird der Wert automatisch an den benachbarten Wert angepasst .

Wenn zum Beispiel heute ist 2014-09-30, dann

var dt = new Date();
dt.setFullYear(2014); /* Sep 30 2014 */
dt.setMonth(1);       /* Mar 02 2014, see, here the auto adjustment occurs! */
dt.setDate(28);       /* Mar 28 2014 */

Um dies zu vermeiden, legen Sie die Werte direkt mit dem Konstruktor fest.

var dt = new Date(2014, 11, 31);
xdazz
quelle
1
Ich habe es gerade herausgefunden, aber es macht für mich keinen Sinn
user2859409
15
@ user2859409 Es ist wahrscheinlich, weil, wenn Sie den Monat nicht zuerst einstellen, es den aktuellen Monat dauert und dann manchmal in den nächsten Monat
einbrechen kann
3
Ich würde zögern, diesen ersten Codeblock für Monate mit weniger als 31 Tagen zu empfehlen. Wenn Sie beispielsweise das Datum auf den 15. September einstellen möchten, aber heute der 31. August ist, wird das Datum auf den nächsten Monat verschoben und Sie erhalten den 15. Oktober. +1 für den zweiten Codeblock: das ist der besserer Weg zu gehen. Ich wusste nicht einmal, dass es eine 2-Argument-Form gibt setMonth.
Luke Woodward
10
Beachten Sie, dass das Einstellen des Monats vor dem Tag ebenfalls falsch sein kann. In diesem Fall jedoch nicht. Wenn es der 31. Oktober ist, setzt setMonth (10) das Datum auf den 31. November, der auf den 1. Dezember umgebrochen wird. SetDate (31) führt dann zum 31. Dezember. Verwenden Sie daher immer das 2-Argument setMonth ().
Florian F
1
+1, aber ich möchte betonen, dass die zweimonatige Option bevorzugt wird, um Nebenwirkungen zu vermeiden.
Brian
120

Die Sache ist, wenn Sie einen Tag zuerst einstellen, sind Sie immer noch im aktuellen Monat, also im September. Der September hat nur 30 Tage, also:

var dt = new Date(); /* today */
dt.setDate("31"); /* 1st Oct 2014 as should be by spec */
dt.setMonth("11"); /* 1st Dec 2014 */
dt.setFullYear("2014"); /* 1st Dec 2014 */
Jakub Michálek
quelle
22
+1 - Dies ist die Art von Käfer, der den ganzen August schlummert und dich dann im September in den Hintern beißt;)
Niet the Dark Absol
19
Es ist NIEMALS richtig, ein Datum komponentenweise festzulegen , da es Fehlerfälle mit dem ersten Tag und dem ersten Monat und möglicherweise mit dem ersten Jahr am 29.02. Gibt. Sie müssen alle drei Felder gleichzeitig festlegen.
Jim Garrison
5
+1 und es sollte eine akzeptierte Antwort sein, da es erklärt, WARUM Sie den Monat zuerst einstellen sollten. Es ist ein sehr Javascript WTF
Danubian Sailor
2
Sollte in anderen Sprachen ähnlich sein, also kein "Javascript WTF".
Raidri unterstützt Monica
Warum wird das Date-Objekt nicht ausgelöst, wenn ein falsches Datum festgelegt wurde?
JWW
23

Es ist, weil das erste, was Sie tun, ist

dt.setDate(31)

Hiermit wird das aktuelle Datum auf 31 festgelegt. Der aktuelle Monat ist der September mit 30 Tagen.

Wenn Sie das Datum nach diesem Zeitpunkt ausdrucken würden, würde dies den 1. Oktober bedeuten.

funkybro
quelle
12
Das Lustige ist, dass dies nur aufgetaucht ist, weil er es während eines Monats mit 30 Tagen versucht hat. Einen Monat später und es hätte einfach gut funktioniert.
Peter Remmers
13

Angenommen, Sie möchten Jahr, Monat und Datum gleichzeitig festlegen, können Sie den Konstruktor für das längere Datum verwenden :

neues Datum (Jahr, Monat, Tag, Stunde, Minute, Sekunde, Millisekunde);

[...]

Wenn mindestens zwei Argumente angegeben werden, werden fehlende Argumente entweder auf 1 (wenn der Tag fehlt) oder für alle anderen auf 0 gesetzt.

Sie würden also schreiben:

var dt = new Date(2014, 11, 31);

Wie bereits festgelegt, kann das Festlegen eines Datumsabschnitts zu Überläufen führen:

var dt = new Date(2012, 1, 29); // Feb 29 2012
dt.setFullYear(2014);           // Mar 01 2014 instead of Feb 28 2014

Darüber hinaus kann das Festlegen eines Monats vor dem Datum immer noch zu einem unerwarteten Überlauf führen (Antworten, die eine Änderung der Reihenfolge der Methoden empfehlen, sind falsch):

var dt = new Date(2014, 0, 31); // Jan 31 2014
dt.setFullYear(2014);           // Jan 31 2014
dt.setMonth(1);                 // Mar 03 2014 instead of Feb 28 2014
dt.setDate(1);                  // Mar 01 2014
Salman A.
quelle
Ich mag diese Antwort, weil sie Ihnen oben die richtige Lösung gibt und dann erklärt, warum die kaputte Lösung nicht funktioniert ...
Kip
7

Das Warum des Verhaltens und wie man es vermeidet, wurde ausführlich erklärt.

Der eigentliche Fehler in Ihrem Code ist jedoch, dass Sie nicht den Standardkonstruktor verwenden sollten: new Date (). Ihr Code führt zu einem Datum am 13. Dezember mit der aktuellen Uhrzeit. Ich bezweifle, dass du das willst. Sie sollten den Datumskonstruktor verwenden, der Jahr, Monat und Tag als Parameter verwendet.

Florian F.
quelle
1
Ich nehme an, es sollte der Kommentar zur akzeptierten Antwort sein?
Danubian Sailor
Nicht wirklich. Es ist eine Antwort auf die Frage "Was habe ich falsch gemacht?"
Florian F
-1

Die Antworten machten deutlich, dass die richtige Reihenfolge für die Einstellung des Datums lautet:

  • setFullYear ()
  • setMonth ()
  • Datum einstellen()

Ich möchte nur darauf hinweisen, dass es wegen des 29. Februar in Leapyears auch wichtig ist, das Jahr zuerst festzulegen.

Henman
quelle
1
Nein. Die Bestellung garantiert nicht, dass das Datum korrekt eingestellt wird. Siehe Kommentare unter den akzeptierten und am meisten bewerteten Antworten.
Salman A
1
Wenn Ihr Startdatum der 31. ist und Sie es auf einen Monat mit weniger (wie 30) Tagen einstellen, werden Sie im nächsten Monat enden. Das ist also einfach nicht genug. Um sicher zu gehen, sollten Sie das Datum auf höchstens 28 einstellen, bevor Sie den Monat einstellen. Und setzen Sie das Datum schließlich wieder auf den Endwert, falls dieser höher ist.
Bart
-3
var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11);
dt.setDate(31);

Übergeben Sie den Wert als Ganzzahl, nicht als Zeichenfolge. Es wird ein korrekter Wert zurückgegeben.


Update - obige Beschreibung ist nicht korrekt. Das Hauptproblem war, dass Sie diese drei Zeilen in die richtige Reihenfolge bringen mussten. Selbst nachdem ich die Reihenfolge korrigiert hatte, vergaß ich, die Beschreibung zu korrigieren

Deepak Sharma
quelle
Nein, hier nicht mein Test in der Chrome-Konsole: var dt = new Date (); undefined dt.setDate (31); 1412157761255 dt.setMonth (11); 1417431761255 dt.setFullYear (2014); 1417431761255 dt Mon Dec 01 2014 12:02:41 GMT + 0100 (Paris, Madrid)
user2859409
6
Es hat nichts mit der Art des Arguments und alles mit der Sequenz zu tun. Sie erwähnen die Sequenz, als wäre sie eine Nebensache ...
siehe
1
Während dieser Code funktioniert , haben Sie eine falsche Erklärung gegeben, warum.
Danubian Sailor