在Moment.js中补偿utcOffset

时间:2016-05-01 15:12:34

标签: 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);

就是这样:

2016-05-19T23:00:00.000Z

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

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

1 个答案:

答案 0 :(得分:5)

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

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

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

作为一个例子,我现在正在美国中部夏令时间,使我的偏移-5。

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

.format()

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

如果我使用UTC:

moment('2016-05-19T23:00:00.000Z').format()
"2016-05-19T18:00:00-05:00"

没有变化。

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

至于为什么moment.utc('2016-05-19T23:00:00.000Z').format() "2016-05-19T23:00:00+00:00" 总是在JS Date对象上调用它时给你一个UTC日期 - 你可以感谢TC39委员会。这就是它应该按照ES2015规范工作的方式:http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype.toisostring

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