在Moment.js中补偿utcOffset

jon*_*bbs 0 javascript date momentjs

首先,我希望这不是重复.我已经阅读了很多类似的问题,但找不到这个问题.

我有一个javascript datepicker,它在内部使用javascript日期,这有一个意想不到的副作用.当我选择2016年4月30日时,它会在该日期返回午夜(00:00)的日期对象,但如果您在不同的时区并且在内部使用UTC,则会返回一个补偿UTC偏移的对象.所以,因为它是BST,所以我回来的日期是4月30日00:00 GTM + 1:00,当你把它变成ISO字符串时实际上是4月29日23:00.

我想将正确的日期(4月30日,没有时间)发送回服务器,但是当前执行此操作时我得到的日期字符串:

var newDate =  moment(newValue).toISOString();
console.log(newDate);
Run Code Online (Sandbox Code Playgroud)

这是:

2016-05-19T23:00:00.000Z
Run Code Online (Sandbox Code Playgroud)

所以,我对此的理解很弱,但我认为,如果并且在19日23:00作为UTC日期在内部存储,那么日期选择器最初使用我的本地时间偏移需要一个小时,所以它已经是一个UTC日期,转换为UTC无济于事.

我需要做的是使用moment.js来补偿utcOffset并将日期移动到我在UTC中选择的日期的午夜.

Mag*_*int 5

你在这里看到的是JS Date对象和MomentJS在内部都包含一个以毫秒为单位的Unix时间戳.这些时间戳是对全局时间轴上的一个点的引用,如果需要,可以将其转换为本地时间.

当您使用默认moment()构造函数时,您告诉Moment以"本地"模式运行.这意味着当Moment显示它包​​含的日期时,它将从内部包含的UTC Unix时间戳转换为用户的本地时间.

如果你想保持UTC时间(你没有),你可以将你从日期选择器获得的JS Date对象传递给moment.utc()函数,然后当你调用.format()那个时刻时,你总是会看到UTC时间.

举个例子,我现在正在美国中部夏令时间,我的偏移量为-5.

如果我采用您的示例UTC时间戳并将其传递给默认时刻构造函数,我会得到以下内容:

moment('2016-05-19T23:00:00.000Z').format()
"2016-05-19T18:00:00-05:00"
Run Code Online (Sandbox Code Playgroud)

如您所见,为了显示目的,Moment已转换为我当地的时区.

如果我使用UTC虽然:

moment.utc('2016-05-19T23:00:00.000Z').format()
"2016-05-19T23:00:00+00:00"
Run Code Online (Sandbox Code Playgroud)

没变.

您无需担心评论中正在讨论的时钟更改.由于您的日期选择器为您提供了全球时间轴上的确切点,因此时刻始终能够正确转换为本地时间轴.

至于为什么.toISOString()总是在JS Date对象上调用它时给你一个UTC日期 - 你可以感谢TC39委员会.这就是按照ES2015规范它应该如何工作:http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype.toisostring

.toISOString()为了与原生日期的工作方式保持一致,Moment也始终提供UTC .