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

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

问题描述

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



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

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

更新:

我刚才一起入侵的代码(见下文)。真正令人惊讶的是,除了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');
$ b $ 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 =新的时刻(d); ('YYYY-MM-DD')+'< / td>< td>'+ m.format('YYYY-MM-DDTHH:mm ('YYYY-MM-DDTHH:mm:ss')+'< / td>< td>'+ offset +'< td>< td> ; / TD>< / TR>';
$ tbody.append($(s));
d.setDate(d.getDate()+ 1); $ d
$ b if(d window.setTimeout(function(){addDate(d)},0);
}

< / script>
< / head>
< body>
< button onclick =addDate(new Date('01 / 01/1980'));>填表< / button>
< table border =1>
< the>< tr>< th>日期>日期< th>日期< th> th> th偏移< / th> ;< / TR>< / THEAD>
< tbody id ='dates'>< / tbody>
< / table>
< / body>
< / html>


解决方案

实际上指定的行为是使用当前的DST规则,并忽视在特定的日期/时间正在审查的地方。请参阅 ES5 15.9.1.8



The ECMAScript的实现不应该试图确定确切的时间是否受到夏令时的影响,而只是在当前使用夏令时时间算法的情况下夏令时是否已经生效,从而避免了诸如采取夏令时b / b
$ b

这些规则是:将当前的DST规则应用于指定的任何时间。这导致了无用的行为,但这是ECMAScript要求的。



这可能 - 甚至可能 - 这种行为在未来的ECMAScript版本中会改变,要求使用所有时间点的实际DST规则。这并不是最初要求的,因为运输tzdata给实施者带来的负担。语言已经变得足够重要,但是,从长远来看,大概每个人都可能不得不把它吸引过来。但是我所知道的改变可能还有几年的时间,所以不要屏住呼吸。

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.

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());

UPDATE:

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

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>

解决方案

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.

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

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