33

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

这是一个例子来说明它:

  • 约翰在纽约工作,距离服务器(英国)时间 -5 小时
  • 理查德在英国伦敦工作,所以与服务器时差为 0 小时。

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

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

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

4

3 回答 3

27

您需要自己了解 DST 过渡的所有细节吗?还是您只需要知道给定时区的上午 9:00 是什么时候?

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

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

只要确保您使用的是PHP 支持的时区之一。

于 2011-05-27T18:40:22.833 回答
26

正如 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;
}

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

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

... 或提供时间戳作为 date() 的第二个参数,如果您想指定除当前服务器时间之外的日期时间。

于 2012-06-14T12:02:17.687 回答
16

稍微改变我的答案: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 的偏移量,看看您是否想现在发送电子邮件。

于 2011-05-27T16:40:15.947 回答