用 PHP 生成时区的下拉列表

大多数站点需要一些方法来显示用户首选时区中站点上的日期。下面是 两份名单我找到了然后一个方法 使用内置的 PHP 日期时间类在 PHP5。

我需要帮助来了解在尝试从寄存器上的用户获取 UTC 偏移量时,哪一种方法最适合尝试使用。

第一:

<option value="-12">[UTC - 12] Baker Island Time</option>
<option value="-11">[UTC - 11] Niue Time, Samoa Standard Time</option>
<option value="-10">[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time</option>
<option value="-9.5">[UTC - 9:30] Marquesas Islands Time</option>
<option value="-9">[UTC - 9] Alaska Standard Time, Gambier Island Time</option>
<option value="-8">[UTC - 8] Pacific Standard Time</option>
<option value="-7">[UTC - 7] Mountain Standard Time</option>
<option value="-6">[UTC - 6] Central Standard Time</option>
<option value="-5">[UTC - 5] Eastern Standard Time</option>
<option value="-4.5">[UTC - 4:30] Venezuelan Standard Time</option>
<option value="-4">[UTC - 4] Atlantic Standard Time</option>
<option value="-3.5">[UTC - 3:30] Newfoundland Standard Time</option>
<option value="-3">[UTC - 3] Amazon Standard Time, Central Greenland Time</option>
<option value="-2">[UTC - 2] Fernando de Noronha Time, South Georgia &amp; the South Sandwich Islands Time</option>
<option value="-1">[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time</option>
<option value="0" selected="selected">[UTC] Western European Time, Greenwich Mean Time</option>
<option value="1">[UTC + 1] Central European Time, West African Time</option>
<option value="2">[UTC + 2] Eastern European Time, Central African Time</option>
<option value="3">[UTC + 3] Moscow Standard Time, Eastern African Time</option>
<option value="3.5">[UTC + 3:30] Iran Standard Time</option>
<option value="4">[UTC + 4] Gulf Standard Time, Samara Standard Time</option>
<option value="4.5">[UTC + 4:30] Afghanistan Time</option>
<option value="5">[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time</option>
<option value="5.5">[UTC + 5:30] Indian Standard Time, Sri Lanka Time</option>
<option value="5.75">[UTC + 5:45] Nepal Time</option>
<option value="6">[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time</option>
<option value="6.5">[UTC + 6:30] Cocos Islands Time, Myanmar Time</option>
<option value="7">[UTC + 7] Indochina Time, Krasnoyarsk Standard Time</option>
<option value="8">[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time</option>
<option value="8.75">[UTC + 8:45] Southeastern Western Australia Standard Time</option>
<option value="9">[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time</option>
<option value="9.5">[UTC + 9:30] Australian Central Standard Time</option>
<option value="10">[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time</option>
<option value="10.5">[UTC + 10:30] Lord Howe Standard Time</option>
<option value="11">[UTC + 11] Solomon Island Time, Magadan Standard Time</option>
<option value="11.5">[UTC + 11:30] Norfolk Island Time</option>
<option value="12">[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time</option>
<option value="12.75">[UTC + 12:45] Chatham Islands Time</option>
<option value="13">[UTC + 13] Tonga Time, Phoenix Islands Time</option>
<option value="14">[UTC + 14] Line Island Time</option>

或者使用 PHP 友好值:

<option value="Pacific/Midway">(GMT-11:00) Midway Island, Samoa</option>
<option value="America/Adak">(GMT-10:00) Hawaii-Aleutian</option>
<option value="Etc/GMT+10">(GMT-10:00) Hawaii</option>
<option value="Pacific/Marquesas">(GMT-09:30) Marquesas Islands</option>
<option value="Pacific/Gambier">(GMT-09:00) Gambier Islands</option>
<option value="America/Anchorage">(GMT-09:00) Alaska</option>
<option value="America/Ensenada">(GMT-08:00) Tijuana, Baja California</option>
<option value="Etc/GMT+8">(GMT-08:00) Pitcairn Islands</option>
<option value="America/Los_Angeles">(GMT-08:00) Pacific Time (US & Canada)</option>
<option value="America/Denver">(GMT-07:00) Mountain Time (US & Canada)</option>
<option value="America/Chihuahua">(GMT-07:00) Chihuahua, La Paz, Mazatlan</option>
<option value="America/Dawson_Creek">(GMT-07:00) Arizona</option>
<option value="America/Belize">(GMT-06:00) Saskatchewan, Central America</option>
<option value="America/Cancun">(GMT-06:00) Guadalajara, Mexico City, Monterrey</option>
<option value="Chile/EasterIsland">(GMT-06:00) Easter Island</option>
<option value="America/Chicago">(GMT-06:00) Central Time (US & Canada)</option>
<option value="America/New_York">(GMT-05:00) Eastern Time (US & Canada)</option>
<option value="America/Havana">(GMT-05:00) Cuba</option>
<option value="America/Bogota">(GMT-05:00) Bogota, Lima, Quito, Rio Branco</option>
<option value="America/Caracas">(GMT-04:30) Caracas</option>
<option value="America/Santiago">(GMT-04:00) Santiago</option>
<option value="America/La_Paz">(GMT-04:00) La Paz</option>
<option value="Atlantic/Stanley">(GMT-04:00) Faukland Islands</option>
<option value="America/Campo_Grande">(GMT-04:00) Brazil</option>
<option value="America/Goose_Bay">(GMT-04:00) Atlantic Time (Goose Bay)</option>
<option value="America/Glace_Bay">(GMT-04:00) Atlantic Time (Canada)</option>
<option value="America/St_Johns">(GMT-03:30) Newfoundland</option>
<option value="America/Araguaina">(GMT-03:00) UTC-3</option>
<option value="America/Montevideo">(GMT-03:00) Montevideo</option>
<option value="America/Miquelon">(GMT-03:00) Miquelon, St. Pierre</option>
<option value="America/Godthab">(GMT-03:00) Greenland</option>
<option value="America/Argentina/Buenos_Aires">(GMT-03:00) Buenos Aires</option>
<option value="America/Sao_Paulo">(GMT-03:00) Brasilia</option>
<option value="America/Noronha">(GMT-02:00) Mid-Atlantic</option>
<option value="Atlantic/Cape_Verde">(GMT-01:00) Cape Verde Is.</option>
<option value="Atlantic/Azores">(GMT-01:00) Azores</option>
<option value="Europe/Belfast">(GMT) Greenwich Mean Time : Belfast</option>
<option value="Europe/Dublin">(GMT) Greenwich Mean Time : Dublin</option>
<option value="Europe/Lisbon">(GMT) Greenwich Mean Time : Lisbon</option>
<option value="Europe/London">(GMT) Greenwich Mean Time : London</option>
<option value="Africa/Abidjan">(GMT) Monrovia, Reykjavik</option>
<option value="Europe/Amsterdam">(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna</option>
<option value="Europe/Belgrade">(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague</option>
<option value="Europe/Brussels">(GMT+01:00) Brussels, Copenhagen, Madrid, Paris</option>
<option value="Africa/Algiers">(GMT+01:00) West Central Africa</option>
<option value="Africa/Windhoek">(GMT+01:00) Windhoek</option>
<option value="Asia/Beirut">(GMT+02:00) Beirut</option>
<option value="Africa/Cairo">(GMT+02:00) Cairo</option>
<option value="Asia/Gaza">(GMT+02:00) Gaza</option>
<option value="Africa/Blantyre">(GMT+02:00) Harare, Pretoria</option>
<option value="Asia/Jerusalem">(GMT+02:00) Jerusalem</option>
<option value="Europe/Minsk">(GMT+02:00) Minsk</option>
<option value="Asia/Damascus">(GMT+02:00) Syria</option>
<option value="Europe/Moscow">(GMT+03:00) Moscow, St. Petersburg, Volgograd</option>
<option value="Africa/Addis_Ababa">(GMT+03:00) Nairobi</option>
<option value="Asia/Tehran">(GMT+03:30) Tehran</option>
<option value="Asia/Dubai">(GMT+04:00) Abu Dhabi, Muscat</option>
<option value="Asia/Yerevan">(GMT+04:00) Yerevan</option>
<option value="Asia/Kabul">(GMT+04:30) Kabul</option>
<option value="Asia/Yekaterinburg">(GMT+05:00) Ekaterinburg</option>
<option value="Asia/Tashkent">(GMT+05:00) Tashkent</option>
<option value="Asia/Kolkata">(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi</option>
<option value="Asia/Katmandu">(GMT+05:45) Kathmandu</option>
<option value="Asia/Dhaka">(GMT+06:00) Astana, Dhaka</option>
<option value="Asia/Novosibirsk">(GMT+06:00) Novosibirsk</option>
<option value="Asia/Rangoon">(GMT+06:30) Yangon (Rangoon)</option>
<option value="Asia/Bangkok">(GMT+07:00) Bangkok, Hanoi, Jakarta</option>
<option value="Asia/Krasnoyarsk">(GMT+07:00) Krasnoyarsk</option>
<option value="Asia/Hong_Kong">(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi</option>
<option value="Asia/Irkutsk">(GMT+08:00) Irkutsk, Ulaan Bataar</option>
<option value="Australia/Perth">(GMT+08:00) Perth</option>
<option value="Australia/Eucla">(GMT+08:45) Eucla</option>
<option value="Asia/Tokyo">(GMT+09:00) Osaka, Sapporo, Tokyo</option>
<option value="Asia/Seoul">(GMT+09:00) Seoul</option>
<option value="Asia/Yakutsk">(GMT+09:00) Yakutsk</option>
<option value="Australia/Adelaide">(GMT+09:30) Adelaide</option>
<option value="Australia/Darwin">(GMT+09:30) Darwin</option>
<option value="Australia/Brisbane">(GMT+10:00) Brisbane</option>
<option value="Australia/Hobart">(GMT+10:00) Hobart</option>
<option value="Asia/Vladivostok">(GMT+10:00) Vladivostok</option>
<option value="Australia/Lord_Howe">(GMT+10:30) Lord Howe Island</option>
<option value="Etc/GMT-11">(GMT+11:00) Solomon Is., New Caledonia</option>
<option value="Asia/Magadan">(GMT+11:00) Magadan</option>
<option value="Pacific/Norfolk">(GMT+11:30) Norfolk Island</option>
<option value="Asia/Anadyr">(GMT+12:00) Anadyr, Kamchatka</option>
<option value="Pacific/Auckland">(GMT+12:00) Auckland, Wellington</option>
<option value="Etc/GMT-12">(GMT+12:00) Fiji, Kamchatka, Marshall Is.</option>
<option value="Pacific/Chatham">(GMT+12:45) Chatham Islands</option>
<option value="Pacific/Tongatapu">(GMT+13:00) Nuku'alofa</option>
<option value="Pacific/Kiritimati">(GMT+14:00) Kiritimati</option>

或者仅仅使用 PHP 本身:

$timezones = DateTimeZone::listAbbreviations();


$cities = array();
foreach( $timezones as $key => $zones )
{
foreach( $zones as $id => $zone )
{
/**
* Only get timezones explicitely not part of "Others".
* @see http://www.php.net/manual/en/timezones.others.php
*/
if ( preg_match( '/^(America|Antartica|Arctic|Asia|Atlantic|Europe|Indian|Pacific)\//', $zone['timezone_id'] )
&& $zone['timezone_id']) {
$cities[$zone['timezone_id']][] = $key;
}
}
}


// For each city, have a comma separated list of all possible timezones for that city.
foreach( $cities as $key => $value )
$cities[$key] = join( ', ', $value);


// Only keep one city (the first and also most important) for each set of possibilities.
$cities = array_unique( $cities );


// Sort by area/city name.
ksort( $cities );

似乎最后一个版本是最安全的,因为它将随着 PHP 版本的使用而增长。当需要将时区与城市名称联系起来时,您还可以反转该数组。

135362 次浏览

第一个选项允许您从 $_ POST [‘ whateveroucalthesselect’]获取值并将其添加到 UTC。或者甚至存储该值,然后在以后需要时总是调用 UTC + userTZ 设置。对我来说很简单。如果时区频繁变化,最后一个选项将更有价值。

不是这些,而是用 PHP 准备一个带有时区的数组

$arr[0] = "(GMT+02:00) Harare, Pretoria";
$arr[1] = "(GMT+03:00) Jerusalem";

或者

$arr[0] = array("America/Campo_Grande", "(GMT+02:00) Harare, Pretoria");
$arr[1] = array("America/Israel", "(GMT+03:00) Jerusalem");

然后根据这个数组生成表单:

foreach ($arr as $k => $v)
$str .= "<option value=$k>$v[1]</option>";

然后,您可以轻松地切换不同的格式,只需在上面一行代码中进行修改。此外,验证将更加容易,而且不需要正则表达式。只需将 POST 或 GET 发送的值与数组进行比较。现在很容易设置 $arr [ $value _ send _ by _ form ][0]保存 PHP 兼容值,而 $arr [ $value _ send _ by _ form ][1]用户友好值。

我会在 PHP 中做到这一点,除非我会避免做 preg _ match 100的一些次数,并做到这一点,以生成您的列表。

$tzlist = DateTimeZone::listIdentifiers(DateTimeZone::ALL);

此外,我会使用 PHP 的名称的’时区’,忘记了 GMT 偏移量,这将根据 DST 的变化。 Phpbb 中这样的代码只是 b/c 的一种方式,它们仍然支持 PHP4,并且不能依赖于存在的 DateTime 或 DateTimeZone 对象。

我会用下面的代码来做这件事,它与已接受的答案相似(我知道代码可以被重构:) :

    $list = DateTimeZone::listAbbreviations();
$idents = DateTimeZone::listIdentifiers();


$data = $offset = $added = array();
foreach ($list as $abbr => $info) {
foreach ($info as $zone) {
if ( ! empty($zone['timezone_id'])
AND
! in_array($zone['timezone_id'], $added)
AND
in_array($zone['timezone_id'], $idents)) {
$z = new DateTimeZone($zone['timezone_id']);
$c = new DateTime(null, $z);
$zone['time'] = $c->format('H:i a');
$offset[] = $zone['offset'] = $z->getOffset($c);
$data[] = $zone;
$added[] = $zone['timezone_id'];
}
}
}


array_multisort($offset, SORT_ASC, $data);
$options = array();
foreach ($data as $key => $row) {
$options[$row['timezone_id']] = $row['time'] . ' - '
. formatOffset($row['offset'])
. ' ' . $row['timezone_id'];
}


// now you can use $options;


function formatOffset($offset) {
$hours = $offset / 3600;
$remainder = $offset % 3600;
$sign = $hours > 0 ? '+' : '-';
$hour = (int) abs($hours);
$minutes = (int) abs($remainder / 60);


if ($hour == 0 AND $minutes == 0) {
$sign = ' ';
}
return 'GMT' . $sign . str_pad($hour, 2, '0', STR_PAD_LEFT)
.':'. str_pad($minutes,2, '0');


}

它会产生这样的东西:

<option value="America/Boise" label="02:10 am - GMT-06:00 America/Boise">02:10 am - GMT-06:00 America/Boise</option>


<option value="America/Denver" label="02:10 am - GMT-06:00 America/Denver">02:10 am - GMT-06:00 America/Denver</option>
<option value="America/Edmonton" label="02:10 am - GMT-06:00 America/Edmonton">02:10 am - GMT-06:00 America/Edmonton</option>
<option value="America/Inuvik" label="02:10 am - GMT-06:00 America/Inuvik">02:10 am - GMT-06:00 America/Inuvik</option>
<option value="America/Shiprock" label="02:10 am - GMT-06:00 America/Shiprock">02:10 am - GMT-06:00 America/Shiprock</option>


<option value="America/Belize" label="02:10 am - GMT-05:00 America/Belize">02:10 am - GMT-05:00 America/Belize</option>

希望这对你有所帮助,或者激励你做出更好的选择。

您可以从这个数组中创建一个非常简单的下拉菜单(将它放在一起并进行测试是一项非常耗时的任务)。我们已经在一些应用程序中使用了这个列表。

在数据库中存储时区标识符是 非常重要,而不仅仅是像“ GMT + 2”这样的时区偏移量,因为夏令时。

更新

我更新/更正了时区列表(也是结账: https://github.com/paptamas/timezones) :

<?php
$timezones = array (
'(GMT-11:00) Midway Island' => 'Pacific/Midway',
'(GMT-11:00) Samoa' => 'Pacific/Samoa',
'(GMT-10:00) Hawaii' => 'Pacific/Honolulu',
'(GMT-09:00) Alaska' => 'US/Alaska',
'(GMT-08:00) Pacific Time (US &amp; Canada)' => 'America/Los_Angeles',
'(GMT-08:00) Tijuana' => 'America/Tijuana',
'(GMT-07:00) Arizona' => 'US/Arizona',
'(GMT-07:00) Chihuahua' => 'America/Chihuahua',
'(GMT-07:00) La Paz' => 'America/Chihuahua',
'(GMT-07:00) Mazatlan' => 'America/Mazatlan',
'(GMT-07:00) Mountain Time (US &amp; Canada)' => 'US/Mountain',
'(GMT-06:00) Central America' => 'America/Managua',
'(GMT-06:00) Central Time (US &amp; Canada)' => 'US/Central',
'(GMT-06:00) Guadalajara' => 'America/Mexico_City',
'(GMT-06:00) Mexico City' => 'America/Mexico_City',
'(GMT-06:00) Monterrey' => 'America/Monterrey',
'(GMT-06:00) Saskatchewan' => 'Canada/Saskatchewan',
'(GMT-05:00) Bogota' => 'America/Bogota',
'(GMT-05:00) Eastern Time (US &amp; Canada)' => 'US/Eastern',
'(GMT-05:00) Indiana (East)' => 'US/East-Indiana',
'(GMT-05:00) Lima' => 'America/Lima',
'(GMT-05:00) Quito' => 'America/Bogota',
'(GMT-04:00) Atlantic Time (Canada)' => 'Canada/Atlantic',
'(GMT-04:30) Caracas' => 'America/Caracas',
'(GMT-04:00) La Paz' => 'America/La_Paz',
'(GMT-04:00) Santiago' => 'America/Santiago',
'(GMT-03:30) Newfoundland' => 'Canada/Newfoundland',
'(GMT-03:00) Brasilia' => 'America/Sao_Paulo',
'(GMT-03:00) Buenos Aires' => 'America/Argentina/Buenos_Aires',
'(GMT-03:00) Georgetown' => 'America/Argentina/Buenos_Aires',
'(GMT-03:00) Greenland' => 'America/Godthab',
'(GMT-02:00) Mid-Atlantic' => 'America/Noronha',
'(GMT-01:00) Azores' => 'Atlantic/Azores',
'(GMT-01:00) Cape Verde Is.' => 'Atlantic/Cape_Verde',
'(GMT+00:00) Casablanca' => 'Africa/Casablanca',
'(GMT+00:00) Edinburgh' => 'Europe/London',
'(GMT+00:00) Greenwich Mean Time : Dublin' => 'Etc/Greenwich',
'(GMT+00:00) Lisbon' => 'Europe/Lisbon',
'(GMT+00:00) London' => 'Europe/London',
'(GMT+00:00) Monrovia' => 'Africa/Monrovia',
'(GMT+00:00) UTC' => 'UTC',
'(GMT+01:00) Amsterdam' => 'Europe/Amsterdam',
'(GMT+01:00) Belgrade' => 'Europe/Belgrade',
'(GMT+01:00) Berlin' => 'Europe/Berlin',
'(GMT+01:00) Bern' => 'Europe/Berlin',
'(GMT+01:00) Bratislava' => 'Europe/Bratislava',
'(GMT+01:00) Brussels' => 'Europe/Brussels',
'(GMT+01:00) Budapest' => 'Europe/Budapest',
'(GMT+01:00) Copenhagen' => 'Europe/Copenhagen',
'(GMT+01:00) Ljubljana' => 'Europe/Ljubljana',
'(GMT+01:00) Madrid' => 'Europe/Madrid',
'(GMT+01:00) Paris' => 'Europe/Paris',
'(GMT+01:00) Prague' => 'Europe/Prague',
'(GMT+01:00) Rome' => 'Europe/Rome',
'(GMT+01:00) Sarajevo' => 'Europe/Sarajevo',
'(GMT+01:00) Skopje' => 'Europe/Skopje',
'(GMT+01:00) Stockholm' => 'Europe/Stockholm',
'(GMT+01:00) Vienna' => 'Europe/Vienna',
'(GMT+01:00) Warsaw' => 'Europe/Warsaw',
'(GMT+01:00) West Central Africa' => 'Africa/Lagos',
'(GMT+01:00) Zagreb' => 'Europe/Zagreb',
'(GMT+02:00) Athens' => 'Europe/Athens',
'(GMT+02:00) Bucharest' => 'Europe/Bucharest',
'(GMT+02:00) Cairo' => 'Africa/Cairo',
'(GMT+02:00) Harare' => 'Africa/Harare',
'(GMT+02:00) Helsinki' => 'Europe/Helsinki',
'(GMT+02:00) Istanbul' => 'Europe/Istanbul',
'(GMT+02:00) Jerusalem' => 'Asia/Jerusalem',
'(GMT+02:00) Kyiv' => 'Europe/Helsinki',
'(GMT+02:00) Pretoria' => 'Africa/Johannesburg',
'(GMT+02:00) Riga' => 'Europe/Riga',
'(GMT+02:00) Sofia' => 'Europe/Sofia',
'(GMT+02:00) Tallinn' => 'Europe/Tallinn',
'(GMT+02:00) Vilnius' => 'Europe/Vilnius',
'(GMT+03:00) Baghdad' => 'Asia/Baghdad',
'(GMT+03:00) Kuwait' => 'Asia/Kuwait',
'(GMT+03:00) Minsk' => 'Europe/Minsk',
'(GMT+03:00) Nairobi' => 'Africa/Nairobi',
'(GMT+03:00) Riyadh' => 'Asia/Riyadh',
'(GMT+03:00) Volgograd' => 'Europe/Volgograd',
'(GMT+03:30) Tehran' => 'Asia/Tehran',
'(GMT+04:00) Abu Dhabi' => 'Asia/Muscat',
'(GMT+04:00) Baku' => 'Asia/Baku',
'(GMT+04:00) Moscow' => 'Europe/Moscow',
'(GMT+04:00) Muscat' => 'Asia/Muscat',
'(GMT+04:00) St. Petersburg' => 'Europe/Moscow',
'(GMT+04:00) Tbilisi' => 'Asia/Tbilisi',
'(GMT+04:00) Yerevan' => 'Asia/Yerevan',
'(GMT+04:30) Kabul' => 'Asia/Kabul',
'(GMT+05:00) Islamabad' => 'Asia/Karachi',
'(GMT+05:00) Karachi' => 'Asia/Karachi',
'(GMT+05:00) Tashkent' => 'Asia/Tashkent',
'(GMT+05:30) Chennai' => 'Asia/Calcutta',
'(GMT+05:30) Kolkata' => 'Asia/Kolkata',
'(GMT+05:30) Mumbai' => 'Asia/Calcutta',
'(GMT+05:30) New Delhi' => 'Asia/Calcutta',
'(GMT+05:30) Sri Jayawardenepura' => 'Asia/Calcutta',
'(GMT+05:45) Kathmandu' => 'Asia/Katmandu',
'(GMT+06:00) Almaty' => 'Asia/Almaty',
'(GMT+06:00) Astana' => 'Asia/Dhaka',
'(GMT+06:00) Dhaka' => 'Asia/Dhaka',
'(GMT+06:00) Ekaterinburg' => 'Asia/Yekaterinburg',
'(GMT+06:30) Rangoon' => 'Asia/Rangoon',
'(GMT+07:00) Bangkok' => 'Asia/Bangkok',
'(GMT+07:00) Hanoi' => 'Asia/Bangkok',
'(GMT+07:00) Jakarta' => 'Asia/Jakarta',
'(GMT+07:00) Novosibirsk' => 'Asia/Novosibirsk',
'(GMT+08:00) Beijing' => 'Asia/Hong_Kong',
'(GMT+08:00) Chongqing' => 'Asia/Chongqing',
'(GMT+08:00) Hong Kong' => 'Asia/Hong_Kong',
'(GMT+08:00) Krasnoyarsk' => 'Asia/Krasnoyarsk',
'(GMT+08:00) Kuala Lumpur' => 'Asia/Kuala_Lumpur',
'(GMT+08:00) Perth' => 'Australia/Perth',
'(GMT+08:00) Singapore' => 'Asia/Singapore',
'(GMT+08:00) Taipei' => 'Asia/Taipei',
'(GMT+08:00) Ulaan Bataar' => 'Asia/Ulan_Bator',
'(GMT+08:00) Urumqi' => 'Asia/Urumqi',
'(GMT+09:00) Irkutsk' => 'Asia/Irkutsk',
'(GMT+09:00) Osaka' => 'Asia/Tokyo',
'(GMT+09:00) Sapporo' => 'Asia/Tokyo',
'(GMT+09:00) Seoul' => 'Asia/Seoul',
'(GMT+09:00) Tokyo' => 'Asia/Tokyo',
'(GMT+09:30) Adelaide' => 'Australia/Adelaide',
'(GMT+09:30) Darwin' => 'Australia/Darwin',
'(GMT+10:00) Brisbane' => 'Australia/Brisbane',
'(GMT+10:00) Canberra' => 'Australia/Canberra',
'(GMT+10:00) Guam' => 'Pacific/Guam',
'(GMT+10:00) Hobart' => 'Australia/Hobart',
'(GMT+10:00) Melbourne' => 'Australia/Melbourne',
'(GMT+10:00) Port Moresby' => 'Pacific/Port_Moresby',
'(GMT+10:00) Sydney' => 'Australia/Sydney',
'(GMT+10:00) Yakutsk' => 'Asia/Yakutsk',
'(GMT+11:00) Vladivostok' => 'Asia/Vladivostok',
'(GMT+12:00) Auckland' => 'Pacific/Auckland',
'(GMT+12:00) Fiji' => 'Pacific/Fiji',
'(GMT+12:00) International Date Line West' => 'Pacific/Kwajalein',
'(GMT+12:00) Kamchatka' => 'Asia/Kamchatka',
'(GMT+12:00) Magadan' => 'Asia/Magadan',
'(GMT+12:00) Marshall Is.' => 'Pacific/Fiji',
'(GMT+12:00) New Caledonia' => 'Asia/Magadan',
'(GMT+12:00) Solomon Is.' => 'Asia/Magadan',
'(GMT+12:00) Wellington' => 'Pacific/Auckland',
'(GMT+13:00) Nuku\'alofa' => 'Pacific/Tongatapu'
);
?>

按照上面 user210179的示例,我编写了以下函数来生成所有时区及其偏移量的列表:

function generate_timezone_list()
{
static $regions = array(
DateTimeZone::AFRICA,
DateTimeZone::AMERICA,
DateTimeZone::ANTARCTICA,
DateTimeZone::ASIA,
DateTimeZone::ATLANTIC,
DateTimeZone::AUSTRALIA,
DateTimeZone::EUROPE,
DateTimeZone::INDIAN,
DateTimeZone::PACIFIC,
);


$timezones = array();
foreach( $regions as $region )
{
$timezones = array_merge( $timezones, DateTimeZone::listIdentifiers( $region ) );
}


$timezone_offsets = array();
foreach( $timezones as $timezone )
{
$tz = new DateTimeZone($timezone);
$timezone_offsets[$timezone] = $tz->getOffset(new DateTime);
}


// sort timezone by offset
asort($timezone_offsets);


$timezone_list = array();
foreach( $timezone_offsets as $timezone => $offset )
{
$offset_prefix = $offset < 0 ? '-' : '+';
$offset_formatted = gmdate( 'H:i', abs($offset) );


$pretty_offset = "UTC${offset_prefix}${offset_formatted}";


$timezone_list[$timezone] = "(${pretty_offset}) $timezone";
}


return $timezone_list;
}

这将生成一个类似如下的数组:

[Pacific/Midway] => (UTC-11:00) Pacific/Midway
[Pacific/Pago_Pago] => (UTC-11:00) Pacific/Pago_Pago
[Pacific/Niue] => (UTC-11:00) Pacific/Niue
[Pacific/Honolulu] => (UTC-10:00) Pacific/Honolulu
[Pacific/Fakaofo] => (UTC-10:00) Pacific/Fakaofo
…

它目前是按偏移量排序的,但是您可以通过使用 ksort()而不是 asort()轻松地按时区名称排序。

编辑 Tamas 的回答,删除 php.net 站点说不应该再使用的所有“其他”条目。

也许没有关系,但是只要遵循最佳实践就可以了

此外,尽管这份名单将亚速尔群岛列为格林尼治标准时间 -1,但实际上我认为它与格林尼治标准时间相同(至少有时候是这样) ,但我不确定。

通过编辑在 sql 中提供这一功能,以便您可以在表单中创建下拉列表,并将用户的答案绑定到索引。

再次编辑以删除前导空间

CREATE TABLE IF NOT EXISTS `timezones` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(44) DEFAULT NULL,
`timezone` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=141 ;


--
-- Dumping data for table `timezones`
--


INSERT INTO `timezones` (`id`, `name`, `timezone`) VALUES
(1, '(GMT-11:00) Midway Island ', 'Pacific/Midway'),
(2, '(GMT-11:00) Samoa ', 'Pacific/Samoa'),
(3, '(GMT-10:00) Hawaii ', 'Pacific/Honolulu'),
(4, '(GMT-09:00) Alaska ', 'America/Anchorage'),
(5, '(GMT-08:00) Pacific Time (US &amp; Canada) ', 'America/Los_Angeles'),
(6, '(GMT-08:00) Tijuana ', 'America/Tijuana'),
(7, '(GMT-07:00) Chihuahua ', 'America/Chihuahua'),
(8, '(GMT-07:00) La Paz ', 'America/Chihuahua'),
(9, '(GMT-07:00) Mazatlan ', 'America/Mazatlan'),
(10, '(GMT-07:00) Mountain Time (US &amp; Canada) ', 'America/Denver'),
(11, '(GMT-06:00) Central America ', 'America/Managua'),
(12, '(GMT-06:00) Central Time (US &amp; Canada) ', 'America/Chicago'),
(13, '(GMT-06:00) Guadalajara ', 'America/Mexico_City'),
(14, '(GMT-06:00) Mexico City ', 'America/Mexico_City'),
(15, '(GMT-06:00) Monterrey ', 'America/Monterrey'),
(16, '(GMT-05:00) Bogota ', 'America/Bogota'),
(17, '(GMT-05:00) Eastern Time (US &amp; Canada) ', 'America/New_York'),
(18, '(GMT-05:00) Lima ', 'America/Lima'),
(19, '(GMT-05:00) Quito ', 'America/Bogota'),
(20, '(GMT-04:00) Atlantic Time (Canada) ', 'Canada/Atlantic'),
(21, '(GMT-04:30) Caracas ', 'America/Caracas'),
(22, '(GMT-04:00) La Paz ', 'America/La_Paz'),
(23, '(GMT-04:00) Santiago ', 'America/Santiago'),
(24, '(GMT-03:30) Newfoundland ', 'America/St_Johns'),
(25, '(GMT-03:00) Brasilia ', 'America/Sao_Paulo'),
(26, '(GMT-03:00) Buenos Aires ', 'America/Argentina/Buenos_Aires'),
(27, '(GMT-03:00) Georgetown ', 'America/Argentina/Buenos_Aires'),
(28, '(GMT-03:00) Greenland ', 'America/Godthab'),
(29, '(GMT-02:00) Mid-Atlantic ', 'America/Noronha'),
(30, '(GMT-01:00) Azores ', 'Atlantic/Azores'),
(31, '(GMT-01:00) Cape Verde Is. ', 'Atlantic/Cape_Verde'),
(32, '(GMT+00:00) Casablanca ', 'Africa/Casablanca'),
(33, '(GMT+00:00) Edinburgh ', 'Europe/London'),
(34, '(GMT+00:00) Dublin ', 'Europe/Dublin'),
(35, '(GMT+00:00) Lisbon ', 'Europe/Lisbon'),
(36, '(GMT+00:00) London ', 'Europe/London'),
(37, '(GMT+00:00) Monrovia ', 'Africa/Monrovia'),
(38, '(GMT+00:00) UTC ', 'UTC'),
(39, '(GMT+01:00) Amsterdam ', 'Europe/Amsterdam'),
(40, '(GMT+01:00) Belgrade ', 'Europe/Belgrade'),
(41, '(GMT+01:00) Berlin ', 'Europe/Berlin'),
(42, '(GMT+01:00) Bern ', 'Europe/Berlin'),
(43, '(GMT+01:00) Bratislava ', 'Europe/Bratislava'),
(44, '(GMT+01:00) Brussels ', 'Europe/Brussels'),
(45, '(GMT+01:00) Budapest ', 'Europe/Budapest'),
(46, '(GMT+01:00) Copenhagen ', 'Europe/Copenhagen'),
(47, '(GMT+01:00) Ljubljana ', 'Europe/Ljubljana'),
(48, '(GMT+01:00) Madrid ', 'Europe/Madrid'),
(49, '(GMT+01:00) Paris ', 'Europe/Paris'),
(50, '(GMT+01:00) Prague ', 'Europe/Prague'),
(51, '(GMT+01:00) Rome ', 'Europe/Rome'),
(52, '(GMT+01:00) Sarajevo ', 'Europe/Sarajevo'),
(53, '(GMT+01:00) Skopje ', 'Europe/Skopje'),
(54, '(GMT+01:00) Stockholm ', 'Europe/Stockholm'),
(55, '(GMT+01:00) Vienna ', 'Europe/Vienna'),
(56, '(GMT+01:00) Warsaw ', 'Europe/Warsaw'),
(57, '(GMT+01:00) West Central Africa ', 'Africa/Lagos'),
(58, '(GMT+01:00) Zagreb ', 'Europe/Zagreb'),
(59, '(GMT+02:00) Athens ', 'Europe/Athens'),
(60, '(GMT+02:00) Bucharest ', 'Europe/Bucharest'),
(61, '(GMT+02:00) Cairo ', 'Africa/Cairo'),
(62, '(GMT+02:00) Harare ', 'Africa/Harare'),
(63, '(GMT+02:00) Helsinki ', 'Europe/Helsinki'),
(64, '(GMT+02:00) Istanbul ', 'Europe/Istanbul'),
(65, '(GMT+02:00) Jerusalem ', 'Asia/Jerusalem'),
(66, '(GMT+02:00) Kyiv ', 'Europe/Helsinki'),
(67, '(GMT+02:00) Pretoria ', 'Africa/Johannesburg'),
(68, '(GMT+02:00) Riga ', 'Europe/Riga'),
(69, '(GMT+02:00) Sofia ', 'Europe/Sofia'),
(70, '(GMT+02:00) Tallinn ', 'Europe/Tallinn'),
(71, '(GMT+02:00) Vilnius ', 'Europe/Vilnius'),
(72, '(GMT+03:00) Baghdad ', 'Asia/Baghdad'),
(73, '(GMT+03:00) Kuwait ', 'Asia/Kuwait'),
(74, '(GMT+03:00) Minsk ', 'Europe/Minsk'),
(75, '(GMT+03:00) Nairobi ', 'Africa/Nairobi'),
(76, '(GMT+03:00) Riyadh ', 'Asia/Riyadh'),
(77, '(GMT+03:00) Volgograd ', 'Europe/Volgograd'),
(78, '(GMT+03:30) Tehran ', 'Asia/Tehran'),
(79, '(GMT+04:00) Abu Dhabi ', 'Asia/Muscat'),
(80, '(GMT+04:00) Baku ', 'Asia/Baku'),
(81, '(GMT+04:00) Moscow ', 'Europe/Moscow'),
(82, '(GMT+04:00) Muscat ', 'Asia/Muscat'),
(83, '(GMT+04:00) St. Petersburg ', 'Europe/Moscow'),
(84, '(GMT+04:00) Tbilisi ', 'Asia/Tbilisi'),
(85, '(GMT+04:00) Yerevan ', 'Asia/Yerevan'),
(86, '(GMT+04:30) Kabul ', 'Asia/Kabul'),
(87, '(GMT+05:00) Islamabad ', 'Asia/Karachi'),
(88, '(GMT+05:00) Karachi ', 'Asia/Karachi'),
(89, '(GMT+05:00) Tashkent ', 'Asia/Tashkent'),
(90, '(GMT+05:30) Chennai ', 'Asia/Calcutta'),
(91, '(GMT+05:30) Kolkata ', 'Asia/Kolkata'),
(92, '(GMT+05:30) Mumbai ', 'Asia/Calcutta'),
(93, '(GMT+05:30) New Delhi ', 'Asia/Calcutta'),
(94, '(GMT+05:30) Sri Jayawardenepura ', 'Asia/Calcutta'),
(95, '(GMT+05:45) Kathmandu ', 'Asia/Katmandu'),
(96, '(GMT+06:00) Almaty ', 'Asia/Almaty'),
(97, '(GMT+06:00) Astana ', 'Asia/Dhaka'),
(98, '(GMT+06:00) Dhaka ', 'Asia/Dhaka'),
(99, '(GMT+06:00) Ekaterinburg ', 'Asia/Yekaterinburg'),
(100, '(GMT+06:30) Rangoon ', 'Asia/Rangoon'),
(101, '(GMT+07:00) Bangkok ', 'Asia/Bangkok'),
(102, '(GMT+07:00) Hanoi ', 'Asia/Bangkok'),
(103, '(GMT+07:00) Jakarta ', 'Asia/Jakarta'),
(104, '(GMT+07:00) Novosibirsk ', 'Asia/Novosibirsk'),
(105, '(GMT+08:00) Beijing ', 'Asia/Hong_Kong'),
(106, '(GMT+08:00) Chongqing ', 'Asia/Chongqing'),
(107, '(GMT+08:00) Hong Kong ', 'Asia/Hong_Kong'),
(108, '(GMT+08:00) Krasnoyarsk ', 'Asia/Krasnoyarsk'),
(109, '(GMT+08:00) Kuala Lumpur ', 'Asia/Kuala_Lumpur'),
(110, '(GMT+08:00) Perth ', 'Australia/Perth'),
(111, '(GMT+08:00) Singapore ', 'Asia/Singapore'),
(112, '(GMT+08:00) Taipei ', 'Asia/Taipei'),
(113, '(GMT+08:00) Ulaan Bataar ', 'Asia/Ulan_Bator'),
(114, '(GMT+08:00) Urumqi ', 'Asia/Urumqi'),
(115, '(GMT+09:00) Irkutsk ', 'Asia/Irkutsk'),
(116, '(GMT+09:00) Osaka ', 'Asia/Tokyo'),
(117, '(GMT+09:00) Sapporo ', 'Asia/Tokyo'),
(118, '(GMT+09:00) Seoul ', 'Asia/Seoul'),
(119, '(GMT+09:00) Tokyo ', 'Asia/Tokyo'),
(120, '(GMT+09:30) Adelaide ', 'Australia/Adelaide'),
(121, '(GMT+09:30) Darwin ', 'Australia/Darwin'),
(122, '(GMT+10:00) Brisbane ', 'Australia/Brisbane'),
(123, '(GMT+10:00) Canberra ', 'Australia/Canberra'),
(124, '(GMT+10:00) Guam ', 'Pacific/Guam'),
(125, '(GMT+10:00) Hobart ', 'Australia/Hobart'),
(126, '(GMT+10:00) Melbourne ', 'Australia/Melbourne'),
(127, '(GMT+10:00) Port Moresby ', 'Pacific/Port_Moresby'),
(128, '(GMT+10:00) Sydney ', 'Australia/Sydney'),
(129, '(GMT+10:00) Yakutsk ', 'Asia/Yakutsk'),
(130, '(GMT+11:00) Vladivostok ', 'Asia/Vladivostok'),
(131, '(GMT+12:00) Auckland ', 'Pacific/Auckland'),
(132, '(GMT+12:00) Fiji ', 'Pacific/Fiji'),
(133, '(GMT+12:00) International Date Line West ', 'Pacific/Kwajalein'),
(134, '(GMT+12:00) Kamchatka ', 'Asia/Kamchatka'),
(135, '(GMT+12:00) Magadan ', 'Asia/Magadan'),
(136, '(GMT+12:00) Marshall Is. ', 'Pacific/Fiji'),
(137, '(GMT+12:00) New Caledonia ', 'Asia/Magadan'),
(138, '(GMT+12:00) Solomon Is. ', 'Asia/Magadan'),
(139, '(GMT+12:00) Wellington ', 'Pacific/Auckland'),
(140, '(GMT+13:00) Nuku\\alofa ', 'Pacific/Tongatapu');


/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

我知道这已经有了一个答案,但我看到了一个机会来改进这里的一个答案。Toland H 发布了一些非常好的代码,完全符合问题的要求。下面是 Toland H 代码的缩写和扩展版本:

  • 该函数将所有内容放置在选项标签中。只需回显出在选择标签之间返回的内容。
  • 主要改进: 该列表首先按大陆进行排序,然后根据大陆按选项组进行组织。让它非常用户友好的游客选择他们的时区。

function generate_timezone_list() {
static $allRegions = array(
DateTimeZone::AFRICA,
DateTimeZone::AMERICA,
DateTimeZone::ANTARCTICA,
DateTimeZone::ASIA,
DateTimeZone::ATLANTIC,
DateTimeZone::AUSTRALIA,
DateTimeZone::EUROPE,
DateTimeZone::INDIAN,
DateTimeZone::PACIFIC
);
// Makes it easier to create option groups next
$list = array ('AFRICA','AMERICA','ANTARCTICA','ASIA','ATLANTIC','AUSTRALIA','EUROPE','INDIAN','PACIFIC');
// Make array holding the regions (continents), they are arrays w/ all their cities
$region = array();
foreach ($allRegions as $area){
array_push ($region,DateTimeZone::listIdentifiers( $area ));
}
$count = count ($region); $i = 0; $holder = '';
// Go through each region one by one, sorting and formatting it's cities
while ($i < $count){
$chunck = $region[$i];
// Create the region (continents) option group
$holder .= '<optgroup label="---------- '.$list[$i].' ----------">';
$timezone_offsets = array();
foreach( $chunck as $timezone ){
$tz = new DateTimeZone($timezone);
$timezone_offsets[$timezone] = $tz->getOffset(new DateTime);
}
asort ($timezone_offsets);
$timezone_list = array();
foreach ($timezone_offsets as $timezone => $offset){
$offset_prefix = $offset < 0 ? '-' : '+';
$offset_formatted = gmdate( 'H:i', abs($offset) );
$pretty_offset = "UTC ${offset_prefix}${offset_formatted}";
$timezone_list[$timezone] = "(${pretty_offset}) $timezone";
}
// All the formatting is done, finish and move on to next region
foreach ($timezone_list as $key => $val){
$holder .= '<option value="'.$key.'">'.$val.'</option>';
}
$holder .= '</optgroup>';
++$i;
}
return $holder;
}
echo "<select>".generate_timezone_list()."</select>";

然后,您需要做的就是回显出在 html 选择标记之间返回的内容。你会得到一个如下的选择列表:

----- AFRICA -----
(UTC +00:00) Africa/ city name
(UTC +01:00) Africa/ city name
(UTC +02:00) Africa/ city name
(UTC +02:00) Africa/ city name
----- AMERICA -----
(UTC -09:00) America/ city name
(UTC -07:00) America/ city name
(UTC +02:00) America/ city name
(UTC +05:00) America/ city name

诸如此类。

尽管已经有了很多答案,我还是对这个问题提出了另一个解决方案:

  • 时区列表是动态生成的,因此当时区可能发生变化时会自动更新(在 PHP 中)。
  • 时区名称被美化了,例如,“美国/圣巴特勒米”变成了“美国,St. Barthelemy”。
  • 时区按偏移量和名称排序。Toland 的回答只对偏移量进行排序,导致相同偏移量内的时区组未排序。
  • 不从 DateTimeZone::listAbbreviations检索偏移量信息,因为该方法也返回 历史时区信息历史时区信息法维奥的回答确实使用这种方法,这会导致不正确的(历史)偏移量
  • 时区列表仅在首次请求时生成(并使用静态变量“缓存”)。

完整代码如下:

function timezone_list() {
static $timezones = null;


if ($timezones === null) {
$timezones = [];
$offsets = [];
$now = new DateTime('now', new DateTimeZone('UTC'));


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;
}

这是一个输出的例子

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
...
)

对于每一个区域,使用 list缩写()是没有意义的,因为它返回历史上在那里使用过的所有不同的偏移量,而不仅仅是当前的偏移量。列表的正确基础源肯定是 listIdentifier ()。

我将只生成一次列表并保存它,以避免为每个请求生成它。我可以每个月刷新一次。

另外,我可以将所有的时区信息放到一个单独的 js-script 中,并在客户端生成选择列表本身。Js-script 也可以缓存,时区不会经常更改。

另外,在客户端使用 javascript,你可以知道当前的本地时间,因此你可以找到现在有相同时间的区域(分钟可能不同,所以比较应该是近似的) ,并显示在列表的顶部,这样用户就不必滚动所有的400项。还可以在下面显示相邻区域(+/-1小时)。

也请看这个例子

<?php
function get_timezones()
{
$o = array();
$t_zones = timezone_identifiers_list();
foreach($t_zones as $a)
{
$t = '';


try
{
//this throws exception for 'US/Pacific-New'
$zone = new DateTimeZone($a);


$seconds = $zone->getOffset( new DateTime("now" , $zone) );
$hours = sprintf( "%+02d" , intval($seconds/3600));
$minutes = sprintf( "%02d" , ($seconds%3600)/60 );


$t = $a ."  [ $hours:$minutes ]" ;


$o[$a] = $t;
}


//exceptions must be catched, else a blank page
catch(Exception $e)
{
//die("Exception : " . $e->getMessage() . '<br />');
//what to do in catch ? , nothing just relax
}
}


ksort($o);


return $o;
}


$o = get_timezones();
?>


<html>
<body>
<select name="time_zone">
<?php
foreach($o as $tz => $label)
{
echo "<option value="$tz">$label</option>";
}
?>
</select>
</body>
</html>

我想为我的用户提供一些更简单的东西,就像谷歌做的那样。

$timezones = [
"AF" => [
"name" => "Afghanistan"
],
"AL" => [
"name" => "Albania"
],
"DZ" => [
"name" => "Algeria"
],
"AS" => [
"name" => "American Samoa"
],
"AD" => [
"name" => "Andorra"
],
"AQ" => [
"name" => "Antarctica"
],
"AG" => [
"name" => "Antigua & Barbuda"
],
"AR" => [
"name" => "Argentina"
],
"AM" => [
"name" => "Armenia"
],
"AU" => [
"name" => "Australia"
],
"AT" => [
"name" => "Austria"
],
"AZ" => [
"name" => "Azerbaijan"
],
"BS" => [
"name" => "Bahamas"
],
"BD" => [
"name" => "Bangladesh"
],
"BB" => [
"name" => "Barbados"
],
"BY" => [
"name" => "Belarus"
],
"BE" => [
"name" => "Belgium"
],
"BZ" => [
"name" => "Belize"
],
"BM" => [
"name" => "Bermuda"
],
"BT" => [
"name" => "Bhutan"
],
"BO" => [
"name" => "Bolivia"
],
"BA" => [
"name" => "Bosnia & Herzegovina"
],
"BR" => [
"name" => "Brazil"
],
"IO" => [
"name" => "British Indian Ocean Territory"
],
"BN" => [
"name" => "Brunei"
],
"BG" => [
"name" => "Bulgaria"
],
"CA" => [
"name" => "Canada"
],
"CV" => [
"name" => "Cape Verde"
],
"KY" => [
"name" => "Cayman Islands"
],
"TD" => [
"name" => "Chad"
],
"CL" => [
"name" => "Chile"
],
"CN" => [
"name" => "China"
],
"CX" => [
"name" => "Christmas Island"
],
"CC" => [
"name" => "Cocos (Keeling) Islands"
],
"CO" => [
"name" => "Colombia"
],
"CK" => [
"name" => "Cook Islands"
],
"CR" => [
"name" => "Costa Rica"
],
"CI" => [
"name" => "Côte d’Ivoire"
],
"HR" => [
"name" => "Croatia"
],
"CU" => [
"name" => "Cuba"
],
"CW" => [
"name" => "Curaçao"
],
"CY" => [
"name" => "Cyprus"
],
"CZ" => [
"name" => "Czech Republic"
],
"DK" => [
"name" => "Denmark"
],
"DO" => [
"name" => "Dominican Republic"
],
"EC" => [
"name" => "Ecuador"
],
"EG" => [
"name" => "Egypt"
],
"SV" => [
"name" => "El Salvador"
],
"EE" => [
"name" => "Estonia"
],
"FK" => [
"name" => "Falkland Islands (Islas Malvinas)"
],
"FO" => [
"name" => "Faroe Islands"
],
"FJ" => [
"name" => "Fiji"
],
"FI" => [
"name" => "Finland"
],
"FR" => [
"name" => "France"
],
"GF" => [
"name" => "French Guiana"
],
"PF" => [
"name" => "French Polynesia"
],
"TF" => [
"name" => "French Southern Territories"
],
"GE" => [
"name" => "Georgia"
],
"DE" => [
"name" => "Germany"
],
"GH" => [
"name" => "Ghana"
],
"GI" => [
"name" => "Gibraltar"
],
"GR" => [
"name" => "Greece"
],
"GL" => [
"name" => "Greenland"
],
"GU" => [
"name" => "Guam"
],
"GT" => [
"name" => "Guatemala"
],
"GW" => [
"name" => "Guinea-Bissau"
],
"GY" => [
"name" => "Guyana"
],
"HT" => [
"name" => "Haiti"
],
"HN" => [
"name" => "Honduras"
],
"HK" => [
"name" => "Hong Kong"
],
"HU" => [
"name" => "Hungary"
],
"IS" => [
"name" => "Iceland"
],
"IN" => [
"name" => "India"
],
"ID" => [
"name" => "Indonesia"
],
"IR" => [
"name" => "Iran"
],
"IQ" => [
"name" => "Iraq"
],
"IE" => [
"name" => "Ireland"
],
"IL" => [
"name" => "Israel"
],
"IT" => [
"name" => "Italy"
],
"JM" => [
"name" => "Jamaica"
],
"JP" => [
"name" => "Japan"
],
"JO" => [
"name" => "Jordan"
],
"KZ" => [
"name" => "Kazakhstan"
],
"KE" => [
"name" => "Kenya"
],
"KI" => [
"name" => "Kiribati"
],
"KG" => [
"name" => "Kyrgyzstan"
],
"LV" => [
"name" => "Latvia"
],
"LB" => [
"name" => "Lebanon"
],
"LR" => [
"name" => "Liberia"
],
"LY" => [
"name" => "Libya"
],
"LT" => [
"name" => "Lithuania"
],
"LU" => [
"name" => "Luxembourg"
],
"MO" => [
"name" => "Macau"
],
"MK" => [
"name" => "Macedonia (FYROM)"
],
"MY" => [
"name" => "Malaysia"
],
"MV" => [
"name" => "Maldives"
],
"MT" => [
"name" => "Malta"
],
"MH" => [
"name" => "Marshall Islands"
],
"MQ" => [
"name" => "Martinique"
],
"MU" => [
"name" => "Mauritius"
],
"MX" => [
"name" => "Mexico"
],
"FM" => [
"name" => "Micronesia"
],
"MD" => [
"name" => "Moldova"
],
"MC" => [
"name" => "Monaco"
],
"MN" => [
"name" => "Mongolia"
],
"MA" => [
"name" => "Morocco"
],
"MZ" => [
"name" => "Mozambique"
],
"MM" => [
"name" => "Myanmar (Burma)"
],
"NA" => [
"name" => "Namibia"
],
"NR" => [
"name" => "Nauru"
],
"NP" => [
"name" => "Nepal"
],
"NL" => [
"name" => "Netherlands"
],
"NC" => [
"name" => "New Caledonia"
],
"NZ" => [
"name" => "New Zealand"
],
"NI" => [
"name" => "Nicaragua"
],
"NG" => [
"name" => "Nigeria"
],
"NU" => [
"name" => "Niue"
],
"NF" => [
"name" => "Norfolk Island"
],
"KP" => [
"name" => "North Korea"
],
"MP" => [
"name" => "Northern Mariana Islands"
],
"NO" => [
"name" => "Norway"
],
"PK" => [
"name" => "Pakistan"
],
"PW" => [
"name" => "Palau"
],
"PS" => [
"name" => "Palestine"
],
"PA" => [
"name" => "Panama"
],
"PG" => [
"name" => "Papua New Guinea"
],
"PY" => [
"name" => "Paraguay"
],
"PE" => [
"name" => "Peru"
],
"PH" => [
"name" => "Philippines"
],
"PN" => [
"name" => "Pitcairn Islands"
],
"PL" => [
"name" => "Poland"
],
"PT" => [
"name" => "Portugal"
],
"PR" => [
"name" => "Puerto Rico"
],
"QA" => [
"name" => "Qatar"
],
"RE" => [
"name" => "Réunion"
],
"RO" => [
"name" => "Romania"
],
"RU" => [
"name" => "Russia"
],
"WS" => [
"name" => "Samoa"
],
"SM" => [
"name" => "San Marino"
],
"SA" => [
"name" => "Saudi Arabia"
],
"RS" => [
"name" => "Serbia"
],
"SC" => [
"name" => "Seychelles"
],
"SG" => [
"name" => "Singapore"
],
"SK" => [
"name" => "Slovakia"
],
"SI" => [
"name" => "Slovenia"
],
"SB" => [
"name" => "Solomon Islands"
],
"ZA" => [
"name" => "South Africa"
],
"GS" => [
"name" => "South Georgia & South Sandwich Islands"
],
"KR" => [
"name" => "South Korea"
],
"ES" => [
"name" => "Spain"
],
"LK" => [
"name" => "Sri Lanka"
],
"PM" => [
"name" => "St. Pierre & Miquelon"
],
"SD" => [
"name" => "Sudan"
],
"SR" => [
"name" => "Suriname"
],
"SJ" => [
"name" => "Svalbard & Jan Mayen"
],
"SE" => [
"name" => "Sweden"
],
"CH" => [
"name" => "Switzerland"
],
"SY" => [
"name" => "Syria"
],
"TW" => [
"name" => "Taiwan"
],
"TJ" => [
"name" => "Tajikistan"
],
"TH" => [
"name" => "Thailand"
],
"TL" => [
"name" => "Timor-Leste"
],
"TK" => [
"name" => "Tokelau"
],
"TO" => [
"name" => "Tonga"
],
"TT" => [
"name" => "Trinidad & Tobago"
],
"TN" => [
"name" => "Tunisia"
],
"TR" => [
"name" => "Turkey"
],
"TM" => [
"name" => "Turkmenistan"
],
"TC" => [
"name" => "Turks & Caicos Islands"
],
"TV" => [
"name" => "Tuvalu"
],
"UM" => [
"name" => "U.S. Outlying Islands"
],
"UA" => [
"name" => "Ukraine"
],
"AE" => [
"name" => "United Arab Emirates"
],
"GB" => [
"name" => "United Kingdom"
],
"US" => [
"name" => "United States"
],
"UY" => [
"name" => "Uruguay"
],
"UZ" => [
"name" => "Uzbekistan"
],
"VU" => [
"name" => "Vanuatu"
],
"VA" => [
"name" => "Vatican City"
],
"VE" => [
"name" => "Venezuela"
],
"VN" => [
"name" => "Vietnam"
],
"WF" => [
"name" => "Wallis & Futuna"
],
"EH" => [
"name" => "Western Sahara"
],
];


// taken from Toland Hon's Answer
function prettyOffset($offset) {
$offset_prefix = $offset < 0 ? '-' : '+';
$offset_formatted = gmdate( 'H:i', abs($offset) );


$pretty_offset = "UTC${offset_prefix}${offset_formatted}";


return $pretty_offset;
}


foreach ($timezones as $k => $v) {
$tz = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $k);


foreach ($tz as $value) {
$t = new DateTimeZone($value);
$offset = (new DateTime("now", $t))->getOffset();
$timezones[$k]['timezones'][$value] = prettyOffset($offset);
}
}

这给了我一个按国家分组的数组:

["US"]=>
array(2) {
["name"]=>
string(13) "United States"
["timezones"]=>
array(29) {
["America/Adak"]=>
string(9) "UTC-10:00"
["America/Anchorage"]=>
string(9) "UTC-09:00"
["America/Boise"]=>
string(9) "UTC-07:00"
["America/Chicago"]=>
string(9) "UTC-06:00"
["America/Denver"]=>
string(9) "UTC-07:00"
["America/Detroit"]=>
string(9) "UTC-05:00"
["America/Indiana/Indianapolis"]=>
string(9) "UTC-05:00"
["America/Indiana/Knox"]=>
string(9) "UTC-06:00"
["America/Indiana/Marengo"]=>
string(9) "UTC-05:00"
["America/Indiana/Petersburg"]=>
string(9) "UTC-05:00"
["America/Indiana/Tell_City"]=>
string(9) "UTC-06:00"
["America/Indiana/Vevay"]=>
string(9) "UTC-05:00"
["America/Indiana/Vincennes"]=>
string(9) "UTC-05:00"
["America/Indiana/Winamac"]=>
string(9) "UTC-05:00"
["America/Juneau"]=>
string(9) "UTC-09:00"
["America/Kentucky/Louisville"]=>
string(9) "UTC-05:00"
["America/Kentucky/Monticello"]=>
string(9) "UTC-05:00"
["America/Los_Angeles"]=>
string(9) "UTC-08:00"
["America/Menominee"]=>
string(9) "UTC-06:00"
["America/Metlakatla"]=>
string(9) "UTC-08:00"
["America/New_York"]=>
string(9) "UTC-05:00"
["America/Nome"]=>
string(9) "UTC-09:00"
["America/North_Dakota/Beulah"]=>
string(9) "UTC-06:00"
["America/North_Dakota/Center"]=>
string(9) "UTC-06:00"
["America/North_Dakota/New_Salem"]=>
string(9) "UTC-06:00"
["America/Phoenix"]=>
string(9) "UTC-07:00"
["America/Sitka"]=>
string(9) "UTC-09:00"
["America/Yakutat"]=>
string(9) "UTC-09:00"
["Pacific/Honolulu"]=>
string(9) "UTC-10:00"
}
}

这意味着现在我可以做下面这样的事情(当然是通过一些 JavaScript 技巧) : Google Analytics Timezone Settings

这个 PHP 函数为您执行 Job 返回一个数组:

function time_zonelist(){
$return = array();
$timezone_identifiers_list = timezone_identifiers_list();
foreach($timezone_identifiers_list as $timezone_identifier){
$date_time_zone = new DateTimeZone($timezone_identifier);
$date_time = new DateTime('now', $date_time_zone);
$hours = floor($date_time_zone->getOffset($date_time) / 3600);
$mins = floor(($date_time_zone->getOffset($date_time) - ($hours*3600)) / 60);
$hours = 'GMT' . ($hours < 0 ? $hours : '+'.$hours);
$mins = ($mins > 0 ? $mins : '0'.$mins);
$text = str_replace("_"," ",$timezone_identifier);
$return[$timezone_identifier] = $text.' ('.$hours.':'.$mins.')';
}
return $return;
}

这个 PHP 函数返回包括偏移量在内的所有现有时区的数组:

使用它,例如:

print_r(time_zonelist());

在尝试了这里提供的所有解决方案并且没有得到满足之后,我找到了一个符合我需要的脚本,它更加用户友好。郑重声明,我会把它作为一个可能的解决方案。我喜欢复制/粘贴解决方案:)

Script 返回一个选择,其中包含您想要预选的任何时区。

enter image description here

资料来源: https://e-tel.eu/2011/07/13/create-a-time-zone-drop-down-list-ddl-in-php/

<?php
/**
* returns a HTML formated TimeZone select
*
* PHP 5 >= 5.2.0
*
* @param $selectedTimeZone string The timezone marked as "selected"
* @return string
*/
function displayTimeZoneSelect($selectedTimeZone = 'America/New_York'){
$countryCodes = getCountryCodes();
$return = null;
foreach ($countryCodes as $country => $countryCode) {
$timezone_identifiers = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY,$countryCode);
foreach( $timezone_identifiers as $value ){
/* getTimeZoneOffset returns minutes and we need to display hours */
$offset = getTimeZoneOffset($value)/60;
/* for the GMT+1 GMT-1 display */
$offset = ( substr($offset,0,1) == "-" ? " (GMT" : " (GMT+" ) . $offset . ")";
/* America/New_York -> America/New York */
$displayValue = (str_replace('_',' ',$value));
/* Find the city */
$ex = explode("/",$displayValue);
$city = ( ($ex[2]) ? $ex[2] : $ex[1] );
/* For the special names */
$displayValue = htmlentities($country." - ".$city.$offset);
/* handle the $selectedTimeZone in the select form */
$selected = ( ($value == $selectedTimeZone) ? ' selected="selected"' : null );
$return .= '<option value="' . $value . '"' . $selected . '>'
. $displayValue
. '</option>' . PHP_EOL;
}
}


return $return;
}


/**
* ISO 3166 code list
*
* @return array The country codes in 'COUNTRY' => 'CODE' format
* @link http://www.iso.org/iso/iso_3166_code_lists ISO Website
*/
function getCountryCodes(){
$return = array(
"AFGHANISTAN"=>"AF",
"ALAND ISLANDS"=>"AX",
"ALBANIA"=>"AL",
"ALGERIA"=>"DZ",
"AMERICAN SAMOA"=>"AS",
"ANDORRA"=>"AD",
"ANGOLA"=>"AO",
"ANGUILLA"=>"AI",
"ANTARCTICA"=>"AQ",
"ANTIGUA AND BARBUDA"=>"AG",
"ARGENTINA"=>"AR",
"ARMENIA"=>"AM",
"ARUBA"=>"AW",
"AUSTRALIA"=>"AU",
"AUSTRIA"=>"AT",
"AZERBAIJAN"=>"AZ",
"BAHAMAS"=>"BS",
"BAHRAIN"=>"BH",
"BANGLADESH"=>"BD",
"BARBADOS"=>"BB",
"BELARUS"=>"BY",
"BELGIUM"=>"BE",
"BELIZE"=>"BZ",
"BENIN"=>"BJ",
"BERMUDA"=>"BM",
"BHUTAN"=>"BT",
"BOLIVIA, PLURINATIONAL STATE OF"=>"BO",
"BONAIRE, SINT EUSTATIUS AND SABA"=>"BQ",
"BOSNIA AND HERZEGOVINA"=>"BA",
"BOTSWANA"=>"BW",
"BOUVET ISLAND"=>"BV",
"BRAZIL"=>"BR",
"BRITISH INDIAN OCEAN TERRITORY"=>"IO",
"BRUNEI DARUSSALAM"=>"BN",
"BULGARIA"=>"BG",
"BURKINA FASO"=>"BF",
"BURUNDI"=>"BI",
"CAMBODIA"=>"KH",
"CAMEROON"=>"CM",
"CANADA"=>"CA",
"CAPE VERDE"=>"CV",
"CAYMAN ISLANDS"=>"KY",
"CENTRAL AFRICAN REPUBLIC"=>"CF",
"CHAD"=>"TD",
"CHILE"=>"CL",
"CHINA"=>"CN",
"CHRISTMAS ISLAND"=>"CX",
"COCOS (KEELING) ISLANDS"=>"CC",
"COLOMBIA"=>"CO",
"COMOROS"=>"KM",
"CONGO"=>"CG",
"CONGO, THE DEMOCRATIC REPUBLIC OF THE"=>"CD",
"COOK ISLANDS"=>"CK",
"COSTA RICA"=>"CR",
"CÔTE D'IVOIRE"=>"CI",
"CROATIA"=>"HR",
"CUBA"=>"CU",
"CURAÇAO"=>"CW",
"CYPRUS"=>"CY",
"CZECH REPUBLIC"=>"CZ",
"DENMARK"=>"DK",
"DJIBOUTI"=>"DJ",
"DOMINICA"=>"DM",
"DOMINICAN REPUBLIC"=>"DO",
"ECUADOR"=>"EC",
"EGYPT"=>"EG",
"EL SALVADOR"=>"SV",
"EQUATORIAL GUINEA"=>"GQ",
"ERITREA"=>"ER",
"ESTONIA"=>"EE",
"ETHIOPIA"=>"ET",
"FALKLAND ISLANDS (MALVINAS)"=>"FK",
"FAROE ISLANDS"=>"FO",
"FIJI"=>"FJ",
"FINLAND"=>"FI",
"FRANCE"=>"FR",
"FRENCH GUIANA"=>"GF",
"FRENCH POLYNESIA"=>"PF",
"FRENCH SOUTHERN TERRITORIES"=>"TF",
"GABON"=>"GA",
"GAMBIA"=>"GM",
"GEORGIA"=>"GE",
"GERMANY"=>"DE",
"GHANA"=>"GH",
"GIBRALTAR"=>"GI",
"GREECE"=>"GR",
"GREENLAND"=>"GL",
"GRENADA"=>"GD",
"GUADELOUPE"=>"GP",
"GUAM"=>"GU",
"GUATEMALA"=>"GT",
"GUERNSEY"=>"GG",
"GUINEA"=>"GN",
"GUINEA-BISSAU"=>"GW",
"GUYANA"=>"GY",
"HAITI"=>"HT",
"HEARD ISLAND AND MCDONALD ISLANDS"=>"HM",
"HOLY SEE (VATICAN CITY STATE)"=>"VA",
"HONDURAS"=>"HN",
"HONG KONG"=>"HK",
"HUNGARY"=>"HU",
"ICELAND"=>"IS",
"INDIA"=>"IN",
"INDONESIA"=>"ID",
"IRAN, ISLAMIC REPUBLIC OF"=>"IR",
"IRAQ"=>"IQ",
"IRELAND"=>"IE",
"ISLE OF MAN"=>"IM",
"ISRAEL"=>"IL",
"ITALY"=>"IT",
"JAMAICA"=>"JM",
"JAPAN"=>"JP",
"JERSEY"=>"JE",
"JORDAN"=>"JO",
"KAZAKHSTAN"=>"KZ",
"KENYA"=>"KE",
"KIRIBATI"=>"KI",
"KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF"=>"KP",
"KOREA, REPUBLIC OF"=>"KR",
"KUWAIT"=>"KW",
"KYRGYZSTAN"=>"KG",
"LAO PEOPLE'S DEMOCRATIC REPUBLIC"=>"LA",
"LATVIA"=>"LV",
"LEBANON"=>"LB",
"LESOTHO"=>"LS",
"LIBERIA"=>"LR",
"LIBYAN ARAB JAMAHIRIYA"=>"LY",
"LIECHTENSTEIN"=>"LI",
"LITHUANIA"=>"LT",
"LUXEMBOURG"=>"LU",
"MACAO"=>"MO",
"MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF"=>"MK",
"MADAGASCAR"=>"MG",
"MALAWI"=>"MW",
"MALAYSIA"=>"MY",
"MALDIVES"=>"MV",
"MALI"=>"ML",
"MALTA"=>"MT",
"MARSHALL ISLANDS"=>"MH",
"MARTINIQUE"=>"MQ",
"MAURITANIA"=>"MR",
"MAURITIUS"=>"MU",
"MAYOTTE"=>"YT",
"MEXICO"=>"MX",
"MICRONESIA, FEDERATED STATES OF"=>"FM",
"MOLDOVA, REPUBLIC OF"=>"MD",
"MONACO"=>"MC",
"MONGOLIA"=>"MN",
"MONTENEGRO"=>"ME",
"MONTSERRAT"=>"MS",
"MOROCCO"=>"MA",
"MOZAMBIQUE"=>"MZ",
"MYANMAR"=>"MM",
"NAMIBIA"=>"NA",
"NAURU"=>"NR",
"NEPAL"=>"NP",
"NETHERLANDS"=>"NL",
"NEW CALEDONIA"=>"NC",
"NEW ZEALAND"=>"NZ",
"NICARAGUA"=>"NI",
"NIGER"=>"NE",
"NIGERIA"=>"NG",
"NIUE"=>"NU",
"NORFOLK ISLAND"=>"NF",
"NORTHERN MARIANA ISLANDS"=>"MP",
"NORWAY"=>"NO",
"OMAN"=>"OM",
"PAKISTAN"=>"PK",
"PALAU"=>"PW",
"PALESTINIAN TERRITORY, OCCUPIED"=>"PS",
"PANAMA"=>"PA",
"PAPUA NEW GUINEA"=>"PG",
"PARAGUAY"=>"PY",
"PERU"=>"PE",
"PHILIPPINES"=>"PH",
"PITCAIRN"=>"PN",
"POLAND"=>"PL",
"PORTUGAL"=>"PT",
"PUERTO RICO"=>"PR",
"QATAR"=>"QA",
"RÉUNION"=>"RE",
"ROMANIA"=>"RO",
"RUSSIAN FEDERATION"=>"RU",
"RWANDA"=>"RW",
"SAINT BARTHÉLEMY"=>"BL",
"SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA"=>"SH",
"SAINT KITTS AND NEVIS"=>"KN",
"SAINT LUCIA"=>"LC",
"SAINT MARTIN (FRENCH PART)"=>"MF",
"SAINT PIERRE AND MIQUELON"=>"PM",
"SAINT VINCENT AND THE GRENADINES"=>"VC",
"SAMOA"=>"WS",
"SAN MARINO"=>"SM",
"SAO TOME AND PRINCIPE"=>"ST",
"SAUDI ARABIA"=>"SA",
"SENEGAL"=>"SN",
"SERBIA"=>"RS",
"SEYCHELLES"=>"SC",
"SIERRA LEONE"=>"SL",
"SINGAPORE"=>"SG",
"SINT MAARTEN (DUTCH PART)"=>"SX",
"SLOVAKIA"=>"SK",
"SLOVENIA"=>"SI",
"SOLOMON ISLANDS"=>"SB",
"SOMALIA"=>"SO",
"SOUTH AFRICA"=>"ZA",
"SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS"=>"GS",
"SPAIN"=>"ES",
"SRI LANKA"=>"LK",
"SUDAN"=>"SD",
"SURINAME"=>"SR",
"SVALBARD AND JAN MAYEN"=>"SJ",
"SWAZILAND"=>"SZ",
"SWEDEN"=>"SE",
"SWITZERLAND"=>"CH",
"SYRIAN ARAB REPUBLIC"=>"SY",
"TAIWAN, PROVINCE OF CHINA"=>"TW",
"TAJIKISTAN"=>"TJ",
"TANZANIA, UNITED REPUBLIC OF"=>"TZ",
"THAILAND"=>"TH",
"TIMOR-LESTE"=>"TL",
"TOGO"=>"TG",
"TOKELAU"=>"TK",
"TONGA"=>"TO",
"TRINIDAD AND TOBAGO"=>"TT",
"TUNISIA"=>"TN",
"TURKEY"=>"TR",
"TURKMENISTAN"=>"TM",
"TURKS AND CAICOS ISLANDS"=>"TC",
"TUVALU"=>"TV",
"UGANDA"=>"UG",
"UKRAINE"=>"UA",
"UNITED ARAB EMIRATES"=>"AE",
"UNITED KINGDOM"=>"GB",
"UNITED STATES"=>"US",
"UNITED STATES MINOR OUTLYING ISLANDS"=>"UM",
"URUGUAY"=>"UY",
"UZBEKISTAN"=>"UZ",
"VANUATU"=>"VU",
"VENEZUELA, BOLIVARIAN REPUBLIC OF"=>"VE",
"VIET NAM"=>"VN",
"VIRGIN ISLANDS, BRITISH"=>"VG",
"VIRGIN ISLANDS, U.S."=>"VI",
"WALLIS AND FUTUNA"=>"WF",
"WESTERN SAHARA"=>"EH",
"YEMEN"=>"YE",
"ZAMBIA"=>"ZM",
"ZIMBABWE"=>"ZW");
return $return;
}


/**
* Calculates the offset from UTC for a given timezone
*
* @return integer
*/
function getTimeZoneOffset($timeZone) {
$dateTimeZoneUTC = new DateTimeZone("UTC");
$dateTimeZoneCurrent = new DateTimeZone($timeZone);


$dateTimeUTC = new DateTime("now",$dateTimeZoneUTC);
$dateTimeCurrent = new DateTime("now",$dateTimeZoneCurrent);


$offset = (($dateTimeZoneCurrent->getOffset($dateTimeUTC))/60);
return $offset;
}
?>




<label for="timeZone">Timezone<br />
<select id="timeZone" name="timeZone">
<?php echo displayTimeZoneSelect("America/Toronto");?>
</select>
</label>

在一些项目中,拥有非洲、欧洲或太平洋的详细时区是没有意义的。所以这里有一个简短的版本

$timezoneTable = array(
"-12" => "(GMT -12:00) Eniwetok, Kwajalein",
"-11" => "(GMT -11:00) Midway Island, Samoa",
"-10" => "(GMT -10:00) Hawaii",
"-9" => "(GMT -9:00) Alaska",
"-8" => "(GMT -8:00) Pacific Time (US &amp; Canada)",
"-7" => "(GMT -7:00) Mountain Time (US &amp; Canada)",
"-6" => "(GMT -6:00) Central Time (US &amp; Canada), Mexico City",
"-5" => "(GMT -5:00) Eastern Time (US &amp; Canada), Bogota, Lima",
"-4" => "(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz",
"-3.5" => "(GMT -3:30) Newfoundland",
"-3" => "(GMT -3:00) Brazil, Buenos Aires, Georgetown",
"-2" => "(GMT -2:00) Mid-Atlantic",
"-1" => "(GMT -1:00) Azores, Cape Verde Islands",
"0" => "(GMT) Western Europe Time, London, Lisbon, Casablanca",
"1" => "(GMT +1:00) Brussels, Copenhagen, Madrid, Paris",
"2" => "(GMT +2:00) Kaliningrad, South Africa",
"3" => "(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg",
"3.5" => "(GMT +3:30) Tehran",
"4" => "(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi",
"4.5" => "(GMT +4:30) Kabul",
"5" => "(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent",
"5.5" => "(GMT +5:30) Bombay, Calcutta, Madras, New Delhi",
"6" => "(GMT +6:00) Almaty, Dhaka, Colombo",
"7" => "(GMT +7:00) Bangkok, Hanoi, Jakarta",
"8" => "(GMT +8:00) Beijing, Perth, Singapore, Hong Kong",
"9" => "(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk",
"9.5" => "(GMT +9:30) Adelaide, Darwin",
"10" => "(GMT +10:00) Eastern Australia, Guam, Vladivostok",
"11" => "(GMT +11:00) Magadan, Solomon Islands, New Caledonia",
"12" => "(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka"
);


echo "<select>";
foreach ($timezoneTable as $k => $v){
$sel = ($k==-5)?" selected":"";
echo "<option value='".$k."'".$sel.">".$v."</option>";
}
echo "</select>"

这将生成如下选择:

enter image description here

下面是一个创建的多维数组,按偏移量和尼斯化名称排序:

function timezones() {
$timezones = [];


foreach (timezone_identifiers_list() as $timezone) {
$datetime = new \DateTime('now', new DateTimeZone($timezone));
$timezones[] = [
'sort' => str_replace(':', '', $datetime->format('P')),
'offset' => $datetime->format('P'),
'name' => str_replace('_', ' ', implode(', ', explode('/', $timezone))),
'timezone' => $timezone,
];
}


usort($timezones, function($a, $b) {
return $a['sort'] - $b['sort'] ?: strcmp($a['name'], $b['name']);
});


return $timezones;
}


foreach (timezones() as $timezone) {
echo '(UTC '.$timezone['offset'].') '.$timezone['name'].'<br>';
}

回声:

(UTC -11:00) Pacific, Midway
(UTC -11:00) Pacific, Niue
(UTC -11:00) Pacific, Pago Pago
(UTC -10:00) Pacific, Honolulu
(UTC -10:00) Pacific, Johnston
(UTC -10:00) Pacific, Rarotonga
(UTC -10:00) Pacific, Tahiti
(UTC -09:30) Pacific, Marquesas
(UTC -09:00) America, Adak
(UTC -09:00) Pacific, Gambier
(UTC -08:00) America, Anchorage
(UTC -08:00) America, Juneau
...
public static function tzList()
{
$tzMap = array();
$zones = \DateTimeZone::listIdentifiers();
foreach ($zones as $zone) {
$tz = new \DateTimeZone($zone);
$now = new \DateTime("utc", $tz);
$diffInSeconds = $tz->getOffset($now);
$hours = floor($diffInSeconds / 3600);
$minutes = floor(($diffInSeconds % 3600) / 60);
$tzMap[$zone] = sprintf("%+d", $hours) . ":" . sprintf("%02d", $minutes);
}
return $tzMap;
}

当当当!就这么简单。提供一个数组,其键为 PHP 时区,值为格式为 +-Hours: Minutes 的字符串

这是我整理的一个类,混合了我认为是所有建议中最好的一个,并且以碳作为一个依赖:

namespace App\Support;


use Carbon\Carbon;
use DateTimeZone;


class Timezone
{
protected static $timezones;


public static function all(): array
{
if (static::$timezones) {
return static::$timezones;
}


$offsets   = [];
$timezones = [];


foreach (DateTimeZone::listIdentifiers() as $timezone) {


$offsets[]            = $offset = Carbon::now()->timezone($timezone)->offset;
$timezones[$timezone] = static::formatTimezoneDisplay($timezone, $offset);


array_multisort($offsets, $timezones);


}


return static::$timezones = $timezones;
}


protected static function formatTimezoneDisplay(string $timezone, string $offset): string
{
return static::formatOffset($offset) . ' (' . static::formatTimezone($timezone) . ')';
}


protected static function formatOffset(string $offset): string
{
if (!$offset) {
return 'UTC±00:00';
}


$hours   = intval($offset / 3600);
$minutes = abs(intval($offset % 3600 / 60));


return 'UTC' . sprintf('%+03d:%02d', $hours, $minutes);
}


protected static function formatTimezone(string $timezone): string
{
return str_replace(['/', '_', 'St '], [', ', ' ', 'St. '], $timezone);
}
}

您只需使用 Timezone:all(),就可以得到一个 UTC-5:00 (America, New York)格式的数组,因此您可以轻松地在前端显示选择字段。

我使用相应的 jQuery 插件为此创建了一个 PHP 类。我已经在 https://github.com/peterjtracey/timezoneWidget开源了—— PHP 代码的灵感来自另一个 stackoverflow 的答案,但我认为更优雅。JQuery 插件为选择时区提供了一个很好的界面。

对于那些使用 CodeIgniter 的用户,有一个内置的 日期助手功能称为 < strong > timezone _ menu :

$this->load->helper('date');
echo timezone_menu('GMT', 'form-control', 'dropdown-name', ['id' => 'ci-timezone']);

产生以下产出:

<select name="dropdown-name" class="form-control" id="ci-timezone">
<option value="UM12">(UTC -12:00) Baker/Howland Island</option>
<option value="UM11">(UTC -11:00) Niue</option>
<option value="UM10">(UTC -10:00) Hawaii-Aleutian Standard Time, Cook Islands, Tahiti</option>
<option value="UM95">(UTC -9:30) Marquesas Islands</option>
<option value="UM9">(UTC -9:00) Alaska Standard Time, Gambier Islands</option>
<option value="UM8">(UTC -8:00) Pacific Standard Time, Clipperton Island</option>
<option value="UM7">(UTC -7:00) Mountain Standard Time</option>
<option value="UM6">(UTC -6:00) Central Standard Time</option>
<option value="UM5">(UTC -5:00) Eastern Standard Time, Western Caribbean Standard Time</option>
<option value="UM45">(UTC -4:30) Venezuelan Standard Time</option>
<option value="UM4">(UTC -4:00) Atlantic Standard Time, Eastern Caribbean Standard Time</option>
<option value="UM35">(UTC -3:30) Newfoundland Standard Time</option>
<option value="UM3">(UTC -3:00) Argentina, Brazil, French Guiana, Uruguay</option>
<option value="UM2">(UTC -2:00) South Georgia/South Sandwich Islands</option>
<option value="UM1">(UTC -1:00) Azores, Cape Verde Islands</option>
<option value="UTC" selected="selected">(UTC) Greenwich Mean Time, Western European Time</option>
<option value="UP1">(UTC +1:00) Central European Time, West Africa Time</option>
<option value="UP2">(UTC +2:00) Central Africa Time, Eastern European Time, Kaliningrad Time</option>
<option value="UP3">(UTC +3:00) Moscow Time, East Africa Time, Arabia Standard Time</option>
<option value="UP35">(UTC +3:30) Iran Standard Time</option>
<option value="UP4">(UTC +4:00) Azerbaijan Standard Time, Samara Time</option>
<option value="UP45">(UTC +4:30) Afghanistan</option>
<option value="UP5">(UTC +5:00) Pakistan Standard Time, Yekaterinburg Time</option>
<option value="UP55">(UTC +5:30) Indian Standard Time, Sri Lanka Time</option>
<option value="UP575">(UTC +5:45) Nepal Time</option>
<option value="UP6">(UTC +6:00) Bangladesh Standard Time, Bhutan Time, Omsk Time</option>
<option value="UP65">(UTC +6:30) Cocos Islands, Myanmar</option>
<option value="UP7">(UTC +7:00) Krasnoyarsk Time, Cambodia, Laos, Thailand, Vietnam</option>
<option value="UP8">(UTC +8:00) Australian Western Standard Time, Beijing Time, Irkutsk Time</option>
<option value="UP875">(UTC +8:45) Australian Central Western Standard Time</option>
<option value="UP9">(UTC +9:00) Japan Standard Time, Korea Standard Time, Yakutsk Time</option>
<option value="UP95">(UTC +9:30) Australian Central Standard Time</option>
<option value="UP10">(UTC +10:00) Australian Eastern Standard Time, Vladivostok Time</option>
<option value="UP105">(UTC +10:30) Lord Howe Island</option>
<option value="UP11">(UTC +11:00) Srednekolymsk Time, Solomon Islands, Vanuatu</option>
<option value="UP115">(UTC +11:30) Norfolk Island</option>
<option value="UP12">(UTC +12:00) Fiji, Gilbert Islands, Kamchatka Time, New Zealand Standard Time</option>
<option value="UP1275">(UTC +12:45) Chatham Islands Standard Time</option>
<option value="UP13">(UTC +13:00) Samoa Time Zone, Phoenix Islands Time, Tonga</option>
<option value="UP14">(UTC +14:00) Line Islands</option>
</select>

变种1

结果:

...
[America/Scoresbysund] => (UTC+00:00) America/Scoresbysund
[Atlantic/Azores] => (UTC+00:00) Atlantic/Azores
[Atlantic/Reykjavik] => (UTC+00:00) Atlantic/Reykjavik
[Atlantic/St_Helena] => (UTC+00:00) Atlantic/St_Helena
[UTC] => (UTC+00:00) UTC
[Africa/Algiers] => (UTC+01:00) Africa/Algiers
[Africa/Bangui] => (UTC+01:00) Africa/Bangui
...

密码:

$tzlist = DateTimeZone::listIdentifiers(DateTimeZone::ALL);


$result = [];
foreach ($tzlist as $timezone) {
$offset = (new DateTimeZone($timezone))->getOffset(new DateTime);
$offsetPrefix = $offset < 0 ? '-' : '+';
$offsetFormatted = gmdate('H:i', abs($offset));
$utcOffset = "(UTC$offsetPrefix$offsetFormatted)";


$result[$timezone] = "${$utcOffset} $timezone";
}
asort($result);
print_r($result);

变种2

结果:

Array
(
[0] => Array
(
[value] => Africa/Abidjan
[offset] => +00:00
[text] => (UTC+00:00) Africa/Abidjan
)


[1] => Array
(
[value] => Africa/Conakry
[offset] => +00:00
[text] => (UTC+00:00) Africa/Conakry
)
...

密码:

$tzlist = DateTimeZone::listIdentifiers(DateTimeZone::ALL);


$result = [];
foreach ($tzlist as $timezone) {
$offset = (new DateTimeZone($timezone))->getOffset(new DateTime);
$offsetPrefix = $offset < 0 ? '-' : '+';
$offsetFormatted = gmdate('H:i', abs($offset));
$utcOffset = "UTC$offsetPrefix$offsetFormatted";


$result[] = [
'value' => $timezone,
'offset' => "$offsetPrefix$offsetFormatted"
// "text" => "($utcOffset) $timezone"
];
}
usort($result, function ($a, $b) { return strcmp($a["offset"], $b["offset"]); });
print_r($result);
$timezone = array(
'Pacific/Midway' => '(GMT-11:00) Midway Island, Samoa',
'America/Adak' => '(GMT-10:00) Hawaii-Aleutian',
'Etc/GMT+10' => '(GMT-10:00) Hawaii',
'Pacific/Marquesas' => '(GMT-09:30) Marquesas Islands',
'Pacific/Gambier' => '(GMT-09:00) Gambier Islands',
'America/Anchorage' => '(GMT-09:00) Alaska',
'America/Ensenada' => '(GMT-08:00) Tijuana, Baja California',
'Etc/GMT+8' => '(GMT-08:00) Pitcairn Islands',
'America/Los_Angeles' => '(GMT-08:00) Pacific Time (US & Canada)',
'America/Denver' => '(GMT-07:00) Mountain Time (US & Canada)',
'America/Chihuahua' => '(GMT-07:00) Chihuahua, La Paz, Mazatlan',
'America/Dawson_Creek' => '(GMT-07:00) Arizona',
'America/Belize' => '(GMT-06:00) Saskatchewan, Central America',
'America/Cancun' => '(GMT-06:00) Guadalajara, Mexico City, Monterrey',
'Chile/EasterIsland' => '(GMT-06:00) Easter Island',
'America/Chicago' => '(GMT-06:00) Central Time (US & Canada)',
'America/New_York' => '(GMT-05:00) Eastern Time (US & Canada)',
'America/Havana' => '(GMT-05:00) Cuba',
'America/Bogota' => '(GMT-05:00) Bogota, Lima, Quito, Rio Branco',
'America/Caracas' => '(GMT-04:30) Caracas',
'America/Santiago' => '(GMT-04:00) Santiago',
'America/La_Paz' => '(GMT-04:00) La Paz',
'Atlantic/Stanley' => '(GMT-04:00) Faukland Islands',
'America/Campo_Grande' => '(GMT-04:00) Brazil',
'America/Goose_Bay' => '(GMT-04:00) Atlantic Time (Goose Bay)',
'America/Glace_Bay' => '(GMT-04:00) Atlantic Time (Canada)',
'America/St_Johns' => '(GMT-03:30) Newfoundland',
'America/Araguaina' => '(GMT-03:00) UTC-3',
'America/Montevideo' => '(GMT-03:00) Montevideo',
'America/Miquelon' => '(GMT-03:00) Miquelon, St. Pierre',
'America/Godthab' => '(GMT-03:00) Greenland',
'America/Argentina/Buenos_Aires' => '(GMT-03:00) Buenos Aires',
'America/Sao_Paulo' => '(GMT-03:00) Brasilia',
'America/Noronha' => '(GMT-02:00) Mid-Atlantic',
'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is.',
'Atlantic/Azores' => '(GMT-01:00) Azores',
'Europe/Belfast' => '(GMT) Greenwich Mean Time : Belfast',
'Europe/Dublin' => '(GMT) Greenwich Mean Time : Dublin',
'Europe/Lisbon' => '(GMT) Greenwich Mean Time : Lisbon',
'Europe/London' => '(GMT) Greenwich Mean Time : London',
'Africa/Abidjan' => '(GMT) Monrovia, Reykjavik',
'Europe/Amsterdam' => '(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna',
'Europe/Belgrade' => '(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague',
'Europe/Brussels' => '(GMT+01:00) Brussels, Copenhagen, Madrid, Paris',
'Africa/Algiers' => '(GMT+01:00) West Central Africa',
'Africa/Windhoek' => '(GMT+01:00) Windhoek',
'Asia/Beirut' => '(GMT+02:00) Beirut',
'Africa/Cairo' => '(GMT+02:00) Cairo',
'Asia/Gaza' => '(GMT+02:00) Gaza',
'Africa/Blantyre' => '(GMT+02:00) Harare, Pretoria',
'Asia/Jerusalem' => '(GMT+02:00) Jerusalem',
'Europe/Minsk' => '(GMT+02:00) Minsk',
'Asia/Damascus' => '(GMT+02:00) Syria',
'Europe/Moscow' => '(GMT+03:00) Moscow, St. Petersburg, Volgograd',
'Africa/Addis_Ababa' => '(GMT+03:00) Nairobi',
'Asia/Tehran' => '(GMT+03:30) Tehran',
'Asia/Dubai' => '(GMT+04:00) Abu Dhabi, Muscat',
'Asia/Yerevan' => '(GMT+04:00) Yerevan',
'Asia/Kabul' => '(GMT+04:30) Kabul',
'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg',
'Asia/Tashkent' => '(GMT+05:00) Tashkent',
'Asia/Kolkata' => '(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi',
'Asia/Katmandu' => '(GMT+05:45) Kathmandu',
'Asia/Dhaka' => '(GMT+06:00) Astana, Dhaka',
'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk',
'Asia/Rangoon' => '(GMT+06:30) Yangon (Rangoon)',
'Asia/Bangkok' => '(GMT+07:00) Bangkok, Hanoi, Jakarta',
'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk',
'Asia/Hong_Kong' => '(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi',
'Asia/Irkutsk' => '(GMT+08:00) Irkutsk, Ulaan Bataar',
'Australia/Perth' => '(GMT+08:00) Perth',
'Australia/Eucla' => '(GMT+08:45) Eucla',
'Asia/Tokyo' => '(GMT+09:00) Osaka, Sapporo, Tokyo',
'Asia/Seoul' => '(GMT+09:00) Seoul',
'Asia/Yakutsk' => '(GMT+09:00) Yakutsk',
'Australia/Adelaide' => '(GMT+09:30) Adelaide',
'Australia/Darwin' => '(GMT+09:30) Darwin',
'Australia/Brisbane' => '(GMT+10:00) Brisbane',
'Australia/Hobart' => '(GMT+10:00) Hobart',
'Asia/Vladivostok' => '(GMT+10:00) Vladivostok',
'Australia/Lord_Howe' => '(GMT+10:30) Lord Howe Island',
'Etc/GMT-11' => '(GMT+11:00) Solomon Is., New Caledonia',
'Asia/Magadan' => '(GMT+11:00) Magadan',
'Pacific/Norfolk' => '(GMT+11:30) Norfolk Island',
'Asia/Anadyr' => '(GMT+12:00) Anadyr, Kamchatka',
'Pacific/Auckland' => '(GMT+12:00) Auckland, Wellington',
'Etc/GMT-12' => '(GMT+12:00) Fiji, Kamchatka, Marshall Is.',
'Pacific/Chatham' => '(GMT+12:45) Chatham Islands',
'Pacific/Tongatapu' => '(GMT+13:00) Nukualofa',
'Pacific/Kiritimati' => '(GMT+14:00) Kiritimati',


date_default_timezone_set($timezone);

我是这么做的:

php -r "echo json_encode(array_combine(DateTimeZone::listIdentifiers(DateTimeZone::ALL), DateTimeZone::listIdentifiers(DateTimeZone::ALL)));" > list-of-timezones.json

我想把这个想法留在这里:

/*----------TIME ZONE LIST---------*/
function TZList($data_type = false){
$_all_timezone_identifiers = DateTimeZone::listIdentifiers(DateTimeZone::ALL);
$TIMEZONE_LIST = array();
foreach($_all_timezone_identifiers as $k => $v){
$_tzone_group = explode("/", $_all_timezone_identifiers[$k])[0];


$_tzone_new = new DateTimeZone($_all_timezone_identifiers[$k]);
$_tzone_new_date = new DateTime("now", $_tzone_new);


$tzone_arr = array(
'timezone' => $_all_timezone_identifiers[$k],
'timediff' => $_tzone_new_date->format('P'),
'timezone_offset' => $_tzone_new_date->format('Z')/60, //minutes
'text' => "(GMT" .$_tzone_new_date->format('P') .") " .$_all_timezone_identifiers[$k]
);


//BY CONTINENT
if($data_type === true) $TIMEZONE_LIST[$_tzone_group][] = $tzone_arr; else $TIMEZONE_LIST[] = $tzone_arr;
}


//BY TIMEZONE: "America/New_York"
if(is_string($data_type)){
$key = array_search($data_type, array_column($TIMEZONE_LIST, 'timezone'));
$TIMEZONE_LIST = $key !== false ? $TIMEZONE_LIST[$key] : null;
}


return $TIMEZONE_LIST;
}
/*--------------------------------*/

谢谢你。

数组格式的美国国家时区列表。

$america_timezones_list = array(
'+00:00||America/Danmarkshavn'=>'(+00:00) Danmarkshavn',
'-01:00||America/Scoresbysund'=>'(-01:00) Scoresbysund',
'-02:00||America/Miquelon'=>'(-02:00) Miquelon',
'-02:00||America/Noronha'=>'(-02:00) Noronha',
'-02:30||America/St_Johns'=>'(-02:30) St_Johns',
'-03:00||America/Araguaina'=>'(-03:00) Araguaina',
'-03:00||America/Argentina/Buenos_Aires'=>'(-03:00) Argentina/Buenos_Aires',
'-03:00||America/Argentina/Catamarca'=>'(-03:00) Argentina/Catamarca',
'-03:00||America/Argentina/Cordoba'=>'(-03:00) Argentina/Cordoba',
'-03:00||America/Argentina/Jujuy'=>'(-03:00) Argentina/Jujuy',
'-03:00||America/Argentina/La_Rioja'=>'(-03:00) Argentina/La_Rioja',
'-03:00||America/Argentina/Mendoza'=>'(-03:00) Argentina/Mendoza',
'-03:00||America/Argentina/Rio_Gallegos'=>'(-03:00) Argentina/Rio_Gallegos',
'-03:00||America/Argentina/Salta'=>'(-03:00) Argentina/Salta',
'-03:00||America/Argentina/San_Juan'=>'(-03:00) Argentina/San_Juan',
'-03:00||America/Argentina/San_Luis'=>'(-03:00) Argentina/San_Luis',
'-03:00||America/Argentina/Tucuman'=>'(-03:00) Argentina/Tucuman',
'-03:00||America/Argentina/Ushuaia'=>'(-03:00) Argentina/Ushuaia',
'-03:00||America/Asuncion'=>'(-03:00) Asuncion',
'-03:00||America/Bahia'=>'(-03:00) Bahia',
'-03:00||America/Belem'=>'(-03:00) Belem',
'-03:00||America/Cayenne'=>'(-03:00) Cayenne',
'-03:00||America/Fortaleza'=>'(-03:00) Fortaleza',
'-03:00||America/Glace_Bay'=>'(-03:00) Glace_Bay',
'-03:00||America/Godthab'=>'(-03:00) Godthab',
'-03:00||America/Goose_Bay'=>'(-03:00) Goose_Bay',
'-03:00||America/Halifax'=>'(-03:00) Halifax',
'-03:00||America/Maceio'=>'(-03:00) Maceio',
'-03:00||America/Moncton'=>'(-03:00) Moncton',
'-03:00||America/Montevideo'=>'(-03:00) Montevideo',
'-03:00||America/Paramaribo'=>'(-03:00) Paramaribo',
'-03:00||America/Punta_Arenas'=>'(-03:00) Punta_Arenas',
'-03:00||America/Recife'=>'(-03:00) Recife',
'-03:00||America/Santarem'=>'(-03:00) Santarem',
'-03:00||America/Santiago'=>'(-03:00) Santiago',
'-03:00||America/Sao_Paulo'=>'(-03:00) Sao_Paulo',
'-03:00||America/Thule'=>'(-03:00) Thule',
'-04:00||America/Anguilla'=>'(-04:00) Anguilla',
'-04:00||America/Antigua'=>'(-04:00) Antigua',
'-04:00||America/Aruba'=>'(-04:00) Aruba',
'-04:00||America/Barbados'=>'(-04:00) Barbados',
'-04:00||America/Blanc-Sablon'=>'(-04:00) Blanc-Sablon',
'-04:00||America/Boa_Vista'=>'(-04:00) Boa_Vista',
'-04:00||America/Campo_Grande'=>'(-04:00) Campo_Grande',
'-04:00||America/Caracas'=>'(-04:00) Caracas',
'-04:00||America/Cuiaba'=>'(-04:00) Cuiaba',
'-04:00||America/Curacao'=>'(-04:00) Curacao',
'-04:00||America/Detroit'=>'(-04:00) Detroit',
'-04:00||America/Dominica'=>'(-04:00) Dominica',
'-04:00||America/Grand_Turk'=>'(-04:00) Grand_Turk',
'-04:00||America/Grenada'=>'(-04:00) Grenada',
'-04:00||America/Guadeloupe'=>'(-04:00) Guadeloupe',
'-04:00||America/Guyana'=>'(-04:00) Guyana',
'-04:00||America/Havana'=>'(-04:00) Havana',
'-04:00||America/Indiana/Indianapolis'=>'(-04:00) Indiana/Indianapolis',
'-04:00||America/Indiana/Marengo'=>'(-04:00) Indiana/Marengo',
'-04:00||America/Indiana/Petersburg'=>'(-04:00) Indiana/Petersburg',
'-04:00||America/Indiana/Vevay'=>'(-04:00) Indiana/Vevay',
'-04:00||America/Indiana/Vincennes'=>'(-04:00) Indiana/Vincennes',
'-04:00||America/Indiana/Winamac'=>'(-04:00) Indiana/Winamac',
'-04:00||America/Iqaluit'=>'(-04:00) Iqaluit',
'-04:00||America/Kentucky/Louisville'=>'(-04:00) Kentucky/Louisville',
'-04:00||America/Kentucky/Monticello'=>'(-04:00) Kentucky/Monticello',
'-04:00||America/Kralendijk'=>'(-04:00) Kralendijk',
'-04:00||America/La_Paz'=>'(-04:00) La_Paz',
'-04:00||America/Lower_Princes'=>'(-04:00) Lower_Princes',
'-04:00||America/Manaus'=>'(-04:00) Manaus',
'-04:00||America/Marigot'=>'(-04:00) Marigot',
'-04:00||America/Martinique'=>'(-04:00) Martinique',
'-04:00||America/Montserrat'=>'(-04:00) Montserrat',
'-04:00||America/Nassau'=>'(-04:00) Nassau',
'-04:00||America/New_York'=>'(-04:00) New_York',
'-04:00||America/Nipigon'=>'(-04:00) Nipigon',
'-04:00||America/Pangnirtung'=>'(-04:00) Pangnirtung',
'-04:00||America/Port-au-Prince'=>'(-04:00) Port-au-Prince',
'-04:00||America/Port_of_Spain'=>'(-04:00) Port_of_Spain',
'-04:00||America/Porto_Velho'=>'(-04:00) Porto_Velho',
'-04:00||America/Puerto_Rico'=>'(-04:00) Puerto_Rico',
'-04:00||America/Santo_Domingo'=>'(-04:00) Santo_Domingo',
'-04:00||America/St_Barthelemy'=>'(-04:00) St_Barthelemy',
'-04:00||America/St_Kitts'=>'(-04:00) St_Kitts',
'-04:00||America/St_Lucia'=>'(-04:00) St_Lucia',
'-04:00||America/St_Thomas'=>'(-04:00) St_Thomas',
'-04:00||America/St_Vincent'=>'(-04:00) St_Vincent',
'-04:00||America/Thunder_Bay'=>'(-04:00) Thunder_Bay',
'-04:00||America/Toronto'=>'(-04:00) Toronto',
'-04:00||America/Tortola'=>'(-04:00) Tortola',
'-05:00||America/Atikokan'=>'(-05:00) Atikokan',
'-05:00||America/Bogota'=>'(-05:00) Bogota',
'-05:00||America/Cancun'=>'(-05:00) Cancun',
'-05:00||America/Cayman'=>'(-05:00) Cayman',
'-05:00||America/Chicago'=>'(-05:00) Chicago',
'-05:00||America/Eirunepe'=>'(-05:00) Eirunepe',
'-05:00||America/Guayaquil'=>'(-05:00) Guayaquil',
'-05:00||America/Indiana/Knox'=>'(-05:00) Indiana/Knox',
'-05:00||America/Indiana/Tell_City'=>'(-05:00) Indiana/Tell_City',
'-05:00||America/Jamaica'=>'(-05:00) Jamaica',
'-05:00||America/Lima'=>'(-05:00) Lima',
'-05:00||America/Matamoros'=>'(-05:00) Matamoros',
'-05:00||America/Menominee'=>'(-05:00) Menominee',
'-05:00||America/North_Dakota/Beulah'=>'(-05:00) North_Dakota/Beulah',
'-05:00||America/North_Dakota/Center'=>'(-05:00) North_Dakota/Center',
'-05:00||America/North_Dakota/New_Salem'=>'(-05:00) North_Dakota/New_Salem',
'-05:00||America/Panama'=>'(-05:00) Panama',
'-05:00||America/Rainy_River'=>'(-05:00) Rainy_River',
'-05:00||America/Rankin_Inlet'=>'(-05:00) Rankin_Inlet',
'-05:00||America/Resolute'=>'(-05:00) Resolute',
'-05:00||America/Rio_Branco'=>'(-05:00) Rio_Branco',
'-05:00||America/Winnipeg'=>'(-05:00) Winnipeg',
'-06:00||America/Bahia_Banderas'=>'(-06:00) Bahia_Banderas',
'-06:00||America/Belize'=>'(-06:00) Belize',
'-06:00||America/Boise'=>'(-06:00) Boise',
'-06:00||America/Cambridge_Bay'=>'(-06:00) Cambridge_Bay',
'-06:00||America/Costa_Rica'=>'(-06:00) Costa_Rica',
'-06:00||America/Denver'=>'(-06:00) Denver',
'-06:00||America/Edmonton'=>'(-06:00) Edmonton',
'-06:00||America/El_Salvador'=>'(-06:00) El_Salvador',
'-06:00||America/Guatemala'=>'(-06:00) Guatemala',
'-06:00||America/Inuvik'=>'(-06:00) Inuvik',
'-06:00||America/Managua'=>'(-06:00) Managua',
'-06:00||America/Merida'=>'(-06:00) Merida',
'-06:00||America/Mexico_City'=>'(-06:00) Mexico_City',
'-06:00||America/Monterrey'=>'(-06:00) Monterrey',
'-06:00||America/Ojinaga'=>'(-06:00) Ojinaga',
'-06:00||America/Regina'=>'(-06:00) Regina',
'-06:00||America/Swift_Current'=>'(-06:00) Swift_Current',
'-06:00||America/Tegucigalpa'=>'(-06:00) Tegucigalpa',
'-06:00||America/Yellowknife'=>'(-06:00) Yellowknife',
'-07:00||America/Chihuahua'=>'(-07:00) Chihuahua',
'-07:00||America/Creston'=>'(-07:00) Creston',
'-07:00||America/Dawson'=>'(-07:00) Dawson',
'-07:00||America/Dawson_Creek'=>'(-07:00) Dawson_Creek',
'-07:00||America/Fort_Nelson'=>'(-07:00) Fort_Nelson',
'-07:00||America/Hermosillo'=>'(-07:00) Hermosillo',
'-07:00||America/Los_Angeles'=>'(-07:00) Los_Angeles',
'-07:00||America/Mazatlan'=>'(-07:00) Mazatlan',
'-07:00||America/Phoenix'=>'(-07:00) Phoenix',
'-07:00||America/Tijuana'=>'(-07:00) Tijuana',
'-07:00||America/Vancouver'=>'(-07:00) Vancouver',
'-07:00||America/Whitehorse'=>'(-07:00) Whitehorse',
'-08:00||America/Anchorage'=>'(-08:00) Anchorage',
'-08:00||America/Juneau'=>'(-08:00) Juneau',
'-08:00||America/Metlakatla'=>'(-08:00) Metlakatla',
'-08:00||America/Nome'=>'(-08:00) Nome',
'-08:00||America/Sitka'=>'(-08:00) Sitka',
'-08:00||America/Yakutat'=>'(-08:00) Yakutat',
'-09:00||America/Adak'=>'(-09:00) Adak'
);

我已经在很多项目中使用它,分享来帮助你。谢谢你提出这个问题。

如果不希望依赖于静态时区列表,或者希望显示偏移量和时区。

这是我想到的

function timezones()
{
$timezones = \DateTimeZone::listIdentifiers();
$items = array();
foreach($timezones as $timezoneId) {
$timezone = new \DateTimeZone($timezoneId);
$offsetInSeconds = $timezone->getOffset(new \DateTime());
$items[$timezoneId] = $offsetInSeconds;
}
asort($items);
array_walk ($items, function (&$offsetInSeconds, &$timezoneId) {
$offsetPrefix = $offsetInSeconds < 0 ? '-' : '+';
$offset = gmdate('H:i', abs($offsetInSeconds));
$offset = "(GMT${offsetPrefix}${offset}) ".$timezoneId;
$offsetInSeconds = $offset;
});
return $items;
}

结果如下

Array
(
[Pacific/Midway] => (GMT-11:00) Pacific/Midway
[Pacific/Pago_Pago] => (GMT-11:00) Pacific/Pago_Pago
[Pacific/Niue] => (GMT-11:00) Pacific/Niue
[America/Adak] => (GMT-10:00) America/Adak
[Pacific/Tahiti] => (GMT-10:00) Pacific/Tahiti
[Pacific/Rarotonga] => (GMT-10:00) Pacific/Rarotonga
[Pacific/Honolulu] => (GMT-10:00) Pacific/Honolulu
[Pacific/Marquesas] => (GMT-09:30) Pacific/Marquesas
[America/Sitka] => (GMT-09:00) America/Sitka
[Pacific/Gambier] => (GMT-09:00) Pacific/Gambier
[America/Yakutat] => (GMT-09:00) America/Yakutat
[America/Juneau] => (GMT-09:00) America/Juneau
[America/Nome] => (GMT-09:00) America/Nome
[America/Anchorage] => (GMT-09:00) America/Anchorage
[America/Metlakatla] => (GMT-09:00) America/Metlakatla
[America/Los_Angeles] => (GMT-08:00) America/Los_Angeles
[America/Tijuana] => (GMT-08:00) America/Tijuana
[America/Whitehorse] => (GMT-08:00) America/Whitehorse
[America/Vancouver] => (GMT-08:00) America/Vancouver
[America/Dawson] => (GMT-08:00) America/Dawson
[Pacific/Pitcairn] => (GMT-08:00) Pacific/Pitcairn
[America/Mazatlan] => (GMT-07:00) America/Mazatlan
[America/Fort_Nelson] => (GMT-07:00) America/Fort_Nelson
[America/Yellowknife] => (GMT-07:00) America/Yellowknife
[America/Inuvik] => (GMT-07:00) America/Inuvik
[America/Edmonton] => (GMT-07:00) America/Edmonton
[America/Denver] => (GMT-07:00) America/Denver
[America/Chihuahua] => (GMT-07:00) America/Chihuahua
[America/Boise] => (GMT-07:00) America/Boise
[America/Ojinaga] => (GMT-07:00) America/Ojinaga
[America/Cambridge_Bay] => (GMT-07:00) America/Cambridge_Bay
[America/Dawson_Creek] => (GMT-07:00) America/Dawson_Creek
[America/Phoenix] => (GMT-07:00) America/Phoenix
[America/Hermosillo] => (GMT-07:00) America/Hermosillo
[America/Creston] => (GMT-07:00) America/Creston
[America/Matamoros] => (GMT-06:00) America/Matamoros
[America/Menominee] => (GMT-06:00) America/Menominee
[America/Indiana/Knox] => (GMT-06:00) America/Indiana/Knox
[America/Managua] => (GMT-06:00) America/Managua
[America/Bahia_Banderas] => (GMT-06:00) America/Bahia_Banderas
[America/Indiana/Tell_City] => (GMT-06:00) America/Indiana/Tell_City
[America/Belize] => (GMT-06:00) America/Belize
[America/Chicago] => (GMT-06:00) America/Chicago
[America/Guatemala] => (GMT-06:00) America/Guatemala
[America/El_Salvador] => (GMT-06:00) America/El_Salvador
[America/Merida] => (GMT-06:00) America/Merida
[America/Costa_Rica] => (GMT-06:00) America/Costa_Rica
[America/Mexico_City] => (GMT-06:00) America/Mexico_City
[America/Winnipeg] => (GMT-06:00) America/Winnipeg
[Pacific/Galapagos] => (GMT-06:00) Pacific/Galapagos
[America/Resolute] => (GMT-06:00) America/Resolute
[America/Regina] => (GMT-06:00) America/Regina
[America/Rankin_Inlet] => (GMT-06:00) America/Rankin_Inlet
[America/Rainy_River] => (GMT-06:00) America/Rainy_River
[America/North_Dakota/New_Salem] => (GMT-06:00) America/North_Dakota/New_Salem
[America/North_Dakota/Beulah] => (GMT-06:00) America/North_Dakota/Beulah
[America/North_Dakota/Center] => (GMT-06:00) America/North_Dakota/Center
[America/Tegucigalpa] => (GMT-06:00) America/Tegucigalpa
[America/Swift_Current] => (GMT-06:00) America/Swift_Current
[America/Monterrey] => (GMT-06:00) America/Monterrey
[America/Pangnirtung] => (GMT-05:00) America/Pangnirtung
[America/Indiana/Petersburg] => (GMT-05:00) America/Indiana/Petersburg
[America/Indiana/Marengo] => (GMT-05:00) America/Indiana/Marengo
[America/Bogota] => (GMT-05:00) America/Bogota
[America/Toronto] => (GMT-05:00) America/Toronto
[America/Detroit] => (GMT-05:00) America/Detroit
[America/Panama] => (GMT-05:00) America/Panama
[America/Cancun] => (GMT-05:00) America/Cancun
[America/Rio_Branco] => (GMT-05:00) America/Rio_Branco
[America/Port-au-Prince] => (GMT-05:00) America/Port-au-Prince
[America/Cayman] => (GMT-05:00) America/Cayman
[America/Grand_Turk] => (GMT-05:00) America/Grand_Turk
[America/Havana] => (GMT-05:00) America/Havana
[America/Indiana/Indianapolis] => (GMT-05:00) America/Indiana/Indianapolis
[America/Indiana/Vevay] => (GMT-05:00) America/Indiana/Vevay
[America/Guayaquil] => (GMT-05:00) America/Guayaquil
[America/Nipigon] => (GMT-05:00) America/Nipigon
[America/Indiana/Vincennes] => (GMT-05:00) America/Indiana/Vincennes
[America/Atikokan] => (GMT-05:00) America/Atikokan
[America/Indiana/Winamac] => (GMT-05:00) America/Indiana/Winamac
[America/New_York] => (GMT-05:00) America/New_York
[America/Iqaluit] => (GMT-05:00) America/Iqaluit
[America/Jamaica] => (GMT-05:00) America/Jamaica
[America/Nassau] => (GMT-05:00) America/Nassau
[America/Kentucky/Louisville] => (GMT-05:00) America/Kentucky/Louisville
[America/Kentucky/Monticello] => (GMT-05:00) America/Kentucky/Monticello
[America/Eirunepe] => (GMT-05:00) America/Eirunepe
[Pacific/Easter] => (GMT-05:00) Pacific/Easter
[America/Lima] => (GMT-05:00) America/Lima
[America/Thunder_Bay] => (GMT-05:00) America/Thunder_Bay
[America/Guadeloupe] => (GMT-04:00) America/Guadeloupe
[America/Manaus] => (GMT-04:00) America/Manaus
[America/Guyana] => (GMT-04:00) America/Guyana
[America/Halifax] => (GMT-04:00) America/Halifax
[America/Puerto_Rico] => (GMT-04:00) America/Puerto_Rico
[America/Porto_Velho] => (GMT-04:00) America/Porto_Velho
[America/Port_of_Spain] => (GMT-04:00) America/Port_of_Spain
[America/Montserrat] => (GMT-04:00) America/Montserrat
[America/Moncton] => (GMT-04:00) America/Moncton
[America/Martinique] => (GMT-04:00) America/Martinique
[America/Kralendijk] => (GMT-04:00) America/Kralendijk
[America/La_Paz] => (GMT-04:00) America/La_Paz
[America/Marigot] => (GMT-04:00) America/Marigot
[America/Lower_Princes] => (GMT-04:00) America/Lower_Princes
[America/Grenada] => (GMT-04:00) America/Grenada
[America/Santo_Domingo] => (GMT-04:00) America/Santo_Domingo
[America/Goose_Bay] => (GMT-04:00) America/Goose_Bay
[America/Caracas] => (GMT-04:00) America/Caracas
[America/Anguilla] => (GMT-04:00) America/Anguilla
[America/St_Barthelemy] => (GMT-04:00) America/St_Barthelemy
[America/Barbados] => (GMT-04:00) America/Barbados
[America/St_Kitts] => (GMT-04:00) America/St_Kitts
[America/Blanc-Sablon] => (GMT-04:00) America/Blanc-Sablon
[America/Boa_Vista] => (GMT-04:00) America/Boa_Vista
[America/St_Lucia] => (GMT-04:00) America/St_Lucia
[America/St_Thomas] => (GMT-04:00) America/St_Thomas
[America/Antigua] => (GMT-04:00) America/Antigua
[America/St_Vincent] => (GMT-04:00) America/St_Vincent
[America/Thule] => (GMT-04:00) America/Thule
[America/Curacao] => (GMT-04:00) America/Curacao
[America/Tortola] => (GMT-04:00) America/Tortola
[America/Dominica] => (GMT-04:00) America/Dominica
[Atlantic/Bermuda] => (GMT-04:00) Atlantic/Bermuda
[America/Glace_Bay] => (GMT-04:00) America/Glace_Bay
[America/Aruba] => (GMT-04:00) America/Aruba
[America/St_Johns] => (GMT-03:30) America/St_Johns
[America/Argentina/Tucuman] => (GMT-03:00) America/Argentina/Tucuman
[America/Belem] => (GMT-03:00) America/Belem
[America/Santiago] => (GMT-03:00) America/Santiago
[America/Santarem] => (GMT-03:00) America/Santarem
[America/Recife] => (GMT-03:00) America/Recife
[America/Punta_Arenas] => (GMT-03:00) America/Punta_Arenas
[Atlantic/Stanley] => (GMT-03:00) Atlantic/Stanley
[America/Paramaribo] => (GMT-03:00) America/Paramaribo
[America/Fortaleza] => (GMT-03:00) America/Fortaleza
[America/Argentina/San_Luis] => (GMT-03:00) America/Argentina/San_Luis
[Antarctica/Palmer] => (GMT-03:00) Antarctica/Palmer
[America/Montevideo] => (GMT-03:00) America/Montevideo
[America/Cuiaba] => (GMT-03:00) America/Cuiaba
[America/Miquelon] => (GMT-03:00) America/Miquelon
[America/Cayenne] => (GMT-03:00) America/Cayenne
[America/Campo_Grande] => (GMT-03:00) America/Campo_Grande
[Antarctica/Rothera] => (GMT-03:00) Antarctica/Rothera
[America/Godthab] => (GMT-03:00) America/Godthab
[America/Bahia] => (GMT-03:00) America/Bahia
[America/Asuncion] => (GMT-03:00) America/Asuncion
[America/Argentina/Ushuaia] => (GMT-03:00) America/Argentina/Ushuaia
[America/Argentina/La_Rioja] => (GMT-03:00) America/Argentina/La_Rioja
[America/Araguaina] => (GMT-03:00) America/Araguaina
[America/Argentina/Buenos_Aires] => (GMT-03:00) America/Argentina/Buenos_Aires
[America/Argentina/Rio_Gallegos] => (GMT-03:00) America/Argentina/Rio_Gallegos
[America/Argentina/Catamarca] => (GMT-03:00) America/Argentina/Catamarca
[America/Maceio] => (GMT-03:00) America/Maceio
[America/Argentina/San_Juan] => (GMT-03:00) America/Argentina/San_Juan
[America/Argentina/Salta] => (GMT-03:00) America/Argentina/Salta
[America/Argentina/Mendoza] => (GMT-03:00) America/Argentina/Mendoza
[America/Argentina/Cordoba] => (GMT-03:00) America/Argentina/Cordoba
[America/Argentina/Jujuy] => (GMT-03:00) America/Argentina/Jujuy
[Atlantic/South_Georgia] => (GMT-02:00) Atlantic/South_Georgia
[America/Noronha] => (GMT-02:00) America/Noronha
[America/Sao_Paulo] => (GMT-02:00) America/Sao_Paulo
[Atlantic/Cape_Verde] => (GMT-01:00) Atlantic/Cape_Verde
[Atlantic/Azores] => (GMT-01:00) Atlantic/Azores
[America/Scoresbysund] => (GMT-01:00) America/Scoresbysund
[Europe/Lisbon] => (GMT+00:00) Europe/Lisbon
[Europe/London] => (GMT+00:00) Europe/London
[Europe/Jersey] => (GMT+00:00) Europe/Jersey
[Europe/Isle_of_Man] => (GMT+00:00) Europe/Isle_of_Man
[Atlantic/Faroe] => (GMT+00:00) Atlantic/Faroe
[Europe/Guernsey] => (GMT+00:00) Europe/Guernsey
[Europe/Dublin] => (GMT+00:00) Europe/Dublin
[Atlantic/St_Helena] => (GMT+00:00) Atlantic/St_Helena
[Atlantic/Reykjavik] => (GMT+00:00) Atlantic/Reykjavik
[Atlantic/Madeira] => (GMT+00:00) Atlantic/Madeira
[Atlantic/Canary] => (GMT+00:00) Atlantic/Canary
[Africa/Accra] => (GMT+00:00) Africa/Accra
[Antarctica/Troll] => (GMT+00:00) Antarctica/Troll
[Africa/Abidjan] => (GMT+00:00) Africa/Abidjan
[UTC] => (GMT+00:00) UTC
[America/Danmarkshavn] => (GMT+00:00) America/Danmarkshavn
[Africa/Monrovia] => (GMT+00:00) Africa/Monrovia
[Africa/Dakar] => (GMT+00:00) Africa/Dakar
[Africa/Conakry] => (GMT+00:00) Africa/Conakry
[Africa/Casablanca] => (GMT+00:00) Africa/Casablanca
[Africa/Lome] => (GMT+00:00) Africa/Lome
[Africa/Freetown] => (GMT+00:00) Africa/Freetown
[Africa/El_Aaiun] => (GMT+00:00) Africa/El_Aaiun
[Africa/Bissau] => (GMT+00:00) Africa/Bissau
[Africa/Nouakchott] => (GMT+00:00) Africa/Nouakchott
[Africa/Banjul] => (GMT+00:00) Africa/Banjul
[Africa/Ouagadougou] => (GMT+00:00) Africa/Ouagadougou
[Africa/Bamako] => (GMT+00:00) Africa/Bamako
[Europe/Gibraltar] => (GMT+01:00) Europe/Gibraltar
[Africa/Bangui] => (GMT+01:00) Africa/Bangui
[Europe/Ljubljana] => (GMT+01:00) Europe/Ljubljana
[Africa/Ceuta] => (GMT+01:00) Africa/Ceuta
[Africa/Algiers] => (GMT+01:00) Africa/Algiers
[Europe/Busingen] => (GMT+01:00) Europe/Busingen
[Europe/Copenhagen] => (GMT+01:00) Europe/Copenhagen
[Europe/Madrid] => (GMT+01:00) Europe/Madrid
[Europe/Budapest] => (GMT+01:00) Europe/Budapest
[Europe/Brussels] => (GMT+01:00) Europe/Brussels
[Europe/Bratislava] => (GMT+01:00) Europe/Bratislava
[Europe/Berlin] => (GMT+01:00) Europe/Berlin
[Europe/Belgrade] => (GMT+01:00) Europe/Belgrade
[Europe/Andorra] => (GMT+01:00) Europe/Andorra
[Europe/Amsterdam] => (GMT+01:00) Europe/Amsterdam
[Europe/Luxembourg] => (GMT+01:00) Europe/Luxembourg
[Europe/Monaco] => (GMT+01:00) Europe/Monaco
[Europe/Malta] => (GMT+01:00) Europe/Malta
[Europe/Tirane] => (GMT+01:00) Europe/Tirane
[Europe/Zurich] => (GMT+01:00) Europe/Zurich
[Europe/Zagreb] => (GMT+01:00) Europe/Zagreb
[Europe/Warsaw] => (GMT+01:00) Europe/Warsaw
[Europe/Vienna] => (GMT+01:00) Europe/Vienna
[Europe/Vatican] => (GMT+01:00) Europe/Vatican
[Europe/Vaduz] => (GMT+01:00) Europe/Vaduz
[Europe/Stockholm] => (GMT+01:00) Europe/Stockholm
[Africa/Brazzaville] => (GMT+01:00) Africa/Brazzaville
[Europe/Skopje] => (GMT+01:00) Europe/Skopje
[Europe/Sarajevo] => (GMT+01:00) Europe/Sarajevo
[Europe/San_Marino] => (GMT+01:00) Europe/San_Marino
[Europe/Rome] => (GMT+01:00) Europe/Rome
[Europe/Prague] => (GMT+01:00) Europe/Prague
[Europe/Paris] => (GMT+01:00) Europe/Paris
[Europe/Oslo] => (GMT+01:00) Europe/Oslo
[Europe/Podgorica] => (GMT+01:00) Europe/Podgorica
[Africa/Douala] => (GMT+01:00) Africa/Douala
[Arctic/Longyearbyen] => (GMT+01:00) Arctic/Longyearbyen
[Africa/Malabo] => (GMT+01:00) Africa/Malabo
[Africa/Kinshasa] => (GMT+01:00) Africa/Kinshasa
[Africa/Libreville] => (GMT+01:00) Africa/Libreville
[Africa/Ndjamena] => (GMT+01:00) Africa/Ndjamena
[Africa/Lagos] => (GMT+01:00) Africa/Lagos
[Africa/Niamey] => (GMT+01:00) Africa/Niamey
[Africa/Porto-Novo] => (GMT+01:00) Africa/Porto-Novo
[Africa/Sao_Tome] => (GMT+01:00) Africa/Sao_Tome
[Africa/Luanda] => (GMT+01:00) Africa/Luanda
[Africa/Tunis] => (GMT+01:00) Africa/Tunis
[Europe/Uzhgorod] => (GMT+02:00) Europe/Uzhgorod
[Africa/Harare] => (GMT+02:00) Africa/Harare
[Europe/Mariehamn] => (GMT+02:00) Europe/Mariehamn
[Africa/Lubumbashi] => (GMT+02:00) Africa/Lubumbashi
[Asia/Nicosia] => (GMT+02:00) Asia/Nicosia
[Africa/Windhoek] => (GMT+02:00) Africa/Windhoek
[Europe/Tallinn] => (GMT+02:00) Europe/Tallinn
[Europe/Zaporozhye] => (GMT+02:00) Europe/Zaporozhye
[Africa/Gaborone] => (GMT+02:00) Africa/Gaborone
[Africa/Mbabane] => (GMT+02:00) Africa/Mbabane
[Africa/Khartoum] => (GMT+02:00) Africa/Khartoum
[Africa/Johannesburg] => (GMT+02:00) Africa/Johannesburg
[Europe/Vilnius] => (GMT+02:00) Europe/Vilnius
[Africa/Maseru] => (GMT+02:00) Africa/Maseru
[Africa/Lusaka] => (GMT+02:00) Africa/Lusaka
[Europe/Riga] => (GMT+02:00) Europe/Riga
[Africa/Kigali] => (GMT+02:00) Africa/Kigali
[Europe/Helsinki] => (GMT+02:00) Europe/Helsinki
[Africa/Maputo] => (GMT+02:00) Africa/Maputo
[Europe/Chisinau] => (GMT+02:00) Europe/Chisinau
[Europe/Sofia] => (GMT+02:00) Europe/Sofia
[Asia/Beirut] => (GMT+02:00) Asia/Beirut
[Africa/Blantyre] => (GMT+02:00) Africa/Blantyre
[Asia/Jerusalem] => (GMT+02:00) Asia/Jerusalem
[Asia/Gaza] => (GMT+02:00) Asia/Gaza
[Asia/Amman] => (GMT+02:00) Asia/Amman
[Asia/Famagusta] => (GMT+02:00) Asia/Famagusta
[Europe/Athens] => (GMT+02:00) Europe/Athens
[Africa/Bujumbura] => (GMT+02:00) Africa/Bujumbura
[Asia/Hebron] => (GMT+02:00) Asia/Hebron
[Europe/Kaliningrad] => (GMT+02:00) Europe/Kaliningrad
[Africa/Cairo] => (GMT+02:00) Africa/Cairo
[Europe/Kiev] => (GMT+02:00) Europe/Kiev
[Europe/Bucharest] => (GMT+02:00) Europe/Bucharest
[Asia/Damascus] => (GMT+02:00) Asia/Damascus
[Africa/Tripoli] => (GMT+02:00) Africa/Tripoli
[Asia/Baghdad] => (GMT+03:00) Asia/Baghdad
[Africa/Djibouti] => (GMT+03:00) Africa/Djibouti
[Asia/Aden] => (GMT+03:00) Asia/Aden
[Asia/Bahrain] => (GMT+03:00) Asia/Bahrain
[Europe/Istanbul] => (GMT+03:00) Europe/Istanbul
[Africa/Juba] => (GMT+03:00) Africa/Juba
[Europe/Kirov] => (GMT+03:00) Europe/Kirov
[Europe/Moscow] => (GMT+03:00) Europe/Moscow
[Antarctica/Syowa] => (GMT+03:00) Antarctica/Syowa
[Europe/Minsk] => (GMT+03:00) Europe/Minsk
[Africa/Kampala] => (GMT+03:00) Africa/Kampala
[Africa/Dar_es_Salaam] => (GMT+03:00) Africa/Dar_es_Salaam
[Europe/Simferopol] => (GMT+03:00) Europe/Simferopol
[Asia/Riyadh] => (GMT+03:00) Asia/Riyadh
[Indian/Antananarivo] => (GMT+03:00) Indian/Antananarivo
[Asia/Kuwait] => (GMT+03:00) Asia/Kuwait
[Africa/Nairobi] => (GMT+03:00) Africa/Nairobi
[Indian/Mayotte] => (GMT+03:00) Indian/Mayotte
[Africa/Mogadishu] => (GMT+03:00) Africa/Mogadishu
[Asia/Qatar] => (GMT+03:00) Asia/Qatar
[Europe/Volgograd] => (GMT+03:00) Europe/Volgograd
[Africa/Asmara] => (GMT+03:00) Africa/Asmara
[Africa/Addis_Ababa] => (GMT+03:00) Africa/Addis_Ababa
[Indian/Comoro] => (GMT+03:00) Indian/Comoro
[Asia/Tehran] => (GMT+03:30) Asia/Tehran
[Europe/Saratov] => (GMT+04:00) Europe/Saratov
[Indian/Reunion] => (GMT+04:00) Indian/Reunion
[Europe/Astrakhan] => (GMT+04:00) Europe/Astrakhan
[Asia/Baku] => (GMT+04:00) Asia/Baku
[Asia/Dubai] => (GMT+04:00) Asia/Dubai
[Indian/Mauritius] => (GMT+04:00) Indian/Mauritius
[Indian/Mahe] => (GMT+04:00) Indian/Mahe
[Asia/Tbilisi] => (GMT+04:00) Asia/Tbilisi
[Asia/Yerevan] => (GMT+04:00) Asia/Yerevan
[Asia/Muscat] => (GMT+04:00) Asia/Muscat
[Europe/Samara] => (GMT+04:00) Europe/Samara
[Europe/Ulyanovsk] => (GMT+04:00) Europe/Ulyanovsk
[Asia/Kabul] => (GMT+04:30) Asia/Kabul
[Antarctica/Mawson] => (GMT+05:00) Antarctica/Mawson
[Asia/Samarkand] => (GMT+05:00) Asia/Samarkand
[Asia/Aqtobe] => (GMT+05:00) Asia/Aqtobe
[Indian/Maldives] => (GMT+05:00) Indian/Maldives
[Asia/Ashgabat] => (GMT+05:00) Asia/Ashgabat
[Asia/Atyrau] => (GMT+05:00) Asia/Atyrau
[Asia/Dushanbe] => (GMT+05:00) Asia/Dushanbe
[Asia/Yekaterinburg] => (GMT+05:00) Asia/Yekaterinburg
[Asia/Oral] => (GMT+05:00) Asia/Oral
[Asia/Aqtau] => (GMT+05:00) Asia/Aqtau
[Asia/Karachi] => (GMT+05:00) Asia/Karachi
[Asia/Tashkent] => (GMT+05:00) Asia/Tashkent
[Indian/Kerguelen] => (GMT+05:00) Indian/Kerguelen
[Asia/Colombo] => (GMT+05:30) Asia/Colombo
[Asia/Kolkata] => (GMT+05:30) Asia/Kolkata
[Asia/Kathmandu] => (GMT+05:45) Asia/Kathmandu
[Antarctica/Vostok] => (GMT+06:00) Antarctica/Vostok
[Indian/Chagos] => (GMT+06:00) Indian/Chagos
[Asia/Almaty] => (GMT+06:00) Asia/Almaty
[Asia/Omsk] => (GMT+06:00) Asia/Omsk
[Asia/Dhaka] => (GMT+06:00) Asia/Dhaka
[Asia/Bishkek] => (GMT+06:00) Asia/Bishkek
[Asia/Urumqi] => (GMT+06:00) Asia/Urumqi
[Asia/Thimphu] => (GMT+06:00) Asia/Thimphu
[Asia/Qyzylorda] => (GMT+06:00) Asia/Qyzylorda
[Indian/Cocos] => (GMT+06:30) Indian/Cocos
[Asia/Yangon] => (GMT+06:30) Asia/Yangon
[Asia/Novokuznetsk] => (GMT+07:00) Asia/Novokuznetsk
[Asia/Barnaul] => (GMT+07:00) Asia/Barnaul
[Antarctica/Davis] => (GMT+07:00) Antarctica/Davis
[Asia/Novosibirsk] => (GMT+07:00) Asia/Novosibirsk
[Asia/Krasnoyarsk] => (GMT+07:00) Asia/Krasnoyarsk
[Asia/Phnom_Penh] => (GMT+07:00) Asia/Phnom_Penh
[Asia/Pontianak] => (GMT+07:00) Asia/Pontianak
[Asia/Jakarta] => (GMT+07:00) Asia/Jakarta
[Asia/Hovd] => (GMT+07:00) Asia/Hovd
[Asia/Tomsk] => (GMT+07:00) Asia/Tomsk
[Asia/Ho_Chi_Minh] => (GMT+07:00) Asia/Ho_Chi_Minh
[Asia/Vientiane] => (GMT+07:00) Asia/Vientiane
[Indian/Christmas] => (GMT+07:00) Indian/Christmas
[Asia/Bangkok] => (GMT+07:00) Asia/Bangkok
[Asia/Choibalsan] => (GMT+08:00) Asia/Choibalsan
[Asia/Taipei] => (GMT+08:00) Asia/Taipei
[Asia/Makassar] => (GMT+08:00) Asia/Makassar
[Asia/Macau] => (GMT+08:00) Asia/Macau
[Asia/Kuching] => (GMT+08:00) Asia/Kuching
[Asia/Kuala_Lumpur] => (GMT+08:00) Asia/Kuala_Lumpur
[Asia/Shanghai] => (GMT+08:00) Asia/Shanghai
[Asia/Singapore] => (GMT+08:00) Asia/Singapore
[Asia/Brunei] => (GMT+08:00) Asia/Brunei
[Asia/Irkutsk] => (GMT+08:00) Asia/Irkutsk
[Asia/Ulaanbaatar] => (GMT+08:00) Asia/Ulaanbaatar
[Australia/Perth] => (GMT+08:00) Australia/Perth
[Asia/Hong_Kong] => (GMT+08:00) Asia/Hong_Kong
[Antarctica/Casey] => (GMT+08:00) Antarctica/Casey
[Asia/Manila] => (GMT+08:00) Asia/Manila
[Australia/Eucla] => (GMT+08:45) Australia/Eucla
[Asia/Jayapura] => (GMT+09:00) Asia/Jayapura
[Asia/Khandyga] => (GMT+09:00) Asia/Khandyga
[Pacific/Palau] => (GMT+09:00) Pacific/Palau
[Asia/Dili] => (GMT+09:00) Asia/Dili
[Asia/Yakutsk] => (GMT+09:00) Asia/Yakutsk
[Asia/Tokyo] => (GMT+09:00) Asia/Tokyo
[Asia/Seoul] => (GMT+09:00) Asia/Seoul
[Asia/Chita] => (GMT+09:00) Asia/Chita
[Asia/Pyongyang] => (GMT+09:00) Asia/Pyongyang
[Australia/Darwin] => (GMT+09:30) Australia/Darwin
[Asia/Ust-Nera] => (GMT+10:00) Asia/Ust-Nera
[Pacific/Chuuk] => (GMT+10:00) Pacific/Chuuk
[Antarctica/DumontDUrville] => (GMT+10:00) Antarctica/DumontDUrville
[Pacific/Guam] => (GMT+10:00) Pacific/Guam
[Pacific/Port_Moresby] => (GMT+10:00) Pacific/Port_Moresby
[Asia/Vladivostok] => (GMT+10:00) Asia/Vladivostok
[Australia/Brisbane] => (GMT+10:00) Australia/Brisbane
[Australia/Lindeman] => (GMT+10:00) Australia/Lindeman
[Pacific/Saipan] => (GMT+10:00) Pacific/Saipan
[Australia/Adelaide] => (GMT+10:30) Australia/Adelaide
[Australia/Broken_Hill] => (GMT+10:30) Australia/Broken_Hill
[Australia/Sydney] => (GMT+11:00) Australia/Sydney
[Antarctica/Macquarie] => (GMT+11:00) Antarctica/Macquarie
[Pacific/Noumea] => (GMT+11:00) Pacific/Noumea
[Pacific/Norfolk] => (GMT+11:00) Pacific/Norfolk
[Australia/Melbourne] => (GMT+11:00) Australia/Melbourne
[Pacific/Kosrae] => (GMT+11:00) Pacific/Kosrae
[Pacific/Pohnpei] => (GMT+11:00) Pacific/Pohnpei
[Australia/Currie] => (GMT+11:00) Australia/Currie
[Pacific/Guadalcanal] => (GMT+11:00) Pacific/Guadalcanal
[Pacific/Efate] => (GMT+11:00) Pacific/Efate
[Australia/Hobart] => (GMT+11:00) Australia/Hobart
[Asia/Magadan] => (GMT+11:00) Asia/Magadan
[Asia/Sakhalin] => (GMT+11:00) Asia/Sakhalin
[Pacific/Bougainville] => (GMT+11:00) Pacific/Bougainville
[Australia/Lord_Howe] => (GMT+11:00) Australia/Lord_Howe
[Asia/Srednekolymsk] => (GMT+11:00) Asia/Srednekolymsk
[Pacific/Fiji] => (GMT+12:00) Pacific/Fiji
[Pacific/Wake] => (GMT+12:00) Pacific/Wake
[Pacific/Nauru] => (GMT+12:00) Pacific/Nauru
[Pacific/Majuro] => (GMT+12:00) Pacific/Majuro
[Asia/Kamchatka] => (GMT+12:00) Asia/Kamchatka
[Pacific/Kwajalein] => (GMT+12:00) Pacific/Kwajalein
[Pacific/Funafuti] => (GMT+12:00) Pacific/Funafuti
[Pacific/Wallis] => (GMT+12:00) Pacific/Wallis
[Asia/Anadyr] => (GMT+12:00) Asia/Anadyr
[Pacific/Tarawa] => (GMT+12:00) Pacific/Tarawa
[Pacific/Fakaofo] => (GMT+13:00) Pacific/Fakaofo
[Pacific/Enderbury] => (GMT+13:00) Pacific/Enderbury
[Pacific/Auckland] => (GMT+13:00) Pacific/Auckland
[Antarctica/McMurdo] => (GMT+13:00) Antarctica/McMurdo
[Pacific/Tongatapu] => (GMT+13:00) Pacific/Tongatapu
[Pacific/Chatham] => (GMT+13:45) Pacific/Chatham
[Pacific/Kiritimati] => (GMT+14:00) Pacific/Kiritimati
[Pacific/Apia] => (GMT+14:00) Pacific/Apia
)

这里重复了@Jonathan 给出的答案(2021年新鲜) ,并包含了自动选择时区的 javascript/jquery。我喜欢它的原因是: a)它自动选择用户的时区; b)如果他们想改变时区,他们会得到一个按字母顺序排列的可读列表,这样就可以很容易地扫描他们的国家,然后是城市。

在大多数情况下,用户不需要更改它,因为它将使用 javasdcript 正确地自动选择。

PHP 来构建选择器数据:

function timezonePickerData() {
static $timezones = null;
if ($timezones === null) {
$timezones = [];
$offsets = [];
$now = new \DateTime('now', new \DateTimeZone('UTC'));
foreach (\DateTimeZone::listIdentifiers(\DateTimeZone::ALL) as $timezone) {


// Calculate offset
$now->setTimezone(new \DateTimeZone($timezone));
$offsets[] = $offset = $now->getOffset();


// Display text for UTC offset
$hours = intval($offset / 3600);
$minutes = abs(intval($offset % 3600 / 60));
$utcDiff = 'UTC' . ($offset ? sprintf('%+03d:%02d', $hours, $minutes) : '');


// Display text for name
$name = str_replace('/', ', ',$timezone);
$name = str_replace('_', ' ', $name);
$name = str_replace('St ', 'St. ', $name);


$timezones[$timezone] = "$name ($utcDiff)";
}
}


return $timezones;
}

HTML/PHP 来构建选择器:

<select id="timezone">
<?php
foreach(timezonePickerData() as $timezone => $location) {
print "<option value=\"$timezone\">$location</option>\n";
}
?>
</select>

JQuery 自动选择用户时区:

var data = Intl.DateTimeFormat().resolvedOptions()
$("#timezone").val(data.timeZone);

下面是自动选择的选择器格式(未单击) :

America, Los Angeles (UTC-7:00)

当用户单击以更改其时区(易于用户扫描)时,选择列表如下所示:

enter image description here