moment.js - UTC 给出了错误的日期

问题描述 投票:0回答:4

为什么 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 时无法获得正确的日期?

javascript datetime timezone momentjs
4个回答
209
投票

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

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

如果本地时区是 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"

41
投票

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
这样的日期可能会被处理为 1 月 4 日或 4 月 1 日,具体取决于浏览器的区域性设置。


2
投票

用这个:

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

0
投票

以上都不适合我。

但是将日期转换为 ISO 字符串确实如此。

// input date is "2023-09-28T00:00:00-05:00" 
// timezone is chicago time GMT-5:00
const date_str =  new Date(this.date); 

const isoDate =  date_str.toISOString(); 
// isoDate Result "2023-09-28T05:00:00.000Z"


// I have no idea why, but whenever i called the moment() function, 
// it would always get the previous date
// i've tried all the utc method, parseZone, none of them worked, 
// except converting it into ISO string
const startTime = moment(isoDate)
    .set('hour', parseInt(momentConfigStartTimeOfDay.hour))
    .set('minute', parseInt(momentConfigStartTimeOfDay.minute))
    .format();
const endTime = moment(isoDate)
    .set('hour', parseInt(momentConfigEndTimeOfDay.hour))
    .set('minute', parseInt(momentConfigEndTimeOfDay.minute))
    .format();
希望这对某人有帮助。 我花了一天多的时间试图弄清楚什么可行哈哈

© www.soinside.com 2019 - 2024. All rights reserved.