尽管看起来合乎逻辑,但接受的答案是不正确的,因为 JavaScript 日期不是这样工作的。
在这里需要特别注意的是,JavaScript 中日期(即new Date()-0
或Date.now()
)的数值始终以自纪元以来的毫秒为单位来衡量,这是一个基于宇宙历史中精确时刻的无时区量。您无需对返回的数值进行任何加减运算即可将数值Date()
转换为时区,因为该数值没有 timezone。如果它确实有时区,则 JavaScript 日期中的其他所有内容都将不起作用。
时区、闰年、闰秒以及对我们本地时间和日期的所有其他无休止的复杂调整,都是基于这个一致且明确的数值,而不是相反。
以下是日期的数值(提供给日期构造函数)如何独立于时区的示例:
中部标准时间:
new Date(0);
// Wed Dec 31 1969 18:00:00 GMT-0600 (CST)
在阿拉斯加安克雷奇:
new Date(0);
// Wed Dec 31 1969 15:00:00 GMT-0900 (AHST)
在法国巴黎:
new Date(0);
// Thu Jan 01 1970 01:00:00 GMT+0100 (CET)
重要的是要观察到,在所有情况下,基于零毫秒的无时区纪元偏移,结果时间是相同的。法国巴黎的凌晨 1 点与阿拉斯加安克雷奇的前一天下午 3 点完全相同,这与伊利诺伊州芝加哥的下午 6 点完全相同。
因此,此页面上接受的答案是不正确的。观察:
// Create a date.
date = new Date();
// Fri Jan 27 2017 18:16:35 GMT-0600 (CST)
// Observe the numerical value of the date.
date.valueOf();
// 1485562595732
// n.b. this value has no timezone and does not need one!!
// Observe the incorrectly "corrected" numerical date value.
date.valueOf() + date.getTimezoneOffset() * 60000;
// 1485584195732
// Try out the incorrectly "converted" date string.
new Date(date.valueOf() + date.getTimezoneOffset() * 60000);
// Sat Jan 28 2017 00:16:35 GMT-0600 (CST)
/* Not the correct result even within the same script!!!! */
如果你在另一个时区有一个日期字符串,通过创建的结果对象中没有转换new Date("date string")
需要。为什么?无论时区如何,该日期的 JavaScript 数值都将相同。无论原始时区是什么,JavaScript 都会自动通过极其复杂的过程来提取自纪元以来的原始毫秒数。
最重要的是,将文本日期字符串x
插入new Date(x)
构造函数将自动从原始时区(无论可能是什么)转换为无时区的纪元毫秒表示时间,无论任何时区都是相同的。在您的实际应用程序中,您可以选择在您想要的任何时区中显示日期,但不要为此添加/减去日期的数值。在创建日期对象的那一刻,所有的转换都已经发生了。时区甚至不再存在,因为日期对象是使用精确定义且不受时区限制的时间感来实例化的。
当您的应用程序的用户被考虑时,时区才会重新开始存在。用户确实有一个时区,因此您只需向用户显示该时区。但这也会自动发生。
让我们考虑一下原始问题中的几个日期:
date1 = new Date("Fri Jan 20 2012 11:51:36 GMT-0300");
// Fri Jan 20 2012 08:51:36 GMT-0600 (CST)
date2 = new Date("Fri Jan 20 2012 11:51:36 GMT-0300")
// Fri Jan 20 2012 08:51:36 GMT-0600 (CST)
控制台已经知道我的时区,因此它会自动向我显示这些时间对我的意义。
如果您想知道 GMT/UTC 表示的时间,也不需要转换!你根本不改变时间。您只需显示时间的 UTC 字符串:
date1.toUTCString();
// "Fri, 20 Jan 2012 14:51:36 GMT"
编写用于使用 JavaScript 日期的数值以数字方式转换时区的代码几乎肯定会失败。时区太复杂了,这就是为什么 JavaScript 被设计成你不需要这样做的原因。