奥尔森时区偏移错误?

12

今天我注意到我的脚本将Olson时区ID转换并显示为城市和GMT偏移量的结果非常奇怪:阿根廷时区引起了我的注意,因为它们在参考GMT/UTC时显示标准(非DST)时间偏移量±0000。

我检查了我的代码,并发现了一个小错误,但与偏差无关。因此,我通过pecl更新了timezonedb至版本2012.8,但它仍然返回错误的偏移量......

这里是一些代码,可以返回America/Argentina/San_Luis时区的最后3个更改:

$timezone = new DateTimeZone('America/Argentina/San_Luis');
$transitions = $timezone->getTransitions();

echo '<pre>';
print_r(array_slice($transitions, -3, null, true));
echo '</pre>';

这是输出结果:

Array
(
    [59] => Array
        (
            [ts] => 1223784000
            [time] => 2008-10-12T04:00:00+0000
            [offset] => -10800
            [isdst] => 1
            [abbr] => WARST
        )

    [60] => Array
        (
            [ts] => 1236481200
            [time] => 2009-03-08T03:00:00+0000
            [offset] => -14400
            [isdst] => 
            [abbr] => WART
        )

    [61] => Array
        (
            [ts] => 1255233600
            [time] => 2009-10-11T04:00:00+0000
            [offset] => -10800
            [isdst] => 1
            [abbr] => WARST
        )
)

正如您所看到的,索引 59 61 是夏令时偏移量,而索引 60 是标准时间偏移量。

但是,如果您检查Time&Date网站,标准偏移应该为 -10800 (3小时),而不是 -14400

Standard time zone: UTC/GMT -3 hours
No daylight saving time in 2012
Time zone abbreviation: ART - Argentina Time

事实上,即使abbr(应该是ART,因为在2009-10-10取消了夏令时)也是错误的。

这里出了什么问题?我非常确定这与PHP 5.4.6无关,但如果有关系,请告诉我。

PS:我记得曾经读到过Olson数据库的一些法律问题,这是否相关?


更新:我编写了一个小脚本来比较PHP非夏令时偏移量和这个维基百科页面

function getStandardOffset($timezone)
{
    $timezone = new DateTimeZone($timezone);
    //$hemisphere = (ph()->Value($timezone->getLocation(), 'latitude') >= 0) ? 'north' : 'south';
    $transitions = array_reverse(array_slice($timezone->getTransitions(), -3, null, true), true);

    foreach ($transitions as $transition)
    {
        if ($transition['isdst'] == 1)
        {
            continue;
        }

        return sprintf('%+03d:%02u', $transition['offset'] / 3600, abs($transition['offset']) % 3600 / 60);
    }

    return false;
}

$diff = array();
$html = ph()->HTML->DOM(file_get_contents('http://en.wikipedia.org/wiki/List_of_tz_database_time_zones'));
$timezones = DateTimeZone::listIdentifiers();

foreach ($timezones as $timezone)
{
    $offset = str_replace('−', '-', ph()->HTML->DOM($html, sprintf('//td/a[contains(text(), "%s")]/../..', $timezone), '0.td.4.a'));

    if (strcmp($offset, getStandardOffset($timezone)) !== 0)
    {
        $diff[$timezone] = array
        (
            'php' => getStandardOffset($timezone),
            'wiki' => $offset,
        );
    }
}

echo '<pre>';
print_r($diff);
echo '</pre>';

以下时区不同:

Array
(
    [America/Argentina/San_Luis] => Array
        (
            [php] => -04:00
            [wiki] => -03:00
        )

    [Antarctica/Casey] => Array
        (
            [php] => +08:00
            [wiki] => +11:00
        )

    [Antarctica/Davis] => Array
        (
            [php] => +07:00
            [wiki] => +05:00
        )
)

虽然这不是什么大问题,但我还是很好奇为什么会发生这种情况,因为我已经安装了最新版本的Olson tzdb。


1
根据Wikipedia关于tz数据库的页面,该诉讼已经被撤销。您是否正在使用操作系统提供的PHP软件包?考虑到时区数据库的年龄,我认为不会。一些发行版会对PHP进行补丁修复,以使用操作系统提供的时区数据库,而不是PHP提供的默认数据库。 - Charles
@Charles:是的,我正在使用https://launchpad.net/~ondrej/+archive/php5,但奇怪的是,我刚刚更新了timezonedb pecl包,并在PHP信息中显示出来。在那之前,它显示的是system.0(或类似的东西)作为timezonedb版本。 - Alix Axel
给定的 Olson 时区名称的规则取决于当前日期(我不仅指 DST 转换,还包括其他更改),即您的 PHP 和 Wiki 结果可能涉及不同的日期。[我已经使用 2012h 数据库在 2012-01-01 上打印了所提供时区的 UTC 偏移量。它们与 Wiki 数字相符。](https://gist.github.com/b40b41e6b0446cc8e51a/6adb3b9d8a1aa74f4ae1ff4f709b1cefed5c4662#file_show_utcoffset.py) - jfs
1
@BoPersson:是的,但那是一个bug。应该有一个额外的转换:[61] => Array([ts] => 1255233600, [time] => 2009-10-11T04:00:00+0000, [offset] => -10800, [isdst] => 0, [abbr] => ART)... 我会尝试找到可以向IANA报告此错误的地方。 - Alix Axel
1
@Alix Axel:你能再查一下吗?我发现不同来源的数据在这些变更日期上有所不同,所以我不太确定是否匹配。即使是维基百科也说,夏令时标志可能是事实关系,而不是“真正”的关系。与dateandtime.com相比,我甚至看到了不同的日期(http://www.timeanddate.com/worldclock/timezone.html?n=613&syear=2000)。 - hakre
显示剩余6条评论
1个回答

1
我会翻译您这里的第一个例子:

我将在此处采用您的第一个示例:

[60] => Array
    (
        [ts] => 1236481200
        [time] => 2009-03-08T03:00:00+0000
        [offset] => -14400
        [isdst] => 
        [abbr] => WART
    )

然而,如果您检查时间和日期,标准时区偏移应该是-10800(3小时),而不是-14400

根据我所读的,这并不正确;根据this article,在那个时候(2009年3月3日左右),当没有夏令时时区被更改为UTC-4,如果有则为UTC-3。尽管,文章中提到的日期是3月14/15日,而不是3月8日...我不确定是什么原因导致了这种差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接