Как узнать, соблюдает ли часовой пояс переход на летнее время в любое время года?

В PHP вы можете определить, находится ли данная дата в период летнего времени, используя что-то вроде этого:

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

Проблема в том, что это только говорит вам, находится ли этот момент времени в летнем времени. Есть ли надежный способ проверить, действует ли летнее время в любое время в этом часовом поясе?


Отредактируйте, чтобы уточнить:

  • В Брисбене, Австралия, переход на летнее время не осуществляется в любое время года. Круглый год это GMT + 10.
  • Сидней, Австралия, с октября по март, когда он меняется с GMT + 10 на GMT + 11.

Мне интересно, будет ли существующий метод или способ реализовать метод, который работает как таковой:

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

person nickf    schedule 19.10.2009    source источник
comment
Я не понимаю, чего ты хочешь. Не могли бы вы как-нибудь перефразировать вопрос? Или, может быть, привести какой-нибудь пример? Я не знаю.   -  person Ionuț G. Stan    schedule 19.10.2009
comment
Эти австралийцы странные (без обид) в отношении DST: bcl.com. au / times-daylight -aving.htm   -  person Ionuț G. Stan    schedule 19.10.2009
comment
Да, есть даже политическая партия, единственная политика которой - вводить летнее время в Юго-Восточном Квинсленде ...   -  person nickf    schedule 19.10.2009


Ответы (5)


Я нашел метод, который работает с использованием класса 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 году было летнее время .. кто знал?), поэтому эта функция проверяет, будет ли изменение смещения в будущем или нет.

person nickf    schedule 19.10.2009
comment
Для Брисбена - я запустил первую версию 5.2PHP ✅. Второй пример 5.3PHP ❌ - неверно сообщалось, что в Брисбене было летнее время. Я на 7.2.8 - person Simon; 26.12.2019

На самом деле метод 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 месяц (март), надеюсь, что это поможет

person hertzel    schedule 05.02.2010

Может помочь DateTimeZone :: getTransitions.

Вы, вероятно, могли бы его крыть:

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

В противном случае вам потребуется проанализировать текстовые файлы данных zoneinfo.

person Steve Clay    schedule 19.10.2009

Я так не думаю, но поскольку почти каждая страна, соблюдающая летнее время, меняет свое время на целый сезон или два, вы можете попробовать проверить 4 очка в течение любого года.

Например, проверьте date("I", $date) на 2009/01/01, 2009/04/01, 2009/07/01 и 2009/10/01. Если этот часовой пояс переходит в летнее время, то по крайней мере одна из этих дат вернет 1.

person Seb    schedule 19.10.2009

дата должна быть в часовом поясе пользователя / сервера, чтобы она работала, и вы не можете использовать диапазон с датой, как в случае с getTransitions

person hertzel    schedule 05.02.2010