过去的夏令时转换规则的JavaScript时区错误

Bri*_*ian 23 javascript firefox timezone google-chrome node.js

2007年,我们改用夏令时的日子发生了变化.在此更改之前属于DST扩展范围内的任何日期都会在Chrome和Firefox中报告错误的时区偏移.这就像Firefox和Chrome没有注意到DST曾经有过不同日子的事实.

如果您运行以下脚本,它将报告240分钟的偏移量.这是不正确的,它应该报告300分钟.IE10正确地做到了这一点.有谁知道修复?

alert(new Date('11/04/2004').getTimezoneOffset());
Run Code Online (Sandbox Code Playgroud)

更新:

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

我最后用我自己的getTimezoneOffset替换了Date的原型,它根据硬编码表计算它.这对我们有用,因为我们只在美国做生意.这是我能想象到的最糟糕的解决方案......

<!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>
Run Code Online (Sandbox Code Playgroud)

Jef*_*den 30

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:

"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."

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.

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.

  • 圣烟!好的,那就回答了.但是......圣洁的抽烟! (6认同)
  • 哇哦哇哦哇.我想知道是否有人写过ECMAScript规范,知道这句话会产生什么可怕的影响.为什么不依靠操作系统?从操作系统获取当前规则但忽略操作系统具有所有其他规则是没有意义的.Windows有自己的,其他人都有TZDB,所以我认为这不是一个负担.有没有办法在某个地方投票? (5认同)
  • 我为IANA时区数据库驱动的JavaScript实现了一个完整但非常小的时区感知日期库.它使用`strftime`格式的完整实现执行时区感知日期数学和时区感知日期格式.目前没有其他纯JavaScript解决方案可用于时区感知日期.https://github.com/bigeasy/timezone (2认同)
  • 看起来 [ES6 的最新草案](http://t.co/uGzwA8j5Xp) 已经改变了这一点。&gt;&gt;&gt;“ECMAScript 的实现预计将尽最大努力确定本地夏令时调整。依赖于实现的算法使用有关时区的最佳可用信息来确定本地夏令时调整 DaylightSavingTA(t),测量单位为毫秒。” (2认同)