Javascript 补偿Moment.js中的utcOffset

Javascript 补偿Moment.js中的utcOffset,javascript,date,momentjs,Javascript,Date,Momentjs,首先,我希望这不是重复的。我读过很多类似的问题,但找不到一个与这个问题相关的问题 我有一个javascript日期选择器,它在内部使用javascript日期,这会产生意外的副作用。当我选择2016年4月30日时,它将返回该日期午夜(00:00)的日期对象,但如果您位于不同的时区,并且它在内部使用UTC,它将返回一个对象,该对象将补偿您的UTC偏移。因为这里是BST,所以我得到的日期是4月30日00:00GTM+1:00,当你把它转换成ISO字符串时,实际上是4月29日23:00 我想将正确的日

首先,我希望这不是重复的。我读过很多类似的问题,但找不到一个与这个问题相关的问题

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

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

var newDate =  moment(newValue).toISOString();
console.log(newDate);
这是:

2016-05-19T23:00:00.000Z
因此,我对这一点的理解很弱,但我认为datepicker最初是使用我的本地时间偏移量,如果将19日23:00作为UTC日期存储在内部,那么它已经是UTC日期,转换为UTC将没有帮助


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

您在这里看到的是,js date对象和MomentJS在内部都包含以毫秒为单位的Unix时间戳。这些时间戳是对全局时间线上某个点的引用,如果需要,可以将该点转换为本地时间

当您使用默认的
矩()
构造函数时,您告诉矩在“本地”模式下运行。这意味着,当“时刻”显示其包含的日期时,它将从内部包含的UTC Unix时间戳转换为用户的本地时间

如果您想保留UTC时间(您没有),可以将从日期选择器获取的JS Date对象传递到
矩.UTC()
函数,然后在调用
.format()
时,您总会看到UTC时间

举个例子,我现在在美国中央夏令时,做偏移量-5

如果我以您的UTC时间戳为例,并将其传递给默认的力矩构造函数,我会得到以下结果:

moment('2016-05-19T23:00:00.000Z').format()
"2016-05-19T18:00:00-05:00"
如您所见,出于显示目的,“时刻”已转换为我的本地时区

但如果我使用UTC:

moment.utc('2016-05-19T23:00:00.000Z').format()
"2016-05-19T23:00:00+00:00"
没有变化

你不必担心评论中提到的时钟变化。由于您的日期选择器在全球时间线上为您提供了一个精确的点,因此时刻将始终能够正确地转换为本地时间

至于为什么
.toISOString()
在JS日期对象上调用UTC日期时总是给您一个UTC日期,您可以为此感谢TC39委员会。根据ES2015规范,这就是它的工作原理:


出于与本机日期工作方式的一致性,矩也始终为
.toISOString()
提供UTC。

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

当您使用默认的
矩()
构造函数时,您告诉矩在“本地”模式下运行。这意味着,当“时刻”显示其包含的日期时,它将从内部包含的UTC Unix时间戳转换为用户的本地时间

如果您想保留UTC时间(您没有),可以将从日期选择器获取的JS Date对象传递到
矩.UTC()
函数,然后在调用
.format()
时,您总会看到UTC时间

举个例子,我现在在美国中央夏令时,做偏移量-5

如果我以您的UTC时间戳为例,并将其传递给默认的力矩构造函数,我会得到以下结果:

moment('2016-05-19T23:00:00.000Z').format()
"2016-05-19T18:00:00-05:00"
如您所见,出于显示目的,“时刻”已转换为我的本地时区

但如果我使用UTC:

moment.utc('2016-05-19T23:00:00.000Z').format()
"2016-05-19T23:00:00+00:00"
没有变化

你不必担心评论中提到的时钟变化。由于您的日期选择器在全球时间线上为您提供了一个精确的点,因此时刻将始终能够正确地转换为本地时间

至于为什么
.toISOString()
在JS日期对象上调用UTC日期时总是给您一个UTC日期,您可以为此感谢TC39委员会。根据ES2015规范,这就是它的工作原理:


矩也总是为
.toISOString()
提供UTC,以便与本机日期的工作方式保持一致。

因此,澄清一下,您的日期选择器为您提供了一个本机JS日期对象。该日期对象的UTC值是您希望时刻解释为本地时间的值?不,它是相反的,不是吗?为什么不立即调用.format('YYYY-MM-DD')?在上面的场景中,如果您在英国夏季时间,则会显示“2016-05-20”。它在内部存储UTC日期19:00。把它转换成iso会给我一个我不想要的字符串。然而,javascript将其视为20日午夜,并且使用.format()确实为我提供了20日所需的字符串,这可能是因为javascript将日期视为20日,因为它会自动添加到我的偏移量中。我觉得奇怪的是.toISOString()将UTC日期转换为字符串,而.format()将格式化本地日期。虽然你的答案是正确的,但是如果你把它作为一个答案,我会把它标记为正确的。虽然我已经意识到,如果用户在午夜之前选择了一个日期,当时钟变为夏令时,然后在午夜后将其提交给服务器,那么它将向服务器发布错误的日期,但我没有精力去解决这个问题:)如果这确实是你想要的行为,我可以解释为什么:-)。回答来了。那么,澄清一下,