错误的Olson时区抵消?

Ali*_*xel 12 php timezone timezone-offset

今天,我发现我的脚本来转换并显示奥尔森时区ID添加到城市和GMT偏移量是生产一些非常奇怪的结果:阿根廷区引起了我的注意,因为他们显示标准(非DST)时间基准的±0000日光节约/世界标准时间.

我检查了我的代码,我发现在我的逻辑个小bug,但它是不相关的差异,所以我更新timezonedb通过pecl为版本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>';
Run Code Online (Sandbox Code Playgroud)

这是输出:

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

正如你所看到的,索引5961是DST偏移,而该指数60是一个标准的时间偏移.

但是,如果您检查时间和日期,则标准偏移量应为-10800(3小时),而不是-14400:

Standard time zone: UTC/GMT -3 hours
No daylight saving time in 2012
Time zone abbreviation: ART - Argentina Time
Run Code Online (Sandbox Code Playgroud)

事实上,即使abbr是错误的(应该是ART2009-10-10 DST停止以来).

这里出了什么问题?我很确定这是无关紧要的,但如果重要的话,我正在运行PHP 5.4.6.

PS:我记得在阅读有关Olson数据库的一些法律问题时,这可能与此有关吗?


更新:我写了一个小脚本来比较PHP非DST偏移量与这个维基百科页面:

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

以下时区不同:

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

这不是一个大问题,但我很好奇为什么会发生这种情况,因为我有最新版本的Olson tzdb.

Ja͢*_*͢ck 1

我将在这里举第一个例子:

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

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

据我所知,这不是真的。根据这篇文章,大约在那个时候(2009 年 3 月 3 日),当没有夏令时时,时区更改为 UTC-4,如果有夏令时,则时区更改为 UTC-3。不过,文章中提到的日期是 3 月 14 日,而不是 3 月 8 日……我不确定是什么导致了这种差异。