关于dst:PHP夏令时问题

PHP Daylight Savings Time Issue

我有以下功能,用于获取正确的时间,并用于我的网站。
不幸的是,它不会检查夏令时并导致时间错误。我想知道是否有人有可能的解决方案或帮我解决我的问题?

我是PHP编码的新手,我仍然站在它的立足点。如果有人能够帮助我将来自动切换它将会非常有用。

这是功能:

1
2
3
4
5
6
7
8
9
10
function getDSTDifference() {
    $timezone = date_default_timezone_get();

    $newTZ = new DateTimeZone($timezone);
    $trans = $newTZ->getTransitions();

    $offset = $trans[0]['offset'] /60 /60;

    return $offeset;
}

- -编辑 - -

为了更好地澄清我想说的话:

我有一个监控通话时间的网站。在DST和常规时间之间切换期间,这些呼叫时间会关闭一小时(反之亦然)。例如,上周末导致时间显示如下:-57:01:23。而不是按照它的方式使用函数 - 每次DST和常规时间切换时,我必须手动进入并取消注释/注释掉两行代码,是否有可能的解决方案使函数能够执行这个自动?有点像一个更永久的解决方案。对我来说,似乎冗余编码必须不断重新审视该功能,以便做出一遍又一遍的简单改变。同样,我之前没有做过很多关于PHP代码的工作,因此我不熟悉可以使用的内置函数,或者我必须自己创建它。如果有人会有一些信息/帮助来解决这个问题,我将不胜感激。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function getDSTDifference() {
    $timezone = date_default_timezone_get();

    $NewTZ = new DateTimeZone($timezone);
    $transition = $NewTZ->getTransitions();

    $offset = $transition[0]['offset'] /60 /60;

    //The following two lines need to be commented out when it is
    //daylight savings time
    //They need to be uncommented when Daylight Savings Time ends

    $dst = $transition[0]['isdst'];
    $offset = $offset - $dst;

    return $offset;
}

希望这更有意义!
在此先感谢您的帮助!


计算两个给定小时之间差异的一种可能性是使用DateTime :: diff()。在撰写此答案时,有一个PHP错误,您必须转换为UTC之前:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

$zone = new DateTimeZone('Europe/Madrid');
$start = new DateTime('2013-03-31 1:59:00 ', $zone);
$end = new DateTime('2013-03-31 3:00:00', $zone);

// Workaround for bug #63953
// No longer required since PHP/5.6.0, PHP/5.5.8 or PHP/5.4.24
$start->setTimeZone(new DateTimeZone('UTC'));
$end->setTimeZone(new DateTimeZone('UTC'));

$difference = $start->diff($end);
echo $difference->format('%H:%I:%S');

...打印00:01:00因为那是在西欧开始DST的时候。

您还可以使用Unix时间戳,它表示固定的时刻,因此不依赖于时区:

1
2
3
4
5
6
7
8
<?php

$zone = new DateTimeZone('Europe/Madrid');
$start = new DateTime('2013-03-31 1:59:00 ', $zone);
$end = new DateTime('2013-03-31 3:00:00', $zone);

$difference = $end->format('U') - $start->format('U');
echo"$difference seconds";

...打印60 seconds

编辑#1:你是什么意思?我的代码段包含示例数据,因此您可以使用实际代码对其进行测试,您将使用实际数据。您可以(并且应该)将正确的时区设置为默认值,这样您就不必每次都指定它。但即使你不这样做,服务器的时区永远不会改变 - 即使你决定每年多次将计算机移动到另一个州或国家,你仍然可以选择你所选择的固定时区(你的应用程序的时间) zone可以与您的服务器不同)。

如果你真的想要一个解决方案,要求你每年手动更改两次代码(不管是什么原因,也许是收取维护费),你最好跳过日期/时间函数并使用字符串;否则你将冒险PHP为你做计算。

编辑#2:

  • $start$end代表您的数据。我在DST前一分钟选择了样本数据,以说明差异代码工作正常。它与在PHP教程中看到时相同:Hello, World!是示例数据,用于说明echo的工作原理,但在编写应用程序时不必使用Hello, World!

  • 要使用PHP将GMT转换为EST,请创建属于GMT的日期:

    1
    2
    3
    $date = new DateTime('14:30', new DateTimeZone('GMT'));
    echo 'GMT: ' . $date->format('r') . PHP_EOL;
    // GMT: Thu, 07 Nov 2013 14:30:00 +0000

    ...然后切换到EST

    1
    2
    3
    $date->setTimeZone(new DateTimeZone('EST'));
    echo 'EST: ' . $date->format('r') . PHP_EOL;
    // EST: Thu, 07 Nov 2013 09:30:00 -0500

    但是,如果您的原始日期是格林威治标准时间,在扣除它们之前将它们转换为EST并不会带来任何好处。