Задать вопрос
@AlexKuznec

Список часовых поясов для php?

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

В идеале, хотелось бы видеть локализованный список с указанием смещений от UTC, как в операционках. К примеру, моя Windows 10 показывает часовые пояса так:
(UTC +7:00) Томск

Но, покопавшись в инете, нашел, что народ для формирования более банальных списков городят кучу кода, чтобы получить что-нибудь вроде (UTC +7) Asia/Tomsk

Также нашел вот такие танцы с бубнами:
torunar.tk/post/110241942071/php-timezone
UPD: На его основе создал свой вариант локализованного списка средствами php.

Вопрос: есть ли готовые решения для php или yii2, способные выводить этот банальный список по локали?
  • Вопрос задан
  • 6725 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
@AlexKuznec Автор вопроса
Собрал нужный код, получилась такая функция, возвращающая массив для dropDownList() из Yii2 с элементами вида:

'Asia/Krasnoyarsk' => '(UTC+07:00) Красноярск'

Массив с двумерной сортировкой, сначала по сдвигу, потом по имени.
Локализация пока слабовата, может быть поэтому IntlTimeZone class пока почти не документирован.

Кстати, внутри функции устанавливается часовой пояс UTC для вычисления сдвига по времени, я не знаю область его действия. Так что используйте с осторожностью. Вообще, часть с вычислением этого сдвига мне не нравится. Если кто знает способ лучше - напишите в комментариях.

/* robust list of timezones */
function get_list_of_timezones($locale) {

    date_default_timezone_set('UTC');

    $identifiers = DateTimeZone::listIdentifiers();
    foreach($identifiers as $i) {
        // create date time zone from identifier
        $dtz = new DateTimeZone($i);
        // create timezone from identifier
        $tz = IntlTimeZone::createTimeZone($i);
        // if IntlTimeZone is unaware of timezone ID, use identifier as name, else use localized name
        if ($tz->getID() === 'Etc/Unknown' or $i === 'UTC') $name = $i;
        else $name =  $tz->getDisplayName(false, 3, $locale);
        // time offset
        $offset = $dtz->getOffset(new DateTime());
        $sign   = ($offset < 0) ? '-' : '+';

        $tzs[] = [
            'code'   => $i,
            'name'   => '(UTC' . $sign . date('H:i', abs($offset)) . ') ' . $name,
            'offset' => $offset,
        ];
    }

    \yii\helpers\ArrayHelper::multisort($tzs, ['offset', 'name']);

    // sort by offset
//    usort($tzs, function($a, $b){
//        if ($a['offset'] > $b['offset']) {
//            return 1;
//        }
//        elseif ($a['offset'] < $b['offset']) {
//            return -1;
//        }
//        elseif ($a['name'] > $b['name']) {
//            return 1;
//        }
//        elseif ($a['name'] < $b['name']) {
//            return -1;
//        }
//        return 0;
//    });

    return array_column($tzs, 'name', 'code');
}
?>
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Sanasol
@Sanasol
нельзя просто так взять и загуглить ошибку
внезапно столкнулся с отсутствием решения из коробки

А теперь внезапно оно появилось xD
php.net/manual/ru/function.timezone-identifiers-li...
Ответ написан
BOOMER_74
@BOOMER_74
Full-Stack разработчик
Список всех зон - DateTimeZone::listIdentifiers, плюс библиотеки для работы со временем Carbon и Date. К сожалению ничего не знаю про библиотеки с переведенными зонами, поэтому Вам нужно либо дальше искать, либо самому перевести (думаю на JS есть достаточно много решений).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы