moment.js - UTC提供错误的日期

时间:2013-07-25 10:44:41

标签: javascript datetime timezone momentjs

为什么moment.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”为什么它会返回 17th 而不是 18th ,这是传入的。

但是如果我在没有utc的情况下使用momentjs:

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

我回来“2013-07-18”这是我在使用moment.js UTC时所期望的。

这是否意味着我们在使用moment.js UTC时无法获得正确的日期?

3 个答案:

答案 0 :(得分:122)

默认情况下,MomentJS以本地时间进行解析。如果仅提供日期字符串(没有时间),则时间默认为午夜。

在您的代码中,您创建一个本地日期,然后将其转换为UTC时区(实际上,它会使当前实例切换到UTC mode),因此在格式化时,它会被移位(取决于当地时间)向前或向后。

如果本地时区为UTC + N(N为正数),并且您解析了仅限日期的字符串,则您将获得上一个日期。

以下是一些例子来说明它(我在DST期间的本地时间偏移是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"

或者,正如Matt Johnson在他的回答中提到的那样,您可以(并且可能应该)使用moment.utc()将其解析为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"

答案 1 :(得分:26)

默认情况下,Datemoment都会解析浏览器本地时区的输入字符串。但是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之类的日期可能会被处理为1月4日或4月1日,具体取决于浏览器的文化设置。

答案 2 :(得分:-1)

使用这个:

return moment.utc(new Date(oData.CreatedAtUtc), 'MM/DD/YYYY h:mm A').local().format("YYYY-MM-DD HH:mm") + ' (' + timezoneAbbr + ')';