момент.js-UTC дает неправильную дату


почему момент.JS UTC всегда показывает неправильную дату. Например, из консоли разработчика chrome:

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" почему он возвращается 17-й вместо 18-й, это было передано.

но если я использую momentjs без utc:

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

Я вернусь "2013-07-18" это то, что я также ожидаю при использовании moment.Яш мирового.

означает ли это, что мы не удается получить правильную дату при использовании момента.Яш мирового?

2 61

2 ответа:

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

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

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

вот несколько примеров, чтобы проиллюстрировать это (мое местное смещение времени UTC+3 во время 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)"

если вы хотите, чтобы строка даты и времени интерпретировалась как 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"

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

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

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

смотрите документация.

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

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

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

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