Почему момент.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.js UTC.
Означает ли это, что мы не можем получить правильную дату при использовании moment.js UTC?
toString()
послеformat()
(он уже возвращает строку).Ответы:
По умолчанию MomentJS анализирует по местному времени. Если указана только строка даты (без времени), время по умолчанию устанавливается на полночь.
В вашем коде вы создаете локальную дату, а затем конвертируете ее в часовой пояс UTC (фактически, это переводит экземпляр момента в режим UTC ), поэтому при форматировании он сдвигается (в зависимости от вашего местного времени) вперед или назад.
Если местный часовой пояс - 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"
источник
new Date('07-18-2013 UTC')
в виду, что не будет работать в IE8, если вам интересно.Оба
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 апреля, в зависимости от настроек языка и региональных параметров браузера.источник
moment
на консоль не очень полезен. Вы, наверное, смотрите на одно из его внутренних свойств. Вы должны отформатировать его перед проверкой результатов. Напримерmoment.utc().format()
илиmoment().format()
.new Date('2010-12-12')
дает мнеDate {Sat Dec 11 2010 19:00:00 GMT-0500 (Eastern Daylight Time)}
в FF 38.0.5. Просто чтобы контекстуализировать, что именно означает «по местному времени» - в данном случае это, по-видимому, означает «Date
будет предполагать, что строка без часового пояса находится в формате UTC и будет анализироваться по местному времени».d.getUTCDate()
=12
andd.getDate()
=11
'2012-12-12'
это UTC b / c, это в формате ISO, но'December 12, 2012'
и даже'2012/12/12'
анализируются с местным часовым поясом в ES5), но вы меня опередили. Настолько классно, что ES6 делает их всех локальными [саркастически сказал он]. Сроки - это боль, (c) Advent of Dates