Se genera la lista de zonas horarias de forma dinámica, y por lo tanto se actualiza automáticamente cuando se podrían cambiar las zonas horarias (en PHP).
function timezone_list() {
static $timezones = null;
if ($timezones === null) {
$timezones = [];
$offsets = [];
$now = new DateTime();
foreach (DateTimeZone::listIdentifiers() as $timezone) {
$now->setTimezone(new DateTimeZone($timezone));
$offsets[] = $offset = $now->getOffset();
$timezones[$timezone] = '(' . format_GMT_offset($offset) . ') ' . format_timezone_name($timezone);
}
array_multisort($offsets, $timezones);
}
return $timezones;
}
function format_GMT_offset($offset) {
$hours = intval($offset / 3600);
$minutes = abs(intval($offset % 3600 / 60));
return 'GMT' . ($offset ? sprintf('%+03d:%02d', $hours, $minutes) : '');
}
function format_timezone_name($name) {
$name = str_replace('/', ', ', $name);
$name = str_replace('_', ' ', $name);
$name = str_replace('St ', 'St. ', $name);
return $name;
}
// Uso
$timezone = timezone_list();
echo '<pre>';
print_r($timezone);
echo '</pre>';
// Aquí es un ejemplo de la salida:
Array
(
[Pacific/Midway] => (GMT-11:00) Pacific, Midway
[Pacific/Niue] => (GMT-11:00) Pacific, Niue
[Pacific/Pago_Pago] => (GMT-11:00) Pacific, Pago Pago
[America/Adak] => (GMT-10:00) America, Adak
[Pacific/Honolulu] => (GMT-10:00) Pacific, Honolulu
[Pacific/Johnston] => (GMT-10:00) Pacific, Johnston
[Pacific/Rarotonga] => (GMT-10:00) Pacific, Rarotonga
[Pacific/Tahiti] => (GMT-10:00) Pacific, Tahiti
[Pacific/Marquesas] => (GMT-09:30) Pacific, Marquesas
[America/Anchorage] => (GMT-09:00) America, Anchorage
[America/Juneau] => (GMT-08:00) America, Juneau
[America/Metlakatla] => (GMT-08:00) America, Metlakatla
[America/Nome] => (GMT-08:00) America, Nome
[America/Sitka] => (GMT-08:00) America, Sitka
[America/Yakutat] => (GMT-08:00) America, Yakutat
[Pacific/Pitcairn] => (GMT-08:00) Pacific, Pitcairn
[America/Creston] => (GMT-07:00) America, Creston
[America/Dawson] => (GMT-07:00) America, Dawson
...
)