PHP夏令时检测

时间:2011-05-27 16:35:44

标签: php dst gmt binary-search-tree

我需要在当地时间上午9:00向世界各地的用户发送电子邮件。服务器在英国。我能做的是在每个用户和服务器的时间之间设置一个时间差,如果DST不存在,这将完全有效。

以下是一个例子来说明它:

  • John在纽约工作,距服务器(英国)时间-5小时
  • Richard在英国伦敦工作,与服务器有0小时的差异。

当服务器在某个星期天凌晨2:00从GMT转到GMT +1(BST)时,这意味着John现在的时差为-6H。

这个场景我仍然可以通过更新服务器本地时间以外的所有用户来处理,但是一旦我向前/向后移动所有其他用户的时间,我仍然需要一种方法来检测何时(时间和日期)居住在英国境外的用户将(或不会)将当地时间更改为可能的DST。

我需要一个PHP方法来了解/检测世界其他地方何时进入/退出夏令时。

3 个答案:

答案 0 :(得分:26)

您是否需要了解DST过渡的所有细节?或者你只是需要知道什么时候是在给定时区的上午9点?

如果是后者,PHP可以使用您的操作系统的时区数据库为您执行此操作。 strtotime()函数非常擅长“搞清楚”你的意思:

echo strtotime("today 9:00 am America/New_York");  // prints "1306501200"
echo strtotime("today 9:00 am Europe/London");     // prints "1306483200"

请确保您使用PHP supported timezones之一。

答案 1 :(得分:20)

正如Jimmy指出的那样,你可以使用时区转换,但这不适用于PHP< 5.3。因为dateTimeZone()是PHP> = 5.2.2但带参数的getTransitions()不是!在这种情况下,这是一个可以为您提供时区数据的功能,包括是否在DST中。

function timezonez($timezone = 'Europe/London'){
    $tz = new DateTimeZone($timezone);
    $transitions = $tz->getTransitions();
    if (is_array($transitions)){
        foreach ($transitions as $k => $t){
            // look for current year
            if (substr($t['time'],0,4) == date('Y')){
                $trans = $t;
                break;
            }
        }
    }
    return (isset($trans)) ? $trans : false;
}

话虽如此,如果你只需要知道时区是否在夏令时,有一个更简单的方法使用date()。例如,如果您想知道英国是否在DST中,您可以这样做:

date_default_timezone_set('Europe/London');
$bool = date('I'); // this will be 1 in DST or else 0

...或者如果要指定当前服务器时间以外的日期时间,则将时间戳作为第二个arg到date()。

答案 2 :(得分:13)

稍微改变我的回答:DateTimeZone::getTransitions看起来它会做你需要的,只要你有PHP> = 5.2。

来自文档中的评论:

<?php 
$theTime = time(); // specific date/time we're checking, in epoch seconds. 

$tz = new DateTimeZone('America/Los_Angeles'); 
$transition = $tz->getTransitions($theTime, $theTime); 

// only one array should be returned into $transition. Now get the data: 
$offset = $transition[0]['offset']; 
$abbr = $transition[0]['abbr']; 
?>

所以在这里,我们需要做的就是传入我们想要检查的时区,我们可以知道该时区是否在DST /偏移量是多少。然后,您需要检查GMT的偏移量,看看您现在是否要发送电子邮件。