新的日期() 取决于操作系统



好吧,所以我使用 javascript 通过一个简单的正则表达式返回用户系统时间的速记时区

new RegExp('\(.*\)').exec(new Date().toString())[0]; 

这在使用 chrome 的 Mac 下效果很好,例如我按预期得到 (UTC) 或 (EDT) 或 (PDT),但是一旦我们也使用 chrome 进入 Windows,此功能就会落在它的脸上,

所以 Mac 上的new Date().toString()返回

星期二 四月 08 2014 16:07:09 GMT-0400 (EDT)

new Date().toString()在窗口返回

2014 年 4 月 8 日星期二 16:08:11 GMT-0400(美国东部夏令时间)

这对我来说没有任何意义,为什么这样的事情取决于操作系统,最近 v8 中是否有导致此错误的变化,我的目标是在 Chrome 中对用户时区的速记属性进行简单的简短返回,但这是我面临的问题,我对为什么很困惑, 如果有人有解决方案或想法来强制返回速记属性,也许?我将不胜感激,提前谢谢。

我在下面回答了这个问题,https://gist.github.com/austinksmith/10281815

几件事:

  • 是的,JavaScript Date对象上的.toString()输出取决于实现。 您将在不同的操作系统、浏览器和版本上获得不同的结果。 ECMAScript 5.1 §15.9.5.2 对此定义如下:

    15.9.5.2   日期.原型.到字符串()

    此函数返回一个字符串值。字符串的内容取决于实现,但旨在以方便、人类可读的形式表示当前时区中的日期。

  • ESTEDT 等缩写并不代表整个时区。 它们具体表示适用于该特定时刻的时区。 请记住,new Date()初始化为当前的"现在"。 另请参阅时区标签维基中的"时区!=偏移量"。

  • 通常,时区缩写是不明确的。 EST 可能意味着美国的东部标准时间,也可能意味着澳大利亚的东部标准时间。 当然,他们可能会在澳大利亚使用AEST,但谁能说他们是那些在前面加上A而不是美国人的人呢? 此外,EST也可能意味着澳大利亚东部夏令时。 缩写"CST"更糟糕,有 5 种不同的解释——澳大利亚两种,美国一种,中国一种,古巴一种,并且都有不同的偏移量。 有关更多示例,请参阅维基百科上的此列表。

  • 即使在规范中定义的时区缩写的唯一标准是RFC822 §5.1中的标准:

    zone        =  "UT"  / "GMT"                ; Universal Time
                                                ; North American : UT
                /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
                /  "CST" / "CDT"                ;  Central:  - 6/ - 5
                /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
                /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
    

    但这是一种非常令人沮丧的形式,因为它只关注美国,对世界其他地区几乎没有提及。 无论如何,"军事"区域 A-Y 在 RFC1123 年被弃用。 只有"Z"代表UTC保留为现代格式,如ISO8601。

  • 你已经说了你想要的,但没有说出你为什么想要它。 如果您只是想确定用户的时区,请考虑 jsTimeZoneDetect,它将返回您的 IANA 时区标识符,例如 America/New_York 。 然后,您可以将其带回服务器。 大多数平台都有本机支持或用于处理这些的库。

您可以使用Date#toISOString来获得一致的格式。

这没有意义,因为javascript。

但是,您可以通过以下方式获取时区偏移量:

yourDate.getTimezoneOffset();

这将在几分钟内返回浏览器客户端偏移量。请参阅 getTimezoneOffset()

从未尝试过,但您尝试查找的文本归根结底是人类可读的时区描述。 例如,人们可以合理地期望它会根据语言而改变。完全有可能不同的浏览器采取了不同的方法。

IMO要针对的部分将是GMT-0400。 尽管在我看来,更好的方法是

new Date().getTimezoneOffset() / -60

我想你可以自己将其翻译成文本(加载所有时区的数组或通过 Web 服务),如果在所有浏览器上都使用相同的内容很重要。

编辑以回复评论

如果您想以编程方式使用这些信息,那么我建议改用偏移量。 如果您想将其呈现给用户,那么在我看来,您有几个选择:

  1. 使用您最初拥有的正则表达式并接受它将是一个不同浏览器/操作系统上的文本略有不同

  2. 创建从正则表达式返回的值的转换表对于最流行的浏览器/操作系统,并呈现(使用"密钥"beng 上面的正则表达式返回的值)。 如果没有匹配存在,您可以呈现正则表达式返回的值,也可以显示正则表达式返回的值回退到每个偏移量的默认转换。

  3. 结合偏移量和某种形式的 geoIP 查找,以获得最佳效果猜测区域(再次匹配您自己的文本列表呈现),也许再次使用每个偏移量的默认值。

或者,当然,上述的某种组合。 用例是什么? 为什么人类可读但跨浏览器的文本很重要?

我很欣赏提出的所有答案,这就是我想出的

getUserTz: function() {
    var tz;
    try {
      tz = new RegExp('\(.*\)').exec(new Date().toString())[0];
    } catch(e) { // IE10 and lower support
      tz = new Date().toString();
      tz = tz.replace(/[^A-Z]/g, '');
      var zones = ['ADT','AKDT','AKST','AST','CDT','EDT','EGST','EGT','EST','HADT','HAST','MDT','MST','NDT','PDT','PMDT','PMST','PST','WGST','WGT'];
      for(var i=0; i < zones.length; i++) {
        if(tz.indexOf(zones[i]) != -1) {
          tz = "(" + tz.substr(tz.indexOf(zones[i]), tz.length) + ")";
        }
      }
    }
    if(tz && tz.length <= 6) {
      return tz;
    }
    tz = tz.replace("US","");
    tz = tz.replace(/[^A-Z]/g, '');
    return "("+tz+")";
}

首先尝试我使用的原始方法,以便我在 mac 上获得例如 (EDT),然后如果返回的字符大于 6,我采用例如在 Windows 上返回的字符串

"(美国东部夏令时间)"

并去除美国,然后我去除所有小写字符,留下"EDT"和 wala,我有这个时区的简写属性,这可能没有涵盖所有可能的区域,但我目前唯一关心的是北美时区,这应该处理 90% 的用例。

如果有人想使用此代码,请随意 https://gist.github.com/austinksmith/10281815 我进行了一些更新以支持IE10及更低版本,因为返回的格式与IE11不同,请随时更新以添加对其他时区的支持:)

编辑:这已经在IE11-9,FireFox,Chrome,Safari中进行了测试,并且至少在Windows和Mac PC上跨平台工作。

它是依赖于实现的,这意味着它依赖于操作系统和浏览器,如果你想要一致的结果,它不是很可靠。

如果你想以特定的方式一致地解析它,最好的办法是在代码中手动解析它,或者使用像datejs或类似的包。

最新更新