在不使用字符串的情况下获取javascript中另一个时区的时区偏移量

时间:2016-03-09 10:00:10

标签: javascript date datetime timezone timezone-offset

我想计算从'用户时间'到'WET / WEST'的偏移量。

我通过新的4^5获得用户偏移。

但是如何获得WET / WEST的偏移量呢?这样我可以计算两者的组合偏移量?

例如,如果用户处于中欧时间(CET / CEST),则在冬季,组合偏移将为-60(CET)+ 0(WET)= -60。在夏天,它将是-120(CEST)+ 60(WEST)= -60。在这种情况下,它总是-60但用户也可以有一个没有DST的时区。

如果没有将其格式化为字符串并从该字符串中读出新的时区,是否可以这样做?

2 个答案:

答案 0 :(得分:3)

您无法可靠地使用时区缩写进行输入,因为它们可以通过多种不同方式进行解释。例如,CST可能是"中央标准时间"在北美,或者"中国标准时间"或者#34;古巴标准时间"。虽然像WETWEST这样的缩写是唯一的,但很多都是含糊不清的。请参阅the list of time zone abbreviations here

相反,您需要知道IANA时区标识符。一个位置that uses WET/WEST是葡萄牙,其{I}标识为"Europe/Lisbon"。您可以找到标识符列表here。选择正确的标识符非常重要,因为时区会随着时间的推移而变化。每个标识符都反映了每个区域的特定历史记录。

您知道IANA时区标识符,然后您可以选择如何使用它:

  1. 在一些完全支持ECMAScript Internationalization API (ECMA-402)时区功能的现代浏览器中,您可以执行以下操作:

    var d = new Date();
    var s = d.toLocaleString(undefined, { timeZone: "Europe/Lisbon" })
    

    这会在格式化过程中将提供的日期和时间转换为正确的时区。在第一个参数中传递undefined将使用当前区域设置进行格式化。

    这种方法有一些缺点,因为它尚未在所有浏览器中实现,并且没有用于检索特定时间点的原始时区偏移的API。

  2. 您可以考虑使用实现此功能的库。 I list several of them here。我的个人偏好是使用moment.js插件moment-timezone,您可以执行以下操作:

    var m = moment.tz("Europe/Lisbon");
    var s = m.format();
    

    您可以将参数传递给format方法,以显示您喜欢的输出。您还可以转换现有时间,例如:

    var m = moment.utc("2016-01-01T00:00:00").tz("Europe/Lisbon");
    var s = m.format();
    

    您还可以获得特定时刻的偏移量,如下所示:

    var m = moment.utc("2016-01-01T00:00:00").tz("Europe/Lisbon");
    var offsetInMinutes = m.utcOffset();
    var offsetAsString = m.format("Z");
    
  3. 您可以编写自己的代码来处理特定时区。虽然这可能容易出错,但我通常不会推荐它。如果沿着这条路走下去,更新可能会特别困难。

  4. 还要记住,特定时区的偏移量会根据生效的日期和时间而有所不同。因此,new Date()代表"现在"可能会或可能不会始终是正确的输入,具体取决于您的情况。

答案 1 :(得分:0)

我想在不使用库的情况下做到这一点,所以我编写了这个函数,为您提供给定时区和 UTC 之间的时区偏移:

function getTimezoneOffsetFrom(otherTimezone) {
    if (otherTimezone === void 0) { otherTimezone = "Europe/Amsterdam"; }
    var date = new Date();
    function objFromStr(str) {
        var array = str.replace(":", " ").split(" ");
        return {
            day: parseInt(array[0]),
            hour: parseInt(array[1]),
            minute: parseInt(array[2])
        };
    }
    var str = date.toLocaleString(['nl-NL'], { timeZone: otherTimezone, day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: false });
    var other = objFromStr(str);
    str = date.toLocaleString(['nl-NL'], { day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: false });
    var myLocale = objFromStr(str);
    var amsterdamOffset = (other.day * 24 * 60) + (other.hour * 60) + (other.minute);
    var myLocaleOffset = (myLocale.day * 24 * 60) + (myLocale.hour * 60) + (myLocale.minute);
    return myLocaleOffset - amsterdamOffset + date.getTimezoneOffset();
}

也许可以通过使用 en-US 作为区域设置字符串来批准它,然后 str.replace 可能需要过滤逗号或其他东西。