Bester Weg, um a zu füllen Feld mit Zeitzonen

Lesezeit: 33 Minuten

Benutzer-Avatar
Johannes Grün

Ich muss eine Zeitzonenauswahl als Benutzersteuerung anzeigen, was immer einfacher erscheint, als es wirklich ist. Intern speichere ich alles mit einem DateTimeZone Identifier, da dies der klügste Weg zu sein scheint, um das Maß an Genauigkeit zu erreichen, das ich brauche, da dieses Projekt reale Zeiten überbrückt, da es an terrestrische Medien gebunden ist.

Was ich nicht tun möchte, ist, ein Auswahlfeld mit mehr als 300 Zeitzonen anzuzeigen, und ich möchte auch keine gefälschten Zeitzonen-Offsets mit etwas wie “UTC-8” erstellen (wobei nicht nur DST-Informationen verloren gehen, sondern auch die tatsächlichen Daten, die die DST fällt auf).

Am Ende brauche ich eine Auswahl mit Optionen, die die richtigen TZD-Identifikatoren enthalten, etwa so (die eingeklammerten #s sind nicht erforderlich, nur zur Veranschaulichung für potenzielle Endbenutzer):

<select>
<option value="America/Los_Angeles">Los Angeles [UTC-7 | DST]</option>
...
</select>

Hat jemand irgendwelche Hinweise für den Aufbau dieser Liste? Alle Lösungen, die ich gegoogelt habe, waren auf die eine oder andere Weise problematisch.


Ich habe ein Kopfgeld hinzugefügt, falls das jemanden dazu verleiten könnte, eine nettere Antwort mit uns zu teilen. 🙂

  • 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

Benutzer-Avatar
Zubair1

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 $sign . str_pad($hour, 2, '0', STR_PAD_LEFT) .':'. str_pad($minutes,2, '0');

}

$utc = new DateTimeZone('UTC');
$dt = new DateTime('now', $utc);

echo '<select name="userTimeZone">';
foreach(DateTimeZone::listIdentifiers() as $tz) {
    $current_tz = new DateTimeZone($tz);
    $offset =  $current_tz->getOffset($dt);
    $transition =  $current_tz->getTransitions($dt->getTimestamp(), $dt->getTimestamp());
    $abbr = $transition[0]['abbr'];

    echo '<option value="' .$tz. '">' .$tz. ' [' .$abbr. ' '. formatOffset($offset). ']</option>';
}
echo '</select>';

Das Obige gibt alle Zeitzonen im Auswahlmenü mit dem folgenden Format aus:

<select name="userTimeZone">
<option value="America/Los_Angeles">America/Los_Angeles [PDT -7]</option>
</select>

  • Nur als Update, Sie sind der Spitzenreiter für das Kopfgeld. Hat mein Problem per se nicht gelöst, aber du warst so nett, den Format-Parser zu schreiben, der auf den ersten Blick ziemlich gut aussieht. 🙂

    – Johannes Grün

    13. August 2011 um 2:57 Uhr

  • @JohnGreen-PageSpike: Der Offset-Formatierer könnte auf eine einzelne Zeile vereinfacht werden: sprintf('%+03d:%02u', floor($offset / 3600), floor(abs($offset) % 3600 / 60)).

    – Alix Axel

    18. Oktober 2011 um 17:16 Uhr

Benutzer-Avatar
Pedro Lobito

Meine Lösung:

Um eine riesige Zeitzonenliste zu vermeiden, lassen Sie den Benutzer zuerst das Land auswählen und verwenden Sie dann diese Informationen, um eine Liste mit Zeitzonen zu füllen.

Datei bevölkern.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>Select test</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
        <script type="text/javascript" charset="utf-8">
        $(function(){
            $("select#country").change(function(){
                $.getJSON("json.php",{country: $(this).val()}, function(j){
                    var options="";
                    for (var i = 0; i < j.length; i++) {
                        options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
                    }
                    $("#city").html(options);
                    $('#city option:first').attr('selected', 'selected');
                })
            })            
        })
        </script>
    </head>

    <body>

<form action="#">
  <label for="country">Country:</label>
  <select name="country" id="country">
    <option value="Portugal">Portugal</option>
    <option value="United States">United States</option>
    <option value="Japan">Japan</option>
  </select>
  <label for="city">Timezone:</label>
  <select name="city" id="city">
    <option value="Atlantic/Azores">Atlantic/Azores</option>
    <option value="Atlantic/Madeira">Atlantic/Madeira</option>
    <option value="Europe/Lisbon">Europe/Lisbon</option>
  </select>
<input type="submit" name="action" value="Set TZ" />
</form>

Datei json.php

$country = $_GET['country'];
$citylist = "";
$country_list = file_get_contents("country_iso.txt"); //grab this file @ http://pastebin.com/e8gxcVHm

preg_match_all('/(.*?):'.$country.'/im', $country_list, $country_iso, PREG_PATTERN_ORDER);
$country_iso = $country_iso[1][0];


if(isset($country_iso))
{
$tz = DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $country_iso); //php 5.3 needed to use DateTimeZone::PER_COUNTRY !

foreach($tz as $city)   
    $citylist .= "{\"optionValue\": \"$city\", \"optionDisplay\": \"$city\"}, ";   
}

$citylist = preg_replace('/, $/im', '', $citylist);
$citylist = "[".$citylist."]";

echo $citylist; 

Ich hoffe es hilft dir 🙂

  • Dies hilft bei der Auswahl aus 300 Zeitzonen, indem die Liste nach Ländern aufgeteilt wird. Es listet jedoch immer noch mehrere Zeitzonen pro Stadt auf und unterscheidet nicht zwischen den Einhaltungen der Sommerzeit. Abgesehen davon gibt es hier Elemente, die ich wahrscheinlich zur endgültigen Lösung hinzufügen werde. Vielen Dank.

    – Johannes Grün

    16. August 2011 um 2:52 Uhr

Wenn Sie mit zoneinfo arbeiten wollen, haben Sie eigentlich keine andere Wahl, als Hunderte von Einträgen einzufügen, denn so funktioniert zoneinfo. Es hat in der Regel mindestens einen Eintrag pro Land, und es gibt rund 200 Länder (lt Wikipedia).

Was ich vorher gemacht habe, ist zu verwenden timezone_identifiers_list() und filtern Sie alle Einträge heraus, die sich nicht in einer der Standardregionen befinden:

# Output option list, HTML.
$opt="";

$regions = array('Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific');
$tzs = timezone_identifiers_list();
$optgroup = '';
sort($tzs);
foreach ($tzs as $tz) {
    $z = explode("https://stackoverflow.com/", $tz, 2);
    # timezone_identifiers_list() returns a number of
    # backwards-compatibility entries. This filters them out of the 
    # list presented to the user.
    if (count($z) != 2 || !in_array($z[0], $regions)) continue;
    if ($optgroup != $z[0]) {
        if ($optgroup !== '') $opt .= '</optgroup>';
        $optgroup = $z[0];
        $opt .= '<optgroup label="' . htmlentities($z[0]) . '">';
    }
    $opt .= '<option value="' . htmlentities($tz) . '" label="' . htmlentities(str_replace('_', ' ', $z[1])) . '">' . htmlentities(str_replace('_', ' ', $tz)) . '</option>';
}
if ($optgroup !== '') $opt .= '</optgroup>';

Dadurch wird eine Liste mit erstellt <optgroup> Elemente, sodass die Liste zumindest logisch nach Regionen unterteilt wird.

Benutzer-Avatar
Alix Axel

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:

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

Ich fand, dass dies eine ausgezeichnete Ressource ist: http://randomdrake.com/2008/08/06/time-zone-abbreviation-difficulties-with-php/

  • Hier gibt es einige interessante Techniken, die meiner Meinung nach verwendet werden könnten, um Städte für die TZD-Identifikatoren zu verketten. Ich hatte gehofft, jemand hätte ein nettes Wundermittel, das einfach funktionierte und DST-Variationen richtig behandelte. 🙂

    – Johannes Grün

    3. August 2011 um 7:05 Uhr

  • Genau wie ich. Mann, ich vermisse es, 24 einfache Zeitzonen auflisten zu können. 😀

    – Übereifrig

    3. August 2011 um 7:11 Uhr

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>

  • Hier gibt es einige interessante Techniken, die meiner Meinung nach verwendet werden könnten, um Städte für die TZD-Identifikatoren zu verketten. Ich hatte gehofft, jemand hätte ein nettes Wundermittel, das einfach funktionierte und DST-Variationen richtig behandelte. 🙂

    – Johannes Grün

    3. August 2011 um 7:05 Uhr

  • Genau wie ich. Mann, ich vermisse es, 24 einfache Zeitzonen auflisten zu können. 😀

    – Übereifrig

    3. August 2011 um 7:11 Uhr

Benutzer-Avatar
KyleWpppd

Mir fallen da ein paar Möglichkeiten ein.

Zuerst müssen Sie die gesamte Auswahlliste füllen und ein jQuery-Plugin wie verwenden Gewählt um die gesamte Liste zu füllen. Dies wäre wahrscheinlich scheiße, da Ihre Benutzer möglicherweise nicht einmal alle Zeitzonen kennen.

Die zweite Option besteht darin, JS zu verwenden, um die lokale Zeit des Browsers in einem versteckten Eingabefeld abzurufen, und dies mit der Kenntnis der IP des Benutzers zu kombinieren, um zu versuchen, den Standort des Benutzers transparent abzuleiten. Sie könnten sogar ihren vermuteten Standort auf einer Karte anzeigen und sie fragen, ob Sie die richtige Zeit haben.

Die dritte Option besteht darin, den Benutzer tatsächlich zu fragen, wo er lebt. Land und Postleitzahl sollten wahrscheinlich ausreichen, um die Zeitzone für die meisten Benutzer zu erhalten. In Grenzfällen könnten Sie den Benutzer um Klärung bitten.

Persönlich würde ich wahrscheinlich die erste und zweite Lösung kombinieren, um eine Auswahlliste zu erstellen, die die Regionen anzeigt, von denen Sie glauben, dass der Benutzer am nächsten ist.

  • Ich hatte eine angepasste Version des Auswahlmenüs der Jquery-Benutzeroberfläche verwendet, aber Chosen hat einige interessante Funktionen rund um die Mehrfachauswahl. Was die Ortszeit betrifft, könnte ich Ajax wohl manipulieren, um Client-Zeit zu erhalten – aber der Trick ist, dass Client-Zeit in meinem Fall nicht viel mit der Einrichtung des TZD zu tun hat. Angenommen, ich betreibe ein Fernsehnetzwerk und möchte das System so verwalten, dass ich Informationen für einen Sender in Indiana eingeben kann, obwohl ich mich möglicherweise in Kalifornien befinde. Hilft mir nicht zu wissen, dass die lokale TZD America/Los_Angeles ist.

    – Johannes Grün

    3. August 2011 um 7:09 Uhr


1282470cookie-checkBester Weg, um a zu füllen Feld mit Zeitzonen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy