2013-07-25 7 views
53

Почему time.js UTC всегда показывает неправильную дату. Например, из консоли разработчика Chrome:moment.js - UTC дает неправильную дату

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

Оба они вернутся «2013-07-17» почему это возвращение семнадцатого вместо восемнадцатого, который был принят в

. Но если я использую momentjs без ГРИНВИЧА:

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

я вернусь «2013-07-18» это то, что я также ожидаю при использовании time.js UTC.

Означает ли это, что мы не можем получить правильную дату при использовании момента времени. Js UTC?

+1

Я не думаю, что вам нужно 'toString()' after' format() '(он уже возвращает строку). – alex

ответ

81

По умолчанию MomentJS анализирует локальное время. Если предоставляется только строка даты (без времени), время по умолчанию равно полуночи.

В вашем коде вы создаете локальную дату, а затем конвертируете ее в часовой пояс UTC (фактически, он переключает экземпляр экземпляра на UTC mode), поэтому, когда он отформатирован, он сдвигается (в зависимости от вашего местного времени) вперед или назад.

Если местный часовой пояс UTC + N (N - положительное число), и вы разбираете строку только для даты, вы получите предыдущую дату.

Вот несколько примеров, иллюстрирующих это (мое местное время смещение UTC + 3 в течение летнего времени):

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

Если вы хотите даты и времени строку истолковано как UTC, вы должны быть четко об этом:

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

или, как Мэтт Джонсон упоминает в своем ответе, вы можете (и, вероятно, должен) разобрать его в качестве даты UTC, в первую очередь с использованием moment.utc() и включают в себя строку формата в качестве второго аргумента для предварительного неоднозначность.

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

Чтобы перейти в другую сторону вокруг и преобразовать дату в формате UTC к местному времени, вы можете использовать метод local() следующим образом:

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

Большое спасибо. Поэтому в принципе, я должен всегда проходить во время использования UTC или проходить в формате UTC, как в вашем втором подходе. – brg

+0

Либо это, либо придерживаться местного часового пояса. Если вы отправляете время с сервера, вы можете выразить их как временную метку Unix (X) или как строки в определенном часовом поясе. Зачем использовать UTC вместо локального часового пояса пользователя (в любом случае (за исключением отправки нормализованных данных на сервер)? – MasterAM

+1

Помните, что 'новая дата ('07 -18-2013 UTC ')' не будет работать в IE8, если вам все равно. –

20

Оба Date и moment будет разбирать строку ввода в локальный часовой пояс браузера по умолчанию. Однако Date иногда не согласуется с этим. Если строка конкретно YYYY-MM-DD, используя дефис, или если это YYYY-MM-DD HH:mm:ss, она будет интерпретировать ее как по местному времени. В отличие от Date, moment всегда будет соответствовать тому, как он анализирует.

Правильный способ разбора входной момент как UTC в формате вы предоставили бы так:

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

См this documentation.

Если вы хотите, чтобы затем отформатировать его по-разному для вывода, вы могли бы сделать это:

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

Вам не нужно звонить toString явно.

Обратите внимание, что очень важно обеспечить формат ввода. Без него дата, например, 01-04-2013, может обрабатываться как 4 января, так и 1 апреля, в зависимости от настроек культуры браузера.

+0

Спасибо Мэтту, я поддержал ваш отличный ответ. – brg

+0

Только для изучения саке в консоли: ** moment.utc ('2013-07-18 0:00 +0100', 'YYYY-MM-DD HH: mm') ** дает мне ** "2013-07 -18 0:00 +0100 "** Но какие дислокации в jsfiddle при запуске разные: ** Чт 25 июля 2013 01:00:00 GMT + 0100 ** Обратите внимание ** ** 01: 00: 00 **. Благодарю. – brg

+0

Вывод необработанного «момента» на консоли не очень полезен. Вы, вероятно, смотрите на одну из своих внутренних свойств. Вы должны отформатировать его перед проверкой результатов. Например, 'moment.utc(). Format()' или 'moment(). Format()'. –