PHP夏令时检测

Posted

技术标签:

【中文标题】PHP夏令时检测【英文标题】:PHP daylight saving time detection 【发布时间】:2011-09-03 13:20:50 【问题描述】:

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

这里有一个例子来说明它:

John 在纽约工作,距离服务器(英国)时间 -5 小时 Richard 在英国伦敦工作,因此与服务器相差 0 小时。

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

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

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

嗨,Jimmy,您能否在回复中更准确一点,而不仅仅是给我一个 PHP 函数。它并没有真正帮助我解决这个问题。干杯,尼古拉斯。 @Nicolas - 您需要在数组中找到时区,然后检查该时区的 dst 字段。 @Nicolas 我用更直接的方法修改了我的答案,并提供了关于如何处理的说明。希望对您有所帮助。 @JimmySawczuk - 请在下面查看我关于 PHP 解决方案的回答 像魅力一样工作..!!谢谢哥们..!!【参考方案2】:

您需要自己了解 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 supported timezones 之一。

【讨论】:

因为我已经在我的代码中的几个地方使用了 strtotime,我认为你的答案是最好的,即使我还有很多工作要做,特别是将它集成到我的 crontab 工作中(我'将使用TZ= 标签)。干杯 如果指定的时间在 DST 中,尤其是当它变为 -1 时,这将不起作用。 @GorillaApe 你确定吗?通过正确地为该城市进行转换,无论提到的日期是否在 DST 都应该有效。但是,请注意,当您随后将 date() 与该时间戳一起使用时,它会使用使用 date_default_timezone_set() 设置的默认时区!【参考方案3】:

正如 Jimmy 指出的,您可以使用时区转换,但这在 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() 有一个更简单的方法。例如,如果您想知道英国是否在夏令时,您可以这样做:

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

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

【讨论】:

对我来说,忽略夏令时:默认时区欧洲/巴黎,if (date('I')==1) date_default_timezone_set('Europe/London'); 因为我总是想要UTC+1 @khaled_webdev:然后使用“+01:00”时区。 date("I") 帮助我解决了一个相关问题。有布尔值很方便

以上是关于PHP夏令时检测的主要内容,如果未能解决你的问题,请参考以下文章

夏令时的PHP日期问题

PHP 处理夏令时的时区

PHP 时区问题 |英国夏令时和格林威治标准时间

检测当前是不是启用 DST

确定日期夏令时的算法?

在用户的时区显示当前时间,不要忘记夏令时