【问题标题】:How to make JavaScript Date.prototype.toString() always display local time zone如何使 JavaScript Date.prototype.toString() 始终显示本地时区
【发布时间】:2014-08-05 12:43:12
【问题描述】:

我设置了一个 UTC+0 时间,并希望它在每台计算机的本地时区的不同计算机上显示。 但是当我在我的计算机(VMware VM)的 Chrome 中运行代码时,它给了我以下信息:

Date.UTC(2014, 0, 27, 6) // 1390802400000
var now = new Date()               // Tue Aug 05 2014 07:32:38 GMT-0400 (EDT)
now.getTime()     // 1407238358829
new Date(1407238358829)  // Tue Aug 05 2014 07:32:38 GMT-0400 (EDT)
new Date(1390802400000)  // Mon Jan 27 2014 01:00:00 GMT-0500 (EST)

我的电脑是GMT-4,但为什么最后一行显示的是美国东部时间而不是美国东部时间?

我也在其他计算机上尝试相同的代码,例如 EC2 实例 (GMT+0) 和我朋友的 (GMT+8),这些计算机只会显示其本地时区的时间。

但是为什么我的电脑显示其他时区的时间?

【问题讨论】:

    标签: javascript timezone


    【解决方案1】:

    代码运行正常。这就是时区的实际工作方式。希望一些适当的术语能够为您解开疑惑。

    “时区偏移”与“时区”相同。您可以在the timezone tag wiki 中的“时区!= 偏移量”部分了解更多信息。

    你说:

    我的电脑在 GMT-4

    这是不正确的。您的计算机位于北美“东部时间”时区。在 Linux/Mac 上,这可能会显示为 "America/New_York"。在 Windows 上,它会在您的控制面板中显示为“东部时间(美国和加拿大)”。

    该时区的时区偏移在冬季月份为 UTC-05:00,在夏令时生效的夏季月份为 UTC-04:00。我们分别称它们为“东部标准时间”(或 EST)和“东部夏令时间”(或 EDT)。虽然有时这些被称为“时区”,但您可能希望将它们视为“时区段” - 因为它们仅指实际时区的部分

    回顾一下:

    EST = Eastern Standard Time = UTC-05:00 = GMT-5
    EDT = Eastern Daylight Time = UTC-04:00 = GMT-4
    
    ET = Eastern Time = "America/New_York" = "Eastern Time (US & Canada)"
      - Uses EST in the winter
      - Uses EDT in the summer
    

    new Date(1390802400000) 显示为 EST,因为该值是在一月份,即冬季。

    你也说过:

    我也在其他计算机上尝试相同的代码,例如 EC2 实例 (GMT+0) 和我朋友的 (GMT+8),这些计算机只会显示其本地时区的时间。

    EC2 实例可能配置为 UTC。这是服务器的最佳实践。这意味着它将始终具有零偏移。夏令时不会改变。

    您朋友的计算机可能处于不遵循夏令时的时区。例如(我在这里猜测),也许他在"Asia/Shanghai" 时区,该时区在中国使用。由于中国不使用夏令时,因此他的偏移量永久为 UTC+08:00。

    You can see a list of time zones and their offsets here.

    【讨论】:

    • 在许多计算机上也可以选择不遵守夏令时,即使在使用夏令时的位置,因此获得所有本地日期的“标准时间”。
    • @RobG - 是的,这是正确的,至少在 Windows 上是这样。然而,绕过 DST 规则几乎从来都不是一个好主意。世界上有一些分散的地方是必要的 - 但绝大多数地方都有自己独特的时区条目,其中已经考虑了 DST(或缺少 DST)。不过好点。
    【解决方案2】:

    Javascript 中的日期存储为 UTC 时间,更具体地说,存储为自特定日期以来的毫秒数(准确地说是 1970 年 1 月 1 日 00:00:00)。您可以使用date.toLocaleString() 将它们打印到当地时间。仅时间和日期也有具体的方法:date.toLocaleDateString()date.toLocaleTimeString()。这些返回一个字符串,因为本地时间旨在显示,而不是存储。

    作为一项规则:始终将日期存储和处理为 UTC 时间,直到您将它们显示给用户。如果您从用户那里读取当地时间,则需要尽早将它们转换为 UTC 时间并保持原样,直到再次显示它们。


    在您的情况下,您在 EDT 中获得 1 个日期而在 EST 中获得 1 个日期的原因是由于夏令时(将您的时钟设置提前或后 1 小时)。在大约半年的时间里,美国东海岸的某些地区(如纽约)与一年中的另一半时间处于不同的时区。在您的情况下,对于使用 DST 的人来说,8 月 5 日和 1 月 27 日实际上位于不同的时区。您实际上无法在 EDT 的 1 月份找到时间,因为该时区仅存在于 3 月中旬和 10 月中旬之间。

    来源:http://www.timeanddate.com/library/abbreviations/timezones/na/edt.html

    【讨论】:

    • 您的解释很清楚,但我只希望 Date 对象在我的 EDT 计算机上显示 EDT(GMT-4) 时间。为什么“new Date()”有效,而“new Date(1390802400000)”无效(显示 EST 时间)。
    • 这可能与夏令时(DST)有关。 EDT 和 EST 是相同的时区,但在一年中的不同部分。在 10 月中旬至 3 月中旬之间,美国东海岸的特定地区(如纽约)实际上不存在 EDT。我会修改我的答案以反映这一点。
    【解决方案3】:

    当你这样做时:

    new Date(1390802400000)  // Mon Jan 27 2014 01:00:00 GMT-0500 (EST)
    

    使用 1390802400000 的 time value 创建一个新的 Date 对象。如果您只是将其写入输出(警报、控制台等),那么提供的默认值与 Date.toString 相同,它根据本地时区偏移量以方便的格式返回一个字符串。

    如果您想以 UTC 格式查看日期,可以使用 toISOString 方法:

    var d = new Date(1390802400000);
    console.log(d.toISOString());   // 2014-01-27T06:00:00.000Z
    

    或者您可以使用 UTC 方法(例如 getUTCHours)并以您喜欢的任何格式构建字符串。

    我的电脑是 GMT-4,但为什么最后一行显示的是 EST 时间而不是 EDT

    因为在该日期,您的计算机认为当地时区是 EST(可能是美国东部标准时间,而不是澳大利亚东部标准时间)。是吗?

    【讨论】:

    • 谢谢!但是为什么当我执行“new Date()”时我的计算机一开始认为我在 EDT 中,后来当我执行“new Date(1390802400000)”时认为我在 EST 中?其他电脑没有这个问题,只有我的EDT电脑有这个问题。
    • 见我回答的最后一段和马特的回答。您可以将系统设置更改为不遵守夏令时,或者将所需的偏移量直接设置为 UTC-05:00,或者选择具有适当偏移量但没有夏令时的区域。
    • 一开始我以为我的代码不能正常工作,但现在我知道它是正确的,所以我不需要更改任何内容,只需格式化日期并显示。非常感谢!
    • @FlyingHorse——很高兴你对它进行了排序。 :-)
    猜你喜欢
    • 2016-12-22
    • 2012-07-02
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    相关资源
    最近更新 更多