为什么 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 时无法获得正确的日期?
默认情况下,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"
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
这样的日期可能会被处理为 1 月 4 日或 4 月 1 日,具体取决于浏览器的区域性设置。
用这个:
return moment.utc(new Date(oData.CreatedAtUtc), 'MM/DD/YYYY h:mm A').local().format("YYYY-MM-DD HH:mm") + ' (' + timezoneAbbr + ')';
以上都不适合我。
但是将日期转换为 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();