JavaScript 时区对于过去的夏令时转换规则是错误的 [英] JavaScript Time Zone is wrong for past Daylight Saving Time transition rules

查看:24
本文介绍了JavaScript 时区对于过去的夏令时转换规则是错误的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 2007 年,我们改用夏令时的日子发生了变化.在该更改之前落在 DST 扩展范围内的任何日期都会在 Chrome 和 Firefox 中报告不正确的时区偏移.就像 Firefox 和 Chrome 没有注意到 DST 过去有不同的日子一样.

In 2007, the days that we switch to daylight savings time changed. Any date that falls within the extend range of DST prior to that change is reporting an incorrect timezone offset in Chrome and Firefox. It's like Firefox and Chrome don't pay attention to the fact that DST used to have different days.

如果您运行以下脚本,它将报告 240 分钟的偏移量.那是错误的,它应该报告 300 分钟.IE10 正确执行此操作.有人知道修复吗?

If you run the following script it will report an offset of 240 minutes. That's incorrect, it should report 300 minutes. IE10 does this correctly. Does anyone know of a fix?

alert(new Date('11/04/2004').getTimezoneOffset());

更新:

这是我刚刚编写的一段有趣的代码(见下文).令人惊讶的是,除了 IE 之外,每个浏览器中的大多数日期都相差多远.比较开始和结束日期:http://www.timeanddate.com/worldclock/timezone.html?n=77&syear=2000

Here's an interesting piece of code I just hacked together (see below). It's really surprising how far off most of the dates are in every browser but IE. Compare the begin and end dates to this: http://www.timeanddate.com/worldclock/timezone.html?n=77&syear=2000

我最终只是将 Date 的 getTimezoneOffset 原型替换为我自己的原型,该原型基于硬编码表进行计算.这对我们有用,因为我们只在美国开展业务.不过,这是我能想象到的最糟糕的解决方案......

I ended up just replacing Date's prototype for getTimezoneOffset with my own that calculates it based on a hard-coded table. That works for us because we only do business in the U.S. It's about the worst possible solution I can imagine though...

<!DOCTYPE html>
<html>
    <head>
        <title>Moment Test</title>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.0.0/moment.min.js"></script>
        <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
        <script>
var lastOffset = null;
var $tbody = null;
var endDate = new Date('01/01/2021');

function addDate(d) {
    if($tbody === null)
        $tbody = $('#dates');

    var offset = d.getTimezoneOffset();
    var s = '';
    if(lastOffset != offset) {
        if(lastOffset != null)
            s = '<tr style="background-color: red;">';
        lastOffset = offset;
    }
    else {
        s = '<tr>';
    }
    var m = new moment(d);
    s += '<td>' + m.format('YYYY-MM-DD') + '</td><td>' + m.format('YYYY-MM-DDTHH:mm:ssZ') + '</td><td>' + m.format('YYYY-MM-DDTHH:mm:ss') + '</td><td>' + offset + '</td></tr>';
    $tbody.append($(s));
    d.setDate(d.getDate() + 1);

    if(d < endDate)
        window.setTimeout(function(){addDate(d)}, 0);
}

        </script>
    </head>
    <body>
        <button onclick="addDate(new Date('01/01/1980'));">Fill Table</button>
        <table border="1">
            <thead><tr><th>Date</th><th>Date 2</th><th>Date 3</th><th>TZ Offset</th></tr></thead>
            <tbody id='dates'></tbody>
        </table>
    </body>
</html>

推荐答案

使用当前 DST 规则并忽略在特定日期/时间被检查的那些规则实际上是指定的行为.参见 ES5 15.9.1.8:

It's actually specified behavior to use the current DST rules, and to ignore the ones in place at the particular date/time being examined. See ES5 15.9.1.8:

"ECMAScript 的实现不应该试图确定确切的时间是否受夏令时约束,而应该确定如果当时使用当前的夏令时算法,夏令时是否会生效.这避免复杂化,例如考虑当地全年遵守夏令时的年份."

"The implementation of ECMAScript should not try to determine whether the exact time was subject to daylight saving time, but just whether daylight saving time would have been in effect if the current daylight saving time algorithm had been used at the time. This avoids complications such as taking into account the years that the locale observed daylight saving time year round."

规则是:将当前 DST 规则应用于指定的任何时间.这会导致无意义的行为,但这正是 ECMAScript 所要求的.

The rules are: apply the current DST rules, to whatever time was specified. This results in arrant nonsense behavior, but it's what ECMAScript requires.

有可能——甚至可能——这种行为会在 ECMAScript 的未来版本中改变,要求在所有时间点都使用实际的 DST 规则.最初不需要这样做,因为它给实现者带来了传送 tzdata 的负担.然而,语言已经变得足够重要,从长远来看,可能每个人都不得不接受它.但据我所知,这种变化可能需要数年时间,所以不要屏住呼吸.

It's possible -- likely, even -- that this behavior will change in a future version of ECMAScript, to require actual DST rules at all points in time be used. This wasn't required initially because of the burden of shipping tzdata that it imposes on implementers. The language has become important enough, however, that probably everyone will just have to suck it up in the long run. But the change could be years away for all I know, so don't hold your breath on it.

这篇关于JavaScript 时区对于过去的夏令时转换规则是错误的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆