14

在 PHP 中,您可以通过以下方式判断给定日期是否在夏令时期间:

$isDST = date("I", $myDate); // 1 or 0

问题是这只告诉你那个时间点是否在夏令时。是否有可靠的方法来检查 DST 在该时区的任何时间是否有效?


编辑以澄清:

  • 澳大利亚布里斯班一年中的任何时候都没有夏令时。全年都是 GMT+10。
  • 澳大利亚悉尼从 10 月到 3 月从 GMT+10 变为 GMT+11。

我想知道是否会有一些现有的方法,或者实现这样的方法的方法:

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

5 回答 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 年有夏令时......谁知道?),所以这个函数检查未来是否有偏移变化。

于 2009-10-19T01:43:38.817 回答
14

实际上 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

相同的函数调用将在 1 个月(3 月)内返回 true 希望对您有所帮助

于 2010-02-05T22:34:06.793 回答
3

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

你可能会飞它:

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

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

于 2009-10-19T01:39:38.793 回答
0

我不这么认为,但由于几乎每个遵守 DST 的国家都会在一两个赛季中更改时间,因此您可以尝试在任何一年中测试 4 分。

例如,测试date("I", $date)2009/01/01、2009/04/01、2009/07/01 和 2009/10/01。如果该时区属于 DST,那么这些日期中至少有一个将返回 1。

于 2009-10-19T01:24:28.620 回答
0

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

于 2010-02-05T23:11:27.000 回答