2013-07-25 20 views
53

Dlaczego moment.js UTC zawsze pokazuje niewłaściwą datę. Na przykład z konsoli programisty Chrome:moment.js - UTC podaje niewłaściwą datę

moment(('07-18-2013')).utc().format("YYYY-MM-DD").toString() 
// or 
moment.utc(new Date('07-18-2013')).format("YYYY-MM-DD").toString() 

Obaj powrócą „17/07/2013” ​​ dlaczego jest powrocie 17-ta zamiast 18-ty, który został przekazany w

. ale jeśli mogę użyć momentjs bez UTC:

moment(new Date('07-18-2013')).format("YYYY-MM-DD").toString() 

wrócę "18/07/2013" czego się też spodziewam przy użyciu pliku moment.js UTC.

Czy to oznacza, że ​​nie możemy uzyskać poprawnej daty podczas użycia pliku moment.js UTC?

+1

Nie sądzę, że potrzebujesz 'toString()' after 'format()' (już zwraca ciąg znaków). – alex

Odpowiedz

81

Domyślnie MomentJS analizuje w czasie lokalnym. Jeśli podano tylko łańcuch daty (bez czasu), domyślnie jest godzina północna.

W kodzie utworzysz lokalną datę, a następnie przekształcisz ją w strefę czasową UTC (w rzeczywistości zmieni się ona na UTC mode), więc po sformatowaniu zostanie przesunięta (w zależności od czasu lokalnego)) do przodu lub do tyłu.

Jeśli lokalna strefa czasowa ma wartość UTC + N (N oznacza liczbę dodatnią), a przeanalizujesz ciąg z datą, otrzymasz poprzednią datę.

Oto kilka przykładów, aby go ilustrować (mój czas lokalny offset UTC + 3 podczas DST):

>>> moment('07-18-2013', 'MM-DD-YYYY').utc().format("YYYY-MM-DD HH:mm") 
"2013-07-17 21:00" 
>>> moment('07-18-2013 12:00', 'MM-DD-YYYY HH:mm').utc().format("YYYY-MM-DD HH:mm") 
"2013-07-18 09:00" 
>>> Date() 
"Thu Jul 25 2013 14:28:45 GMT+0300 (Jerusalem Daylight Time)" 

Jeśli chcesz ciąg data-czas interpretowany jako UTC, powinno być jawne o nim:

>>> moment(new Date('07-18-2013 UTC')).utc().format("YYYY-MM-DD HH:mm") 
"2013-07-18 00:00" 

lub, jak Matt Johnson wspomina w swojej odpowiedzi, można (i prawdopodobnie powinien ) przetworzy go jako data UTC w pierwszej kolejności przy użyciu moment.utc() i zawierają ciąg formatu jako drugi argument pre uwolnić dwuznaczność.

>>> moment.utc('07-18-2013', 'MM-DD-YYYY').format("YYYY-MM-DD HH:mm") 
"2013-07-18 00:00" 

Aby przejść na odwrót i przekonwertować datę UTC do lokalnej daty, można użyć metody local(), co następuje:

>>> moment.utc('07-18-2013', 'MM-DD-YYYY').local().format("YYYY-MM-DD HH:mm") 
"2013-07-18 03:00" 
+0

Wielkie dzięki. Zasadniczo powinienem zawsze przechodzić w czasie, gdy używam UTC lub przekazywać w UTC, jak w twoim drugim podejściu. – brg

+0

Albo to lub pozostań przy lokalnej strefie czasowej. Jeśli wysyłasz czas z serwera, możesz wyrazić je jako uniksowy znacznik czasu (X) lub jako łańcuchy w określonej strefie czasowej. Dlaczego mimo to używać UTC zamiast lokalnej strefy czasowej użytkownika (z wyjątkiem wysyłania znormalizowanych danych do serwera)? – MasterAM

+1

Pamiętaj, że 'nowa data ('07 -18-2013 UTC ')' nie zadziała w IE8, jeśli ci na tym zależy. –

20

Zarówno Date i moment będzie analizować ciąg wejściowy w domyślna lokalna strefa czasowa przeglądarki. Jednak w tym przypadku czasami Date jest niespójne. Jeśli ciąg znaków jest specyficznie YYYY-MM-DD, przy użyciu łączników lub jeśli jest to YYYY-MM-DD HH:mm:ss, będzie interpretowany jako czas lokalny. W przeciwieństwie do Date, moment zawsze będzie konsekwentnie o tym, jak analizuje.

Poprawny sposób analizowania chwilą wejścia jako UTC w formacie przewidzianym byłoby tak:

moment.utc('07-18-2013', 'MM-DD-YYYY') 

Patrz this documentation.

Jeśli chcesz następnie sformatować go inaczej wyjścia, by to zrobić:

moment.utc('07-18-2013', 'MM-DD-YYYY').format('YYYY-MM-DD') 

Nie trzeba zadzwonić toString wyraźnie.

Należy pamiętać, że bardzo ważne jest podanie formatu wejściowego. Bez tego data taka jak 01-04-2013 może zostać przetworzona jako 4 stycznia lub 1 kwietnia, w zależności od ustawień kultury przeglądarki.

+0

Dzięki Matt, przegłosowałem twoją wspaniałą odpowiedź. – brg

+0

Tylko dla nauki sake, w konsoli: ** moment.utc ("2013-07-18 0:00 +0100", "RRRR-MM-DD HH: mm") ** daje mi ** "2013-07 -18 0:00 +0100 "** Ale to, co zmienia się w jsfiddle, gdy jest inaczej, to: ** Czw Lipiec 25 2013 01:00:00 GMT + 0100 ** Zwróć uwagę na ** 01: 00: 00 **. dzięki. – brg

+0

Wydawanie surowego "momentu" na konsoli nie jest zbyt użyteczne. Prawdopodobnie patrzysz na jedną ze swoich wewnętrznych właściwości. Powinieneś sformatować go przed sprawdzeniem wyników. Na przykład 'moment.utc(). Format()' lub 'moment(). Format()'. –

Powiązane problemy