Функция 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 minutes read Administrator

Comments (0)

No comments yet
Only registered users can post new comments

Article multicategories

Additional categories where this article is shown as similar.

Content author

Administrator

Offline

Administrator

Last logged: 2026-09-13 14:50

  • Page published: 2025-01-22 19:52
  • Last update: 2025-01-22 19:55