Próbuję przekonwertować ciąg na obiekt Date i działa przez wszystkie dni z wyjątkiem 31 grudnia, gdzie według obiektu jest napisane 1 grudnia zamiast 31. Nie mam pojęcia dlaczego. Oto mój JavaScript
kod:
var dt = new Date();
dt.setDate("31");
dt.setMonth("11");
dt.setFullYear("2014");
ale moja wartość zmiennej to:
Mon Dec 01 2014 11:48:08 GMT+0100 (Paris, Madrid)
Jeśli zrobię to samo dla dowolnej innej daty, mój obiekt wróci do odpowiedniej wartości. Czy masz pojęcie, co zrobiłem źle?
javascript
date
datetime
user2859409
źródło
źródło
Date
parametrów konstruktora bezpośrednio:new Date(2014, 11, 31)
Odpowiedzi:
: ( nie jest bezpieczny przez miesiące krótsze niż 31 dni )setMonth
powinien wcześniejsetDate
var dt = new Date(); dt.setFullYear(2014); dt.setMonth(11); dt.setDate(31);
I
setMonth
jest drugi parametr może być również używany do ustawiania daty.var dt = new Date(); dt.setFullYear(2014); dt.setMonth(11, 31);
Jeśli konstruktor nie poda żadnych argumentów, użyje bieżącej daty i godziny zgodnie z ustawieniami systemu.
Tak więc użycie
setMonth
isetDate
oddzielnie nadal spowodowałoby nieoczekiwany rezultat.Jeśli ustawione wartości są większe niż ich zakres logiczny , wartość zostanie automatycznie dostosowana do wartości sąsiedniej .
Na przykład, jeśli dzisiaj jest
2014-09-30
, tovar 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 */
Aby tego uniknąć, ustaw wartości bezpośrednio przy użyciu konstruktora.
var dt = new Date(2014, 11, 31);
źródło
setMonth
istnieje dwuargumentowa forma .Rzecz w tym, że kiedy ustawiasz dzień pierwszy, nadal jesteś w bieżącym miesiącu, czyli wrześniu. Wrzesień ma tylko 30 dni, więc:
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 */
źródło
To dlatego, że pierwszą rzeczą, którą robisz, jest
dt.setDate(31)
To ustawia bieżącą datę na 31. Bieżący miesiąc to wrzesień, który ma 30 dni, więc jest zawijany.
Gdybyś miał wydrukować datę po tym punkcie, byłby to 1 października.
źródło
Zakładając, że zamierzasz ustawić rok, miesiąc i datę jednocześnie, możesz użyć konstruktora dłuższej daty :
Więc napisałbyś:
var dt = new Date(2014, 11, 31);
Jak już ustalono, ustawienie jednej porcji daty naraz może spowodować przepełnienia:
var dt = new Date(2012, 1, 29); // Feb 29 2012 dt.setFullYear(2014); // Mar 01 2014 instead of Feb 28 2014
Ponadto ustawienie miesiąca przed datą może nadal powodować nieoczekiwane przepełnienie (odpowiedzi zalecające zmianę kolejności metod są niepoprawne):
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
źródło
Dokładnie wyjaśniono, dlaczego to zachowanie i jak go uniknąć.
Ale prawdziwym błędem w twoim kodzie jest to, że nie powinieneś używać domyślnego konstruktora: new Date (). Twój kod spowoduje wyświetlenie daty 13 grudnia z aktualną godziną. Wątpię, czy tego chcesz. Należy użyć konstruktora Date, który przyjmuje jako parametry rok, miesiąc i dzień.
źródło
Odpowiedzi jasno wskazywały, że prawidłowa kolejność ustawiania daty to:
Chcę tylko zaznaczyć, że ważne jest również, aby ustawić rok na początku, ponieważ 29 lutego jest latami letnimi.
źródło
var dt = new Date(); dt.setFullYear(2014); dt.setMonth(11); dt.setDate(31);
Przekaż wartość jako liczbę całkowitą, a nie łańcuch. Zwróci poprawną wartość u.
Aktualizacja - powyższy opis nie jest poprawny .. główny problem polegał na tym, że trzeba było ustawić te trzy linie w odpowiedniej kolejności .. Nawet po poprawieniu kolejności zapomniałem poprawić opis ..: P
źródło