Функция cot_timezone_list в Cotonti

Описание функции
Эта функция возвращает список часовых поясов, отсортированных по смещению от времени UTC. Каждый элемент списка содержит информацию о часовых поясах, такую как их идентификатор, смещение (в секундах), название и описание.

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


/**
 * Returns a list of timezones sorted by GMT offset.
 *
 * @param bool $withUtc Return 'UTC' as the first option, otherwise it won't be included
 * @param bool $dst Include DST in timezone offsets, if DST is in effect there right now
 * @return array Multidimensional array. Each timezone has the following keys:
 *  'identifier' - PHP timezone name, e.g. "America/El_Salvador"
 *  'offset' - GMT offset in seconds, e.g. -21600
 *  'title' - Localized timezone name, e.g. "America/El Salvador"
 *  'description' - Hourly GMT offset and localized name, e.g. "GMT-06:00 America/El Salvador"
 */
function cot_timezone_list($withUtc = false, $dst = false)
{
	global $Ltz;
	if (!$Ltz) {
        include cot_langfile('countries', 'core');
    }
	static $timezones = [];
	if (!$timezones) {
		$timezonelist = [];
		$regions = ['Africa', 'America', 'Antarctica', 'Asia', 'Atlantic', 'Europe', 'Indian', 'Pacific'];
		$identifiers = DateTimeZone::listIdentifiers();
		foreach ($identifiers as $timezone) {
		    $tmp = explode('/', $timezone, 2);
            $region = $tmp[0];
            $city = isset($tmp[1]) ? $tmp[1] : '';
			if (!in_array($region, $regions)) {
                continue;
            }
			$offset = cot_timezone_offset($timezone, false, $dst);
			$gmtoffset = cot_build_timezone($offset);
			$title = isset($Ltz[$timezone])
                ? $Ltz[$timezone]
                : $region . '/' . str_replace('_', ' ', $city);
			$timezonelist[] = [
				'identifier' => $timezone,
				'offset' => $offset,
				'title' => $title,
				'description' => "$gmtoffset $title",
			];
		}
        $offsets = [];
        $names = [];
		foreach ($timezonelist as $k => $tz) {
			$offsets[$k] = $tz['offset'];
			$names[$k] = $tz['title'];
		}
		array_multisort($offsets, SORT_ASC, $names, SORT_ASC, $timezonelist);
		$timezones = $timezonelist;
	}

	return $withUtc
        ? array_merge([['name' => 'UTC', 'identifier' => 'UTC', 'offset' => 0, 'description' => 'UTC']], $timezones)
        : $timezones;
}

 


Аргументы
$withUtc (bool):

Указывает, нужно ли включить часовой пояс UTC в начало списка.
По умолчанию: false.
$dst (bool):

Учитывать ли переход на летнее время (DST) при расчете смещений часовых поясов.
По умолчанию: false.


Возвращаемое значение
Функция возвращает многомерный массив, где каждый элемент имеет структуру:

identifier: строка, идентификатор часового пояса (например, "America/New_York").
offset: целое число, смещение от UTC в секундах (например, -18000 для UTC-5).
title: строка, локализованное название часового пояса (например, "America/New York").
description: строка, включающая смещение UTC и название (например, "GMT-05:00 America/New York").


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

1. Инициализация локализации и кеширования
 
global $Ltz;
if (!$Ltz) {
    include cot_langfile('countries', 'core');
}
static $timezones = [];


$Ltz: глобальная переменная, содержащая локализованные названия стран и часовых поясов.
Если она еще не загружена, подключается файл локализации через cot_langfile.
$timezones: статическая переменная для кеширования результатов.
Если список часовых поясов уже был сформирован, он не пересоздается, а возвращается из кеша.


2. Список часовых поясов
 
$timezonelist = [];
$regions = ['Africa', 'America', 'Antarctica', 'Asia', 'Atlantic', 'Europe', 'Indian', 'Pacific'];
$identifiers = DateTimeZone::listIdentifiers();
$regions: массив, содержащий допустимые регионы часовых поясов.
$identifiers: список всех часовых поясов, возвращаемый стандартным методом DateTimeZone::listIdentifiers().

3. Формирование списка часовых поясов
 
foreach ($identifiers as $timezone) {
    $tmp = explode('/', $timezone, 2);
    $region = $tmp[0];
    $city = isset($tmp[1]) ? $tmp[1] : '';
    if (!in_array($region, $regions)) {
        continue;
    }
    $offset = cot_timezone_offset($timezone, false, $dst);
    $gmtoffset = cot_build_timezone($offset);
    $title = isset($Ltz[$timezone])
        ? $Ltz[$timezone]
        : $region . '/' . str_replace('_', ' ', $city);
    $timezonelist[] = [
        'identifier' => $timezone,
        'offset' => $offset,
        'title' => $title,
        'description' => "$gmtoffset $title",
    ];
}


Разделение идентификатора часового пояса:
Идентификатор делится на регион и город. Например, "America/New_York" -> ['America', 'New_York'].

Проверка региона:
Если регион не входит в допустимые, часовой пояс пропускается.

Смещение часового пояса:
Вычисляется с помощью функции cot_timezone_offset.

Форматирование названия:
Если локализованное название доступно в $Ltz, используется оно.
Иначе используется стандартный формат "Region/City".

Добавление в список:
Каждый часовой пояс добавляется в массив $timezonelist с ключами identifier, offset, title, description.


4. Сортировка часовых поясов
 
$offsets = [];
$names = [];
foreach ($timezonelist as $k => $tz) {
    $offsets[$k] = $tz['offset'];
    $names[$k] = $tz['title'];
}
array_multisort($offsets, SORT_ASC, $names, SORT_ASC, $timezonelist);


Создаются два массива: $offsets (смещения) и $names (названия).
array_multisort сортирует часовые пояса:
Сначала по смещению (offset), затем по названию (title).

5. Добавление UTC в начало списка
 
return $withUtc
    ? array_merge([['name' => 'UTC', 'identifier' => 'UTC', 'offset' => 0, 'description' => 'UTC']], $timezones)
    : $timezones;
    
    
Если withUtc == true, добавляется элемент для UTC.
В противном случае возвращается только массив часовых поясов.


Пример использования

1. Получение списка всех часовых поясов:
 
$timezones = cot_timezone_list();
print_r($timezones);


2. Получение списка с UTC:
 
$timezones = cot_timezone_list(true);
print_r($timezones);


Пример результата:
 
[
    ['name' => 'UTC', 'identifier' => 'UTC', 'offset' => 0, 'description' => 'UTC'],
    ['identifier' => 'Africa/Abidjan', 'offset' => 0, 'title' => 'Africa/Abidjan', 'description' => 'GMT+00:00 Africa/Abidjan'],
    ['identifier' => 'America/New_York', 'offset' => -18000, 'title' => 'America/New York', 'description' => 'GMT-05:00 America/New York'],
    ...
]

 

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:51
  • Last update: 2025-01-22 19:51