Функция cot_timezone_offset в Cotonti

Разберем функцию cot_timezone_offset, которая вычисляет смещение от GMT для заданного часового пояса с учетом (или без учета) перехода на летнее время (DST).

Описание функции
Функция возвращает смещение часового пояса относительно GMT (UTC) в секундах или часах. Она поддерживает опцию учета перехода на летнее время и позволяет выбрать единицу измерения результата.

 


/**
 * Returns the offset from GMT in seconds or hours, with or without DST.
 * Example: Europe/Amsterdam returns 3600 (GMT+1) in the winter, but 7200 (GMT+2) in the summer (DST).
 * Whether or not to apply DST is determined automatically by PHP, but can be disabled.
 * A list of supported timezone identifiers is here: http://php.net/manual/en/timezones.php
 *
 * @param string $tz Timezone identifier (e.g. Europe/Amsterdam)
 * @param bool $hours Return hours instead of seconds
 * @param bool $dst Include DST in offset if DST is in effect right now
 * @return mixed Timezone difference in seconds (int) or hours (float)
 */
function cot_timezone_offset($tz, $hours = false, $dst = true)
{
	if (!$tz || in_array($tz, array('UTC', 'GMT', 'Universal', 'UCT', 'Zulu'))) return 0;
	try
	{
		// $origin_dtz = new DateTimeZone('UTC');
		$remote_dtz = new DateTimeZone($tz);
		if (!$dst)
		{
			// Standard offset is in Winter
			$standard_offset = $remote_dtz->getOffset(new DateTime("next year January 1"));
			// $trans = cot_timezone_transitions($tz);
			// $dstoffset = ($trans['current']['isdst']) ? $trans['current']['offset'] - $trans['previous']['offset'] : 0;
		}
		// $origin_dt = new DateTime('now', $origin_dtz);
		$remote_dt = new DateTime('now', $remote_dtz);
	}
	catch(Exception $e)
	{
		return null;
	}
	// $offset = $remote_dtz->getOffset($remote_dt) - $origin_dtz->getOffset($origin_dt) - $dstoffset;
	$offset = $dst ? $remote_dtz->getOffset($remote_dt) : $standard_offset;
	return $hours ? floatval($offset / 3600) : $offset;
}

Аргументы

$tz (string):

Идентификатор часового пояса (например, "Europe/Amsterdam").
Если указаны значения "UTC", "GMT", "Universal", "UCT", "Zulu", возвращается 0, так как они представляют нулевое смещение.

$hours (bool):

Если true, смещение возвращается в часах (тип float).
Если false, смещение возвращается в секундах (тип int).
По умолчанию: false.

$dst (bool):

Если true, учитывается летнее время (DST).
Если false, возвращается стандартное смещение (например, для зимнего времени).
По умолчанию: true.
Возвращаемое значение


Целое число (int): смещение в секундах (по умолчанию).
Число с плавающей точкой (float): смещение в часах, если $hours == true.
null: если указанный часовой пояс недействителен или произошла ошибка.


Подробный разбор кода

1. Обработка особых случаев
 
if (!$tz || in_array($tz, array('UTC', 'GMT', 'Universal', 'UCT', 'Zulu'))) return 0;
Если часовой пояс пустой ($tz == null) или равен одному из стандартных значений для UTC, сразу возвращается 0.
2. Создание объекта часового пояса
 
try
{
    $remote_dtz = new DateTimeZone($tz);
}
catch(Exception $e)
{
    return null;
}


new DateTimeZone($tz): создает объект часового пояса.
Если идентификатор недействителен, выбрасывается исключение, и функция возвращает null.

3. Обработка летнего времени (DST)
Если $dst == false, используется стандартное (зимнее) смещение:

 
if (!$dst)
{
    $standard_offset = $remote_dtz->getOffset(new DateTime("next year January 1"));
}


new DateTime("next year January 1"):

Создает объект даты для 1 января следующего года. Обычно это дата без летнего времени.
$remote_dtz->getOffset(...):
Возвращает смещение часового пояса относительно UTC в секундах.

4. Текущая дата и смещение
Если $dst == true, используется текущее смещение с учетом перехода на летнее время:

 
$remote_dt = new DateTime('now', $remote_dtz);
$offset = $dst ? $remote_dtz->getOffset($remote_dt) : $standard_offset;


new DateTime('now', $remote_dtz):
Создает объект текущей даты и времени в указанном часовом поясе.
$remote_dtz->getOffset(...):
Определяет смещение часового пояса относительно UTC для текущей даты (включая DST, если применимо).

5. Возврат значения
 
return $hours ? floatval($offset / 3600) : $offset;


Если $hours == true, смещение делится на 3600, чтобы получить значение в часах.
В противном случае возвращается смещение в секундах.

Пример использования
1. Получение смещения в секундах:
 
$offset = cot_timezone_offset('Europe/Amsterdam');
echo $offset; // Например, 3600 (GMT+1)


2. Получение смещения в часах:
 
$offsetHours = cot_timezone_offset('America/New_York', true);
echo $offsetHours; // Например, -5 (GMT-5)


3. Смещение без учета DST:
 
$offsetNoDst = cot_timezone_offset('Europe/Moscow', false, false);
echo $offsetNoDst; // Например, 10800 (GMT+3)


Возможные ошибки и исключения
Неправильный идентификатор часового пояса:

Если передан недействительный $tz, возвращается null.
Ошибки при расчете смещения:

Если объект DateTimeZone не удается создать, функция завершает выполнение с возвратом null.
Вывод
Функция cot_timezone_offset является удобным инструментом для работы с часовыми поясами, позволяя:

Учитывать переход на летнее время.
Получать смещения как в секундах, так и в часах.
Работать с различными форматами идентификаторов часовых поясов.

4 минут чтения Administrator

Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Автор контента

Administrator

Оффлайн

Administrator

Последняя авторизация: 05.07.2026 18:32

  • Страница размещена: 22.01.2025 19:52
  • Последнее обновление: 22.01.2025 19:55