Ich habe eine dynamische, selbst aktualisierte Lösung entwickelt, die keine Nachschlagetabellen benötigt (Demo wählen):
function Timezones()
{
$result = array();
$timezones = array();
// only process geographical timezones
foreach (preg_grep('~^(?:A(?:frica|merica|ntarctica|rctic|tlantic|sia|ustralia)|Europe|Indian|Pacific)/~', timezone_identifiers_list()) as $timezone)
{
if (is_object($timezone = new DateTimeZone($timezone)) === true)
{
$id = array();
// get only the two most distant transitions
foreach (array_slice($timezone->getTransitions($_SERVER['REQUEST_TIME']), -2) as $transition)
{
// dark magic
$id[] = sprintf('%b|%+d|%u', $transition['isdst'], $transition['offset'], $transition['ts']);
}
if (count($id) > 1)
{
sort($id, SORT_NUMERIC); // sort by %b (isdst = 0) first, so that we always get the raw offset
}
$timezones[implode('|', $id)][] = $timezone->getName();
}
}
if ((is_array($timezones) === true) && (count($timezones) > 0))
{
uksort($timezones, function($a, $b) // sort offsets by -, 0, +
{
foreach (array('a', 'b') as $key)
{
$$key = explode('|', $$key);
}
return intval($a[1]) - intval($b[1]);
});
foreach ($timezones as $key => $value)
{
$zone = reset($value); // first timezone ID is our internal timezone
$result[$zone] = preg_replace(array('~^.*/([^/]+)$~', '~_~'), array('$1', ' '), $value); // "humanize" city names
if (array_key_exists(1, $offset = explode('|', $key)) === true) // "humanize" the offset
{
$offset = str_replace(' +00:00', '', sprintf('(UTC %+03d:%02u)', $offset[1] / 3600, abs($offset[1]) % 3600 / 60));
}
if (asort($result[$zone]) === true) // sort city names
{
$result[$zone] = trim(sprintf('%s %s', $offset, implode(', ', $result[$zone])));
}
}
}
return $result;
}
Es gibt viele Zeitzonen, die genau die gleichen Offsets und DST-Timings haben (Europe/Dublin
, Europe/Lisbon
und Europe/London
um nur einige zu nennen), gruppiert mein Algorithmus diese Zonen (unter Verwendung einer speziellen Notation in den Array-Schlüsseln dst?|offset|timestamp
) in der ersten Zeitzonen-ID dieser Gruppe und verkettet humanisierte Transformationen des letzten Segments (normalerweise auf Stadtebene) der Zeitzonen-ID:
Array
(
[Pacific/Midway] => (UTC -11:00) Midway, Niue, Pago Pago
[America/Adak] => (UTC -10:00) Adak
[Pacific/Fakaofo] => (UTC -10:00) Fakaofo, Honolulu, Johnston, Rarotonga, Tahiti
[Pacific/Marquesas] => (UTC -10:30) Marquesas
[America/Anchorage] => (UTC -09:00) Anchorage, Juneau, Nome, Sitka, Yakutat
[Pacific/Gambier] => (UTC -09:00) Gambier
[America/Dawson] => (UTC -08:00) Dawson, Los Angeles, Tijuana, Vancouver, Whitehorse
[America/Santa_Isabel] => (UTC -08:00) Santa Isabel
[America/Metlakatla] => (UTC -08:00) Metlakatla, Pitcairn
[America/Dawson_Creek] => (UTC -07:00) Dawson Creek, Hermosillo, Phoenix
[America/Chihuahua] => (UTC -07:00) Chihuahua, Mazatlan
[America/Boise] => (UTC -07:00) Boise, Cambridge Bay, Denver, Edmonton, Inuvik, Ojinaga, Shiprock, Yellowknife
[America/Chicago] => (UTC -06:00) Beulah, Center, Chicago, Knox, Matamoros, Menominee, New Salem, Rainy River, Rankin Inlet, Resolute, Tell City, Winnipeg
[America/Belize] => (UTC -06:00) Belize, Costa Rica, El Salvador, Galapagos, Guatemala, Managua, Regina, Swift Current, Tegucigalpa
[Pacific/Easter] => (UTC -06:00) Easter
[America/Bahia_Banderas] => (UTC -06:00) Bahia Banderas, Cancun, Merida, Mexico City, Monterrey
[America/Detroit] => (UTC -05:00) Detroit, Grand Turk, Indianapolis, Iqaluit, Louisville, Marengo, Monticello, Montreal, Nassau, New York, Nipigon, Pangnirtung, Petersburg, Thunder Bay, Toronto, Vevay, Vincennes, Winamac
[America/Atikokan] => (UTC -05:00) Atikokan, Bogota, Cayman, Guayaquil, Jamaica, Lima, Panama, Port-au-Prince
[America/Havana] => (UTC -05:00) Havana
[America/Caracas] => (UTC -05:30) Caracas
[America/Glace_Bay] => (UTC -04:00) Bermuda, Glace Bay, Goose Bay, Halifax, Moncton, Thule
[Atlantic/Stanley] => (UTC -04:00) Stanley
[America/Santiago] => (UTC -04:00) Palmer, Santiago
[America/Anguilla] => (UTC -04:00) Anguilla, Antigua, Aruba, Barbados, Blanc-Sablon, Boa Vista, Curacao, Dominica, Eirunepe, Grenada, Guadeloupe, Guyana, Kralendijk, La Paz, Lower Princes, Manaus, Marigot, Martinique, Montserrat, Port of Spain, Porto Velho, Puerto Rico, Rio Branco, Santo Domingo, St Barthelemy, St Kitts, St Lucia, St Thomas, St Vincent, Tortola
[America/Campo_Grande] => (UTC -04:00) Campo Grande, Cuiaba
[America/Asuncion] => (UTC -04:00) Asuncion
[America/St_Johns] => (UTC -04:30) St Johns
[America/Sao_Paulo] => (UTC -03:00) Sao Paulo
[America/Araguaina] => (UTC -03:00) Araguaina, Bahia, Belem, Buenos Aires, Catamarca, Cayenne, Cordoba, Fortaleza, Jujuy, La Rioja, Maceio, Mendoza, Paramaribo, Recife, Rio Gallegos, Rothera, Salta, San Juan, Santarem, Tucuman, Ushuaia
[America/Montevideo] => (UTC -03:00) Montevideo
[America/Godthab] => (UTC -03:00) Godthab
[America/Argentina/San_Luis] => (UTC -03:00) San Luis
[America/Miquelon] => (UTC -03:00) Miquelon
[America/Noronha] => (UTC -02:00) Noronha, South Georgia
[Atlantic/Cape_Verde] => (UTC -01:00) Cape Verde
[America/Scoresbysund] => (UTC -01:00) Azores, Scoresbysund
[Atlantic/Canary] => (UTC) Canary, Dublin, Faroe, Guernsey, Isle of Man, Jersey, Lisbon, London, Madeira
[Africa/Abidjan] => (UTC) Abidjan, Accra, Bamako, Banjul, Bissau, Casablanca, Conakry, Dakar, Danmarkshavn, El Aaiun, Freetown, Lome, Monrovia, Nouakchott, Ouagadougou, Reykjavik, Sao Tome, St Helena
[Africa/Algiers] => (UTC +01:00) Algiers, Bangui, Brazzaville, Douala, Kinshasa, Lagos, Libreville, Luanda, Malabo, Ndjamena, Niamey, Porto-Novo, Tunis
[Africa/Ceuta] => (UTC +01:00) Amsterdam, Andorra, Belgrade, Berlin, Bratislava, Brussels, Budapest, Ceuta, Copenhagen, Gibraltar, Ljubljana, Longyearbyen, Luxembourg, Madrid, Malta, Monaco, Oslo, Paris, Podgorica, Prague, Rome, San Marino, Sarajevo, Skopje, Stockholm, Tirane, Vaduz, Vatican, Vienna, Warsaw, Zagreb, Zurich
[Africa/Windhoek] => (UTC +01:00) Windhoek
[Asia/Damascus] => (UTC +02:00) Damascus
[Asia/Beirut] => (UTC +02:00) Beirut
[Asia/Jerusalem] => (UTC +02:00) Jerusalem
[Asia/Nicosia] => (UTC +02:00) Athens, Bucharest, Chisinau, Helsinki, Istanbul, Mariehamn, Nicosia, Riga, Sofia, Tallinn, Vilnius
[Africa/Blantyre] => (UTC +02:00) Blantyre, Bujumbura, Cairo, Gaborone, Gaza, Harare, Hebron, Johannesburg, Kigali, Lubumbashi, Lusaka, Maputo, Maseru, Mbabane, Tripoli
[Asia/Amman] => (UTC +02:00) Amman
[Africa/Addis_Ababa] => (UTC +03:00) Addis Ababa, Aden, Antananarivo, Asmara, Baghdad, Bahrain, Comoro, Dar es Salaam, Djibouti, Juba, Kaliningrad, Kampala, Khartoum, Kiev, Kuwait, Mayotte, Minsk, Mogadishu, Nairobi, Qatar, Riyadh, Simferopol, Syowa, Uzhgorod, Zaporozhye
[Asia/Tehran] => (UTC +03:30) Tehran
[Asia/Yerevan] => (UTC +04:00) Yerevan
[Asia/Dubai] => (UTC +04:00) Dubai, Mahe, Mauritius, Moscow, Muscat, Reunion, Samara, Tbilisi, Volgograd
[Asia/Baku] => (UTC +04:00) Baku
[Asia/Kabul] => (UTC +04:30) Kabul
[Antarctica/Mawson] => (UTC +05:00) Aqtau, Aqtobe, Ashgabat, Dushanbe, Karachi, Kerguelen, Maldives, Mawson, Oral, Samarkand, Tashkent
[Asia/Colombo] => (UTC +05:30) Colombo, Kolkata
[Asia/Kathmandu] => (UTC +05:45) Kathmandu
[Antarctica/Vostok] => (UTC +06:00) Almaty, Bishkek, Chagos, Dhaka, Qyzylorda, Thimphu, Vostok, Yekaterinburg
[Asia/Rangoon] => (UTC +06:30) Cocos, Rangoon
[Antarctica/Davis] => (UTC +07:00) Bangkok, Christmas, Davis, Ho Chi Minh, Hovd, Jakarta, Novokuznetsk, Novosibirsk, Omsk, Phnom Penh, Pontianak, Vientiane
[Antarctica/Casey] => (UTC +08:00) Brunei, Casey, Choibalsan, Chongqing, Harbin, Hong Kong, Kashgar, Krasnoyarsk, Kuala Lumpur, Kuching, Macau, Makassar, Manila, Perth, Shanghai, Singapore, Taipei, Ulaanbaatar, Urumqi
[Australia/Eucla] => (UTC +08:45) Eucla
[Asia/Dili] => (UTC +09:00) Dili, Irkutsk, Jayapura, Palau, Pyongyang, Seoul, Tokyo
[Australia/Adelaide] => (UTC +09:30) Adelaide, Broken Hill
[Australia/Darwin] => (UTC +09:30) Darwin
[Antarctica/DumontDUrville] => (UTC +10:00) Brisbane, Chuuk, DumontDUrville, Guam, Lindeman, Port Moresby, Saipan, Yakutsk
[Australia/Currie] => (UTC +10:00) Currie, Hobart, Melbourne, Sydney
[Australia/Lord_Howe] => (UTC +10:30) Lord Howe
[Antarctica/Macquarie] => (UTC +11:00) Efate, Guadalcanal, Kosrae, Macquarie, Noumea, Pohnpei, Sakhalin, Vladivostok
[Pacific/Norfolk] => (UTC +11:30) Norfolk
[Antarctica/McMurdo] => (UTC +12:00) Auckland, McMurdo, South Pole
[Asia/Anadyr] => (UTC +12:00) Anadyr, Fiji, Funafuti, Kamchatka, Kwajalein, Magadan, Majuro, Nauru, Tarawa, Wake, Wallis
[Pacific/Chatham] => (UTC +12:45) Chatham
[Pacific/Enderbury] => (UTC +13:00) Enderbury, Tongatapu
[Pacific/Apia] => (UTC +13:00) Apia
[Pacific/Kiritimati] => (UTC +14:00) Kiritimati
)
Zugegeben, die Verkettung von Städten ist immer noch verdammt lang, aber die Liste der eindeutigen (tatsächlichen) Zeitzonen ist von 414 (oder 415, wenn wir die nicht geografische UTC betrachten) auf 75 gesunken – was meiner Meinung nach ziemlich gut ist und dies widerzuspiegeln scheint Liste der “normalisierten” Zeitzonen, die Windows verwendet (auch 75).
Bei diesem automatisierten Ansatz gibt es zwei große Probleme:
- die gewählte Zeitzonen-ID für eine Gruppe von Städten ist die erste in alphabetischer Reihenfolge, das bedeutet, dass z (UTC) Kanaren, Dublin, Färöer, Guernsey, Isle of Man, Jersey, Lissabon, London, Madeira der Zeitzonenwert wird sein
Atlantic/Canary
– Obwohl daran nichts auszusetzen sein sollte, wäre es sinnvoller, eine Zeitzonen-ID auszuwählen, die einer größeren Stadt zugeordnet ist (z Europe/London
)
- Die Verkettung von Städten ist eindeutig das größte Problem, es gibt einfach zu viele davon – eine Möglichkeit, dieses Problem zu lösen, wäre die Verwendung von
array_slice($cities, 0, $maxCities)
vor dem Implodieren, aber dies würde die Stadtdimension nicht berücksichtigen und für ein Limit von 4 Kanaren, Dublin, Färöer, Guernsey, Isle of Man, Jersey, Lissabon, London, Madeira würde werden Kanaren, Dublin, Färöer, Guernsey anstelle des logischeren Windows-Äquivalents Dublin, Edinburgh, Lissabon, London.
Dies sollte nicht sehr nützlich sein, aber ich dachte, ich würde es teilen – vielleicht kann es jemand anderes verbessern.
Am Ende des Tages glaube ich nicht, dass es eine gute Lösung gibt, um die zu große Liste von Zeitzonen vorab auszusortieren … Und die damit verbundenen Probleme haben mich dazu veranlasst, einfach mit einer anständig großen Klasse zu beginnen. Ich poste es hier, weil es einige Leute gab, die sich dafür interessierten. Hoffentlich hilft meine Lösung auch jemand anderem.
Was es macht:
-
Ermöglicht das Erstellen einer Liste von Zeitzonen aus der gesamten Liste innerhalb von PHP
-
Hiermit können Sie eine schöne Liste aus Ihren eigenen vorgefertigten Definitionen erstellen und aktuelle UTC-Offsets berechnen.
-
Ermöglicht das Erstellen einer Liste nach Ländern.
-
Dedupliziert Zeitzonen mit derselben Abkürzung. Beachten Sie, dass ich nicht viel recherchiert habe, um zu sehen, ob es Duplikate in der Liste gibt, die ich nicht loswerden sollte. Es ist klug genug zu wissen, dass, obwohl zwei Zeitzonen möglicherweise dieselbe Abkürzung melden (z. B. MST für Arizona), weiter eingegeben wird, ob die Zeitzone die Sommerzeit zu jeder Jahreszeit unterstützt oder nicht.
-
Gibt entweder ziemlich konfigurierbares HTML aus (ohne in die Template-Route zu gehen) oder JSON für Ajax oder Inline-JavaScript.
-
Berechnet den aktuellen Zeitzonenoffset für eine beliebige Zeitzone. Beachten Sie, dass dies nicht statisch ist … es wird sich im Laufe des Jahres ändern.
-
Bietet große Mengen an Zucker für den realen Gebrauch.
Was es nicht tut:
- Trennen Sie Länder oder Kontinente durch eine OptGroup heraus. Da ich bereits eine Sortierung nach UTC-Offset durchführe, schien dies mehr Verwirrung zu stiften, als es zu lindern.
Dinge, die ich eines Tages hinzufügen könnte:
-
Erstellen Sie den HTML-Code aus der Vorlage statt wie hier inline.
-
Zusätzliche Selektoren, wie z. B. die Auswahl einer Reihe von Ländern anstelle eines einzelnen.
-
Gruppieren, aber wie ich oben erwähnt habe, bin ich dabei.
-
Code ist ziemlich nass. Es gibt einige geringfügige Unterschiede im Codierungsstil.
-
Möglichkeit, eine „bevorzugte“ Liste mit Anzeigenamen anzugeben. Obwohl zum Beispiel „Dawson“ ein absolut brauchbarer Kandidat ist, um als „die“ Stadt für die PDT aufgeführt zu werden, da sie Teil der PST-Hauptgruppe ist und Sommerzeit einhält … sollte eine Stadt mit etwas mehr als 1000 Einwohnern dies nicht tun Los Angeles, San Francisco, Seattle oder Vancouver schlagen, nur weil es lexikalisch zuerst auftaucht.
-
Rohausgabe, damit niemand an die einfachen Methoden „toSelect“ und „toJson“ gebunden ist.
Im Allgemeinen sollte es so wie es ist meinen Bedürfnissen entsprechen. Es verarbeitet alle Zeitzonen, mit denen ich vertraut bin, und alle, die ich für mein aktuelles Projekt benötige. Leider konzentriert sich mein Wissensbereich hauptsächlich auf die USA und Westeuropa.
Ist es perfekt? Wahrscheinlich nicht. Ich freue mich, von Problemen/Fehlern/Verbesserungen zu hören, die jemand mit diesem Code haben könnte, da er wahrscheinlich in meiner permanenten Bibliothek landen wird. Wenn jemand denkt, dass ich high bin… lass es mich auch wissen. Das war der springende Punkt bei dieser Frage, um den besten Weg zu finden, einen Zeitzonenselektor genau darzustellen, der für Endbenutzer tatsächlich etwas nützlich ist.
Zeitzonenliste.php:
<?php
class TimezoneList
{
public $timezones = array();
private $_initialized = false;
private $_dt_now;
private $_utc;
function __construct($grouped = false)
{
$this->_utc = new DateTimeZone('UTC');
$this->_dt_now = new DateTime('now', $this->_utc);
}
// Public Static Alternate Constructors
public static function byCountry($countryKey)
{
$retVal = new TimezoneList();
$retVal->_setList($countryKey);
return $retVal;
}
public static function fromTimezones(Array $tzArr)
{
$retVal = new TimezoneList();
foreach ($tzArr as $tzItem)
{
$retVal->timezones[] = $tzItem;
}
$retVal->_initialized = true;
return $retVal;
}
public static function fromIdentifierList($timezoneList, $friendlyNames = NULL)
{
$retVal = new TimezoneList();
if ($friendlyNames)
{
if (count($timezoneList) != count($friendlyNames)) throw new Exception('Array count mismatch in TimezoneBuilder::fromList');
}
// I'd normally use a foreach pattern, but since friendlyNames is optional, this seemed the way to go.
for ($ii = 0; $ii < count($timezoneList); $ii++)
{
$pTimezoneEx = new TimezoneExtended($timezoneList[$ii]);
if ($friendlyNames)
{
$pTimezoneEx->friendlyName = $friendlyNames[$ii];
}
$retVal->timezones[] = $pTimezoneEx;
}
$retVal->_initialized = true;
return $retVal;
}
// Private Statics
// Private utility function [ Thanks to Zubair1 ]
private static function _formatOffset($offset)
{
$hours = $offset / 3600;
$remainder = $offset % 3600;
$sign = $hours > 0 ? '+' : '-';
$hour = (int)abs($hours);
$minutes = (int)abs($remainder / 60);
$sign = (($hour == 0) && ($minutes == 0)) ? ' ' : $sign;
return $sign.str_pad($hour, 2, '0', STR_PAD_LEFT).':'.str_pad($minutes,2, '0');
}
// Publics
public function getUniqueTimezoneList($countryKey = null)
{
$this->_initialize();
$outArr = array();
$usedTzs = array();
foreach ($this->timezones as $timezoneEx)
{
if (!(in_array($timezoneEx->currentKey, $usedTzs)))
{
$usedTzs[] = $timezoneEx->currentKey;
$outArr[] = $timezoneEx;
}
}
usort($outArr,array('self','_orderByOffset'));
return self::fromTimezones($outArr);
}
// In final code, I'll use a PHP include with output buffering as a template.
public function toSelect($displayOffset = true, $displayCurrent = true, $selected = array(), Array $options = array())
{
$pOpts = array();
$pItems = array();
foreach ($options as $key=>$option)
{
$pOpts[] = ' '.$key.'="'.$option.'"';
}
if (!is_array($selected)) $selected = array($selected);
$outVal="<select".implode('', $pOpts).'>'."\n";
foreach ($this->timezones as $timezoneEx)
{
$offset="";
$selectionAttr="";
if (in_array($timezoneEx->tzkey, $selected))
{
$selectionAttr=" selected="selected"";
}
if ($displayOffset)
{
$offset=" [".$timezoneEx->currentAbbr.' '.self::_formatOffset($timezoneEx->currentOffset);
if ($displayCurrent && (!($timezoneEx->observesDst))) $offset .= ' ( Does not observe DST ) ';
$offset .= ']';
}
$pItems[] = "\t".'<option value="'.$timezoneEx->tzkey.'"'.$selectionAttr.'>'.$timezoneEx->friendlyName.$offset.'</option>';
}
$outVal .= implode("\n", $pItems)."\n".'</select>';
return $outVal;
}
public function toJson()
{
$outArr = array();
foreach ($this->timezones as $timezoneEx)
{
$outArr[] = $timezoneEx->toShallowArray();
}
return json_encode($outArr);
}
// Privates
private function _initialize()
{
if ($this->_initialized) return;
$this->_setList();
}
private function _orderByOffset($a, $b)
{
if( $a->currentOffset == $b->currentOffset ){ return 0 ; }
return ($a->currentOffset < $b->currentOffset) ? -1 : 1;
}
private function _setList($countryKey = NULL)
{
$this->timezones = array();
$listType = ($countryKey) ? DateTimeZone::PER_COUNTRY : DateTimeZone::ALL;
$tzIds = DateTimeZone::listIdentifiers($listType, $countryKey);
foreach ($tzIds as $tzIdentifier)
{
$this->timezones[] = new TimezoneExtended($tzIdentifier);
}
$this->_initialized = true;
}
}
class TimezoneExtended
{
const START_YEAR = 'January 1st';
const MID_YEAR = 'July 1st';
private static $_dt_startYear = NULL; // Static so that we don't have to rebuild it each time we go through.
private static $_dt_midYear = NULL;
private static $_dtz_utc = NULL;
private static $_dt_now = NULL;
private $_baseObj;
public $tzkey;
public $friendlyName;
public $currentKey; // Current Key contains the friendly Timezone Key + whether this timezone observes DST.
// This is unique across the US & Canada. Unsure if it will be unique across other Timezones.
public $currentAbbr;
public $currentOffset;
public $currentlyDst;
public $observesDst = false; // Defaults to off
function __construct($tzKey)
{
if (empty(self::$_dtz_utc)) self::$_dtz_utc = new DateTimeZone('UTC');
if (empty(self::$_dtz_now)) self::$_dt_now = new DateTime('now', self::$_dtz_utc);
if (empty(self::$_dt_startYear)) self::$_dt_startYear = new DateTime(self::START_YEAR, self::$_dtz_utc);
if (empty(self::$_dt_midYear)) self::$_dt_midYear = new DateTime(self::MID_YEAR, self::$_dtz_utc);
$this->tzkey = $tzKey;
$this->_baseObj = new DateTimeZone($tzKey);
if ($this->_baseObj == NULL) throw new Exception('Invalid Timezone Key');
foreach ($this->_baseObj->getTransitions(self::$_dt_startYear->getTimestamp()) as $transition)
{
if ($transition['isdst']) $this->observesDst = true;
}
foreach ($this->_baseObj->getTransitions(self::$_dt_midYear->getTimestamp()) as $transition)
{
if ($transition['isdst']) $this->observesDst = true;
}
$this->friendlyName =str_replace('_',' ',array_pop(explode("https://stackoverflow.com/",$tzKey)));
$pTransition = $this->_baseObj->getTransitions(self::$_dt_now->getTimestamp());
$this->currentAbbr = $pTransition[0]['abbr']; // With a Timestamp, we should only get one transition.
$this->currentlyDst = $pTransition[0]['isdst'];
$this->currentKey = $this->currentAbbr.'_'.$this->observesDst;
$this->currentOffset = $this->_baseObj->getOffset(self::$_dt_now);
}
public function toShallowArray()
{
$outArr = array(
'tzkey'=>$this->tzkey,
'friendlyName'=>$this->friendlyName,
'currentOffset'=>$this->currentOffset/3600,
'observesDst'=>$this->observesDst,
'currentlyDst'=>$this->currentlyDst,
'currentAbbr'=>$this->currentAbbr
);
return $outArr;
}
}
Wütend. Hier sind Anwendungsbeispiele (timezones.php):
<?php
include_once 'TimezoneList.php';
/* Example 1: Get Select Box by Country Code */
$tzl = TimezoneList::byCountry('US');
$tzl = $tzl->getUniqueTimezoneList();
echo $tzl->toSelect(true,true,'America/Los_Angeles');
echo "\n".'<br />'."\n";
/* Example 2: Get a list by country code, output as JSON for AJAX (or similar uses) */
$_REQUEST['country_code'] = 'US'; // Hack for quick usage.
$tzl_ajax = TimezoneList::byCountry($_REQUEST['country_code']);
$tzl_ajax = $tzl_ajax->getUniqueTimezoneList();
echo '<script type="text/javascript">'."\n";
echo 'var foo = '.$tzl_ajax->toJson().';';
echo "\n".'</script>';
echo "\n".'<br />'."\n";
/* Example 3: Get Select Box from a list of TZDs + friendly names */
$tzl2 = TimezoneList::fromIdentifierList(
array('America/Los_Angeles','America/Boise','America/Phoenix','America/Chicago','America/New_York'),
array('Pacific','Mountain','Mountain (Arizona)','Central','Eastern')
);
// Example shows setting extra properties on the <SELECT>.
echo $tzl2->toSelect(true,false,'America/Los_Angeles',
array('style'=>'font-size:15px; border:1px solid #ccc; padding:4px', 'id'=>'timezone_list', 'class'=>'standard-list', 'name'=>'timezone')
);
echo "\n".'<br />'."\n";
/* Example 4: Get a raw list of timezones */
$tzl3 = new TimezoneList(true);
$tzl3 = $tzl3->getUniqueTimezoneList();
echo $tzl3->toSelect(true,false,'America/Los_Angeles');
Und hier ist der Ausgabecode aus den Beispielen in timezones.php:
<select>
<option value="Pacific/Honolulu">Honolulu [HST -10:00 ( Does not observe DST ) ]</option>
<option value="America/Adak">Adak [HADT -09:00]</option>
<option value="America/Anchorage">Anchorage [AKDT -08:00]</option>
<option value="America/Phoenix">Phoenix [MST -07:00 ( Does not observe DST ) ]</option>
<option value="America/Los_Angeles" selected="selected">Los Angeles [PDT -07:00]</option>
<option value="America/Boise">Boise [MDT -06:00]</option>
<option value="America/Chicago">Chicago [CDT -05:00]</option>
<option value="America/Detroit">Detroit [EDT -04:00]</option>
</select>
<br />
<script type="text/javascript">
var foo = [{"tzkey":"Pacific\/Honolulu","friendlyName":"Honolulu","currentOffset":-10,"observesDst":false,"currentlyDst":false,"currentAbbr":"HST"},{"tzkey":"America\/Adak","friendlyName":"Adak","currentOffset":-9,"observesDst":true,"currentlyDst":true,"currentAbbr":"HADT"},{"tzkey":"America\/Anchorage","friendlyName":"Anchorage","currentOffset":-8,"observesDst":true,"currentlyDst":true,"currentAbbr":"AKDT"},{"tzkey":"America\/Phoenix","friendlyName":"Phoenix","currentOffset":-7,"observesDst":false,"currentlyDst":false,"currentAbbr":"MST"},{"tzkey":"America\/Los_Angeles","friendlyName":"Los Angeles","currentOffset":-7,"observesDst":true,"currentlyDst":true,"currentAbbr":"PDT"},{"tzkey":"America\/Boise","friendlyName":"Boise","currentOffset":-6,"observesDst":true,"currentlyDst":true,"currentAbbr":"MDT"},{"tzkey":"America\/Chicago","friendlyName":"Chicago","currentOffset":-5,"observesDst":true,"currentlyDst":true,"currentAbbr":"CDT"},{"tzkey":"America\/Detroit","friendlyName":"Detroit","currentOffset":-4,"observesDst":true,"currentlyDst":true,"currentAbbr":"EDT"}];
</script>
<br />
<select style="font-size:15px; border:1px solid #ccc; padding:4px" id="timezone_list" class="standard-list" name="timezone">
<option value="America/Los_Angeles" selected="selected">Pacific [PDT -07:00]</option>
<option value="America/Boise">Mountain [MDT -06:00]</option>
<option value="America/Phoenix">Mountain (Arizona) [MST -07:00]</option>
<option value="America/Chicago">Central [CDT -05:00]</option>
<option value="America/New_York">Eastern [EDT -04:00]</option>
</select>
<br />
<select>
<option value="Pacific/Midway">Midway [SST -11:00]</option>
<option value="Pacific/Niue">Niue [NUT -11:00]</option>
<option value="Pacific/Apia">Apia [WST -11:00]</option>
<option value="Pacific/Tahiti">Tahiti [TAHT -10:00]</option>
<option value="Pacific/Honolulu">Honolulu [HST -10:00]</option>
<option value="Pacific/Rarotonga">Rarotonga [CKT -10:00]</option>
<option value="Pacific/Fakaofo">Fakaofo [TKT -10:00]</option>
<option value="Pacific/Marquesas">Marquesas [MART -09:30]</option>
<option value="America/Adak">Adak [HADT -09:00]</option>
<option value="Pacific/Gambier">Gambier [GAMT -09:00]</option>
<option value="America/Anchorage">Anchorage [AKDT -08:00]</option>
<option value="Pacific/Pitcairn">Pitcairn [PST -08:00]</option>
<option value="America/Dawson_Creek">Dawson Creek [MST -07:00]</option>
<option value="America/Dawson">Dawson [PDT -07:00]</option>
<option value="America/Belize">Belize [CST -06:00]</option>
<option value="America/Boise">Boise [MDT -06:00]</option>
<option value="Pacific/Easter">Easter [EAST -06:00]</option>
<option value="Pacific/Galapagos">Galapagos [GALT -06:00]</option>
<option value="America/Resolute">Resolute [CDT -05:00]</option>
<option value="America/Cancun">Cancun [CDT -05:00]</option>
<option value="America/Guayaquil">Guayaquil [ECT -05:00]</option>
<option value="America/Lima">Lima [PET -05:00]</option>
<option value="America/Bogota">Bogota [COT -05:00]</option>
<option value="America/Atikokan">Atikokan [EST -05:00]</option>
<option value="America/Caracas">Caracas [VET -04:30]</option>
<option value="America/Guyana">Guyana [GYT -04:00]</option>
<option value="America/Campo_Grande">Campo Grande [AMT -04:00]</option>
<option value="America/La_Paz">La Paz [BOT -04:00]</option>
<option value="America/Anguilla">Anguilla [AST -04:00]</option>
<option value="Atlantic/Stanley">Stanley [FKT -04:00]</option>
<option value="America/Detroit">Detroit [EDT -04:00]</option>
<option value="America/Boa_Vista">Boa Vista [AMT -04:00]</option>
<option value="America/Santiago">Santiago [CLT -04:00]</option>
<option value="America/Asuncion">Asuncion [PYT -04:00]</option>
<option value="Antarctica/Rothera">Rothera [ROTT -03:00]</option>
<option value="America/Paramaribo">Paramaribo [SRT -03:00]</option>
<option value="America/Sao_Paulo">Sao Paulo [BRT -03:00]</option>
<option value="America/Argentina/Buenos_Aires">Buenos Aires [ART -03:00]</option>
<option value="America/Cayenne">Cayenne [GFT -03:00]</option>
<option value="America/Glace_Bay">Glace Bay [ADT -03:00]</option>
<option value="America/Argentina/San_Luis">San Luis [WARST -03:00]</option>
<option value="America/Araguaina">Araguaina [BRT -03:00]</option>
<option value="America/Montevideo">Montevideo [UYT -03:00]</option>
<option value="America/St_Johns">St Johns [NDT -02:30]</option>
<option value="America/Miquelon">Miquelon [PMDT -02:00]</option>
<option value="America/Noronha">Noronha [FNT -02:00]</option>
<option value="America/Godthab">Godthab [WGST -02:00]</option>
<option value="Atlantic/Cape_Verde">Cape Verde [CVT -01:00]</option>
<option value="Atlantic/Azores">Azores [AZOST 00:00]</option>
<option value="America/Scoresbysund">Scoresbysund [EGST 00:00]</option>
<option value="UTC">UTC [UTC 00:00]</option>
<option value="Africa/Abidjan">Abidjan [GMT 00:00]</option>
<option value="Africa/Casablanca">Casablanca [WET 00:00]</option>
<option value="Africa/Bangui">Bangui [WAT +01:00]</option>
<option value="Europe/Guernsey">Guernsey [BST +01:00]</option>
<option value="Europe/Dublin">Dublin [IST +01:00]</option>
<option value="Africa/Algiers">Algiers [CET +01:00]</option>
<option value="Atlantic/Canary">Canary [WEST +01:00]</option>
<option value="Africa/Windhoek">Windhoek [WAT +01:00]</option>
<option value="Africa/Johannesburg">Johannesburg [SAST +02:00]</option>
<option value="Africa/Blantyre">Blantyre [CAT +02:00]</option>
<option value="Africa/Tripoli">Tripoli [EET +02:00]</option>
<option value="Africa/Ceuta">Ceuta [CEST +02:00]</option>
<option value="Asia/Jerusalem">Jerusalem [IDT +03:00]</option>
<option value="Africa/Addis_Ababa">Addis Ababa [EAT +03:00]</option>
<option value="Africa/Cairo">Cairo [EEST +03:00]</option>
<option value="Antarctica/Syowa">Syowa [SYOT +03:00]</option>
<option value="Europe/Volgograd">Volgograd [VOLST +04:00]</option>
<option value="Europe/Samara">Samara [SAMST +04:00]</option>
<option value="Asia/Tbilisi">Tbilisi [GET +04:00]</option>
<option value="Europe/Moscow">Moscow [MSD +04:00]</option>
<option value="Asia/Dubai">Dubai [GST +04:00]</option>
<option value="Indian/Mauritius">Mauritius [MUT +04:00]</option>
<option value="Indian/Reunion">Reunion [RET +04:00]</option>
<option value="Indian/Mahe">Mahe [SCT +04:00]</option>
<option value="Asia/Tehran">Tehran [IRDT +04:30]</option>
<option value="Asia/Kabul">Kabul [AFT +04:30]</option>
<option value="Asia/Aqtau">Aqtau [AQTT +05:00]</option>
<option value="Asia/Ashgabat">Ashgabat [TMT +05:00]</option>
<option value="Asia/Oral">Oral [ORAT +05:00]</option>
<option value="Asia/Yerevan">Yerevan [AMST +05:00]</option>
<option value="Asia/Baku">Baku [AZST +05:00]</option>
<option value="Indian/Kerguelen">Kerguelen [TFT +05:00]</option>
<option value="Indian/Maldives">Maldives [MVT +05:00]</option>
<option value="Asia/Karachi">Karachi [PKT +05:00]</option>
<option value="Asia/Dushanbe">Dushanbe [TJT +05:00]</option>
<option value="Asia/Samarkand">Samarkand [UZT +05:00]</option>
<option value="Antarctica/Mawson">Mawson [MAWT +05:00]</option>
<option value="Asia/Colombo">Colombo [IST +05:30]</option>
<option value="Asia/Kathmandu">Kathmandu [NPT +05:45]</option>
<option value="Indian/Chagos">Chagos [IOT +06:00]</option>
<option value="Asia/Bishkek">Bishkek [KGT +06:00]</option>
<option value="Asia/Almaty">Almaty [ALMT +06:00]</option>
<option value="Antarctica/Vostok">Vostok [VOST +06:00]</option>
<option value="Asia/Yekaterinburg">Yekaterinburg [YEKST +06:00]</option>
<option value="Asia/Dhaka">Dhaka [BDT +06:00]</option>
<option value="Asia/Thimphu">Thimphu [BTT +06:00]</option>
<option value="Asia/Qyzylorda">Qyzylorda [QYZT +06:00]</option>
<option value="Indian/Cocos">Cocos [CCT +06:30]</option>
<option value="Asia/Rangoon">Rangoon [MMT +06:30]</option>
<option value="Asia/Jakarta">Jakarta [WIT +07:00]</option>
<option value="Asia/Hovd">Hovd [HOVT +07:00]</option>
<option value="Antarctica/Davis">Davis [DAVT +07:00]</option>
<option value="Asia/Bangkok">Bangkok [ICT +07:00]</option>
<option value="Indian/Christmas">Christmas [CXT +07:00]</option>
<option value="Asia/Omsk">Omsk [OMSST +07:00]</option>
<option value="Asia/Novokuznetsk">Novokuznetsk [NOVST +07:00]</option>
<option value="Asia/Choibalsan">Choibalsan [CHOT +08:00]</option>
<option value="Asia/Ulaanbaatar">Ulaanbaatar [ULAT +08:00]</option>
<option value="Asia/Brunei">Brunei [BNT +08:00]</option>
<option value="Antarctica/Casey">Casey [WST +08:00]</option>
<option value="Asia/Singapore">Singapore [SGT +08:00]</option>
<option value="Asia/Manila">Manila [PHT +08:00]</option>
<option value="Asia/Hong_Kong">Hong Kong [HKT +08:00]</option>
<option value="Asia/Krasnoyarsk">Krasnoyarsk [KRAST +08:00]</option>
<option value="Asia/Makassar">Makassar [CIT +08:00]</option>
<option value="Asia/Kuala_Lumpur">Kuala Lumpur [MYT +08:00]</option>
<option value="Australia/Eucla">Eucla [CWST +08:45]</option>
<option value="Pacific/Palau">Palau [PWT +09:00]</option>
<option value="Asia/Tokyo">Tokyo [JST +09:00]</option>
<option value="Asia/Dili">Dili [TLT +09:00]</option>
<option value="Asia/Jayapura">Jayapura [EIT +09:00]</option>
<option value="Asia/Pyongyang">Pyongyang [KST +09:00]</option>
<option value="Asia/Irkutsk">Irkutsk [IRKST +09:00]</option>
<option value="Australia/Adelaide">Adelaide [CST +09:30]</option>
<option value="Asia/Yakutsk">Yakutsk [YAKST +10:00]</option>
<option value="Australia/Currie">Currie [EST +10:00]</option>
<option value="Pacific/Port_Moresby">Port Moresby [PGT +10:00]</option>
<option value="Pacific/Guam">Guam [ChST +10:00]</option>
<option value="Pacific/Truk">Truk [TRUT +10:00]</option>
<option value="Antarctica/DumontDUrville">DumontDUrville [DDUT +10:00]</option>
<option value="Australia/Lord_Howe">Lord Howe [LHST +10:30]</option>
<option value="Pacific/Ponape">Ponape [PONT +11:00]</option>
<option value="Pacific/Kosrae">Kosrae [KOST +11:00]</option>
<option value="Antarctica/Macquarie">Macquarie [MIST +11:00]</option>
<option value="Pacific/Noumea">Noumea [NCT +11:00]</option>
<option value="Pacific/Efate">Efate [VUT +11:00]</option>
<option value="Pacific/Guadalcanal">Guadalcanal [SBT +11:00]</option>
<option value="Asia/Sakhalin">Sakhalin [SAKST +11:00]</option>
<option value="Asia/Vladivostok">Vladivostok [VLAST +11:00]</option>
<option value="Pacific/Norfolk">Norfolk [NFT +11:30]</option>
<option value="Asia/Kamchatka">Kamchatka [PETST +12:00]</option>
<option value="Pacific/Tarawa">Tarawa [GILT +12:00]</option>
<option value="Asia/Magadan">Magadan [MAGST +12:00]</option>
<option value="Pacific/Wallis">Wallis [WFT +12:00]</option>
<option value="Pacific/Kwajalein">Kwajalein [MHT +12:00]</option>
<option value="Pacific/Funafuti">Funafuti [TVT +12:00]</option>
<option value="Pacific/Nauru">Nauru [NRT +12:00]</option>
<option value="Asia/Anadyr">Anadyr [ANAST +12:00]</option>
<option value="Antarctica/McMurdo">McMurdo [NZST +12:00]</option>
<option value="Pacific/Wake">Wake [WAKT +12:00]</option>
<option value="Pacific/Fiji">Fiji [FJT +12:00]</option>
<option value="Pacific/Chatham">Chatham [CHAST +12:45]</option>
<option value="Pacific/Enderbury">Enderbury [PHOT +13:00]</option>
<option value="Pacific/Tongatapu">Tongatapu [TOT +13:00]</option>
<option value="Pacific/Kiritimati">Kiritimati [LINT +14:00]</option>
</select>
DateTimeZone::listIdentifiers
? Das gibt ein Array zurück, aus dem Sie leicht eine Auswahlbox erstellen könnten. Falls gewünscht, können Sie das Array filtern – nützliches Beispiel hier.– Jon Gauthier
3. August 2011 um 5:01 Uhr
@Hans Engel – Ja, aber wie gesagt … mehr als 300 Zeitzonen sind lächerlich … zumal es nicht unbedingt erforderlich ist, 12-16 Variationen derselben Zeitzone zu haben, die denselben DST-Regeln folgen. Das ist eigentlich die Lösung, die ich versuche loszuwerden. 🙂
– Johannes Grün
3. August 2011 um 7:01 Uhr
Verfolge diesen Thread mit Interesse, da ich im Moment auch das gleiche Problem habe 🙂
– F21
16. August 2011 um 0:35 Uhr
Benutzt du PHP 5.3? Wenn ja, werde ich die Lösung hier posten.
– Pedro Lobito
16. August 2011 um 1:56 Uhr
@Tuga – Ja, 5.3. Offen für Lösungen in jedem Geschmack. 🙂
– Johannes Grün
16. August 2011 um 2:11 Uhr