任何时候如何确定时区是否遵守夏令时?

14

在PHP中,您可以使用类似以下代码判断特定日期是否处于夏令时期间:

$isDST = date("I", $myDate); // 1 or 0
问题在于这只告诉您某个特定时间是否处于夏令时。是否有一种可靠的方法来检查该时区任何时间是否正在执行夏令时?

编辑以澄清:

  • 澳大利亚布里斯班全年不实行夏令时,时区始终为GMT+10。
  • 澳大利亚悉尼从十月到三月实行夏令时,时区从GMT+10变更为GMT+11。

我想知道是否有现有的方法或一种实现方法的方式,可以按如下方式工作:

timezoneDoesDST('Australia/Brisbane');  // false
timezoneDoesDST('Australia/Sydney');  // true

我不明白你想要什么。你能否换一种方式重述问题?或者给出一些例子?我不知道。 - Ionuț G. Stan
这些澳大利亚人在夏令时方面有点奇怪(无意冒犯):http://www.bcl.com.au/times-daylight-saving.htm - Ionuț G. Stan
是的,在南东昆士兰州,甚至有一个政党的唯一政策就是引入夏令时。 - nickf
5个回答

15

我发现了一种使用 PHP 的 DateTimezone 类的方法(适用于 PHP 5.2+)

function timezoneDoesDST($tzId) {
    $tz = new DateTimeZone($tzId);
    $trans = $tz->getTransitions();
    return ((count($trans) && $trans[count($trans) - 1]['ts'] > time()));
}

或者,如果您正在运行PHP 5.3+版本

function timezoneDoesDST($tzId) {
    $tz = new DateTimeZone($tzId);
    return count($tz->getTransitions(time())) > 0;
}

getTransitions()函数可以提供时区每次偏移更改的信息。这包括历史数据(谁知道布里斯班在1916年实行了夏令时?),因此该函数会检查未来是否会有偏移更改。


对于布里斯班 - 我运行了第一个5.2PHP版本✅。第二个5.3PHP示例❌ - 错误地报告布里斯班正在使用夏令时。我现在使用的是7.2.8版本。 - Simon
看起来你需要检查count($tz->getTransitions(time())) > 1,因为我认为总是有一个条目。编辑:@Simon,我刚刚仔细阅读了我上面的评论,我认为我的答案解决了你的问题。 - undefined

15

实际上,nickf的方法对我不起作用,所以我进行了一些改进......

/**
* Finds wherever a TZ is experimenting dst or not
* @author hertzel Armengol <emudojo @ gmail.com>
* @params string TimeZone -> US/Pacific for example
*
*/
function timezoneExhibitsDST($tzId) {
    $tz = new DateTimeZone($tzId);
    $date = new DateTime("now",$tz);  
    $trans = $tz->getTransitions();
    foreach ($trans as $k => $t) 
      if ($t["ts"] > $date->format('U')) {
          return $trans[$k-1]['isdst'];    
    }
}

// Usage  

var_dump(timezoneExhibitsDST("US/Pacific")); --> prints false
var_dump(timezoneExhibitsDST("Europe/London")); --> prints false
var_dump(timezoneExhibitsDST("America/Chicago")); --> prints false

同一个函数调用在一个月(三月)内将返回true,希望对您有所帮助。


3

DateTimeZone::getTransitions 可能会有所帮助。

你可能可以试试:

$hasDst = date("I", strtotime('June 1')) !== date("I", strtotime('Jan 1'));

否则,您需要解析基于文本的zoneinfo数据文件。

0

日期必须在用户/服务器时区上才能正常工作,并且您不能像使用getTransitions一样使用日期范围


0

我不这么认为,但由于几乎每个观察夏令时的国家都会在一个或两个季节更改时间,因此您可以尝试在任何给定年份的四个时间点进行测试。

例如,对于2009/01/01、2009/04/01、2009/07/01和2009/10/01进行测试date("I", $date)。如果该时区处于夏令时,则其中至少有一个日期将返回1。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接