【问题标题】:How to tell JavaScript Date where to take TimezoneOffset from?如何告诉 JavaScript Date 从哪里获取 TimezoneOffset?
【发布时间】:2016-10-30 21:05:04
【问题描述】:

我使用 new Date(<date-string>).getTime() 将日期字符串传递到 1970 年的毫秒数。

问题是日期字符串不包含时区。他们是英国人,因此时区将是 GMT 或 GMT+1,具体取决于日期...

当我在前端 (Chrome) 或后端 (Node.js) 中使用此技术时。采用的时区是英国时区(GMT 或 GMT+1,具体取决于日期)。我假设这是从操作系统中获取的。

但是,当使用我被告知配置为 UTC 的 Node.js 服务器时...时区始终为 GMT,导致英国夏令时出错。

有没有办法告诉Date 在不更改服务器配置的情况下从操作系统获取时区?

例子:

var aDate = new Date('2016-06-23 10:15:0');
var timestamp = aDate.getTime();

以防我的解释不清楚:

// Executed on 28-06-2016

// In the browser (in London)
new Date().getTimezoneOffset();                            // -60
new Date('28-06-2016 11:11:11').getTimezoneOffset();       // -60
new Date('28-01-2016 11:11:11').getTimezoneOffset();       // 0

// In the Node.js server I am forced to use, which is configured to use UTC
new Date().getTimezoneOffset();                            // 0
new Date('28-06-2016 11:11:11').getTimezoneOffset();       // 0
new Date('28-01-2016 11:11:11').getTimezoneOffset();       // 0

// Ideally, I would like to have the output I get in the browser when I run the code in the UTC Node.js server

【问题讨论】:

    标签: javascript node.js date datetime timezone


    【解决方案1】:

    我建议为此使用Moment Timezone,因为如果没有库,这将变得不必要地复杂。要从给定时区的给定日期以毫秒为单位获取 UTC,您可以这样做:

    const moment = require('moment-timezone');
    
    function londonTimeToUTC(dateString) {
      return moment.tz(dateString, 'DD-MM-YYYY HH:mm:ss', 'Europe/London').valueOf();
    }
    
    console.log(londonTimeToUTC('28-06-2016 11:11:11')); // 1467108671000
    console.log(londonTimeToUTC('28-01-2016 11:11:11')); // 1453979471000
    

    传递给moment.tz() 的第二个参数是format string,如果日期字符串不在ISO format 中,这是必需的。第三个参数是任何有效的timezone identifier

    【讨论】:

    • 这对我不起作用。正如我所说,我正在使用配置为使用 UTC 的服务器。所以,对我来说,new Date().getTimezoneOffset(); 将永远返回0,无论我的时区如何。我的问题是:我该怎么做才能让Date() 构造函数考虑我的时区?
    • @DavidTorres 抱歉,我想我仍然不清楚这个问题。你的意思是你想为英国夏令时调整一个日期字符串,然后将它传递给 Date 构造函数?
    • 我想要的是将日期字符串提供给构造函数,并且构造函数根据日期考虑它是 BST 还是 GMT。如果您在大多数环境中运行该代码(但不在我运行代码的服务器中,因为它被配置为在 UTC 上工作),会发生什么情况(另外,有人告诉我,服务器是一个很好的做法在UTC,但对我来说是一种痛苦)。
    • @DavidTorres 您必须使用非 ISO 格式的日期字符串。虽然Date 构造函数可以处理这些,但这显然已被弃用。相反,将Date 对象传递给moment.tz()。我已经编辑了答案以反映这一点。
    • .valueOf()返回UTC时间,dateString参数预计会标准化为UTC,所以这是意料之中的。 .utcOffset() 将为您提供与 UTC 的偏移量,这将为您提供伦敦和马德里的不同结果。这不是您想要的UTC偏移量吗?我觉得我仍然缺少一些东西。
    【解决方案2】:

    有什么方法可以告诉Date 在不更改服务器配置的情况下从操作系统获取时区?

    来自操作系统的时区Date 对象使用的。如果您询问是否可以在不更改配置的情况下更改该时区,那么不可以 - 没有办法做到这一点。 Date 对象总是采用本地时区的行为。即使您在输入字符串中提供偏移量,它也只是使用它来确定内部 UTC 时间戳。通过大多数属性(包括toStringgetTimezoneOffset)的输出将始终使用本地时区。

    即使在您的示例中,您也不能指望浏览器行为总是返回您显示的值,因为访问您网站的每个用户可能有不同的时区设置。

    推荐的处理方法是使用moment.js 库,它可以自己处理UTC 和本地时间,但如果您想使用特定时区,可能需要使用moment-timezone extension,比如Europe/London

    现在,话虽如此,如果您确定整个 node.js 应用程序将在单个时区运行,并且您在 Linux 或 OSX(不是 Windows)上运行,那么您确实可以更改哪个时间node.js 认为是“本地”的区域。只需在启动节点之前设置TZ 环境变量,如下所示:

    env TZ='Europe/London' node server.js
    

    浏览器或 Windows 没有对应的。而且您仍然必须在您的网站上与可能的非英国用户抗衡 - 所以这并不能保证客户端和服务器时间之间的匹配。但它确实解决了您的问题。

    另见:

    【讨论】:

    • 我需要的是在运行new Date('<british-date-string>') 时获得正确的时间戳。无论 Node.js 服务器在哪里,服务器都会保留 UTC。我只看到在创建日期后将日期转换为不同时区的选项,但首先创建的日期是错误的,因为new Date() 不知道接收的日期是英国的。
    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多