Задача
Необходимо обеспечить корректное определение времени с учетом перехода на летнее время.
Решение
Библиотека zoneinfo производит верные вычисления с учетом DST. В UNIX-системах преимущества zoneinfo обеспечивает функция putenv():
putenv('TZ=MST7MDT');
print strftime('%c');
Если zoneinfo нельзя использовать, то можно изменить жестко запрограммированные смещения часовых поясов, с учетом наличия или отсутствия поддержки DST локальным часовым поясом. Функция localtime() позволяет определить текущий статус поддержки DST:
// Определение текущего времени UTC
$now = time();
// Калифорния на 8 часов отстает от зоны UTC
$now -= 8 * 3600;
// DST действует?
$ar = localtime($now,true);
if ($ar['tm_isdst']) { $now += 3600; }
// Используем функцию gmdate() или gmstrftime()
// для печати Калифорнийского времени
print gmstrftime('%c',$now);
Обсуждение
Замена метки времени на значение смещения часового пояса относительно зоны UTC и последующий вызов функции gmdate() или gmstrftime() для вывода на печать значений функций, соответствующих часовому поясу, – это гибкий метод, работающий в любой временной зоне, но вычисления DST не совсем точны. Для коротких интервалов времени, когда DST-статус сервера отличается от статуса целевого часового пояса, результат неверен. Например, в 3:30 A.M. EDT в первое воскресенье апреля (после перехода на летнее время) в Тихоокеанском часовом поясе время (11:30 P.M.) еще зимнее. Сервер в Восточном часовом поясе, использующий этот метод, определит, что Калифорнийское время отстает от зоны UTC на семь часов, тогда как в действительности отставание составляет восемь часов. В 6:00 A.M. EDT (3:00 A.M. PDT) и Тихоокеанское и Восточное время уже учитывают DST, поэтому вычисления снова правильные (отставание Калифорнии от зоны UTC составляет восемь часов).