web-dev-qa-db-fra.com

TimeZones dans Java

J'autorise les utilisateurs de mon application Web à planifier des événements en fonction des fuseaux horaires de leur choix.

Je veux présenter une bonne liste de fuseaux horaires à l'utilisateur final, puis la convertir facilement en objet Java.util.TimeZone À l'extrémité du serveur.

String[] TimeZone.getAvailableIds() est quelque chose que je pourrais utiliser, mais le problème est qu'il imprime environ 585 identifiants de fuseau horaire.

Quelle est la meilleure façon de présenter à l'utilisateur une brève liste de fuseaux horaires (comme le ferait une boîte Windows pour les paramètres de fuseau horaire) et de la convertir facilement en objet TimeZone à l'extrémité du serveur en utilisant son identifiant?

26
Vish

La liste des fuseaux horaires est très spécifique à l'application et aux paramètres régionaux. Vous seul savez quelles zones sont les plus applicables à vos utilisateurs. Nous avons en fait différentes listes pour différentes régions.

Voici notre liste pour les utilisateurs américains pour votre référence,

    "Pacific/Midway",
    "US/Hawaii",
    "US/Alaska",
    "US/Pacific",
    "America/Tijuana",
    "US/Arizona",
    "America/Chihuahua",
    "US/Mountain",
    "America/Guatemala",
    "US/Central",
    "America/Mexico_City",
    "Canada/Saskatchewan",
    "America/Bogota",
    "US/Eastern",
    "US/East-Indiana",
    "Canada/Eastern",
    "America/Caracas",
    "America/Manaus",
    "America/Santiago",
    "Canada/Newfoundland",
    "Brazil/East",
    "America/Buenos_Aires",
    "America/Godthab",
    "America/Montevideo",
    "Atlantic/South_Georgia",
    "Atlantic/Azores",
    "Atlantic/Cape_Verde",
    "Africa/Casablanca",
    "Europe/London",
    "Europe/Berlin",
    "Europe/Belgrade",
    "Europe/Brussels",
    "Europe/Warsaw",
    "Africa/Algiers",
    "Asia/Amman",
    "Europe/Athens",
    "Asia/Beirut",
    "Africa/Cairo",
    "Africa/Harare",
    "Europe/Helsinki",
    "Asia/Jerusalem",
    "Europe/Minsk",
    "Africa/Windhoek",
    "Asia/Baghdad",
    "Asia/Kuwait",
    "Europe/Moscow",
    "Africa/Nairobi",
    "Asia/Tbilisi",
    "Asia/Tehran",
    "Asia/Muscat",
    "Asia/Baku",
    "Asia/Yerevan",
    "Asia/Kabul",
    "Asia/Yekaterinburg",
    "Asia/Karachi",
    "Asia/Calcutta",
    "Asia/Colombo",
    "Asia/Katmandu",
    "Asia/Novosibirsk",
    "Asia/Dhaka",
    "Asia/Rangoon",
    "Asia/Bangkok",
    "Asia/Krasnoyarsk",
    "Asia/Hong_Kong",
    "Asia/Irkutsk",
    "Asia/Kuala_Lumpur",
    "Australia/Perth",
    "Asia/Taipei",
    "Asia/Tokyo",
    "Asia/Seoul",
    "Asia/Yakutsk",
    "Australia/Adelaide",
    "Australia/Darwin",
    "Australia/Brisbane",
    "Australia/Sydney",
    "Pacific/Guam",
    "Australia/Hobart",
    "Asia/Vladivostok",
    "Asia/Magadan",
    "Pacific/Auckland",
    "Pacific/Fiji",
    "Pacific/Tongatapu",
24
ZZ Coder

Je viens d'écrire un petit utilitaire Java qui fournit une liste des fuseaux horaires Windows (les zones de la boîte de dialogue de sélection de fuseau horaire dans Windows), et leurs Java objets TimeZone associés. Voir https://github.com/nfergu/Java-Time-Zone-List

Ceci est basé sur les mappages CLDR à http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml

11
Neil

Vous pouvez réduire la liste avec des ID TZ qui correspondent uniquement à l'expression rationnelle suivante

^(Africa|America|Asia|Atlantic|Australia|Europe|Indian|Pacific)/.*
4
tbruyelle

Juste pour compléter la réponse de tbruyelle, j'ai ajouté quelques autres pays (par exemple le Canada), supprimé la partie "/" du filtre et fourni un moyen de trier la liste.

public static void main(String[] args)
{
    List<String> simplifiedTimezoneList = getTimezoneIdList();

    for (String tz : simplifiedTimezoneList)
        System.out.println(tz);
}

public static List<String> getTimezoneIdList()
{
    String[] temp = TimeZone.getAvailableIDs();
    List<String> timezoneList = new ArrayList<String>();
    List<String> simplifiedTimezoneList = new ArrayList<String>();
    for (String tz : temp)
    {
        timezoneList.add(tz);
    }
    Collections.sort(timezoneList);
    String filterList = "Canada|Mexico|Chile|Cuba|Brazil|Japan|Turkey|Mideast|Africa|America|Asia|Atlantic|Australia|Europe|Indian|Pacific";
    Pattern p = Pattern.compile("^(" + filterList + ").*");
    for (String tz : timezoneList)
    {
        Matcher m = p.matcher(tz);
        if (m.find())
        {
            simplifiedTimezoneList.add(tz);
        }
    }
    return simplifiedTimezoneList;
}
3
Bryan

J'ai fait cela pour une entreprise que je ne possède plus, donc je ne peux pas fournir de code. La JVM sous Windows est livrée avec un fichier appelé tzmappings (regardez dans C:\Program Files\Java\jre6\lib ou similaire) qui mappe les fuseaux horaires Windows au formulaire Continent/City basé sur zoneinfo de Java.

Malheureusement, les noms textuels dans tzmappings sont terribles, vous devez donc faire quelques minutes de tabulation. Ouvrez regedit et accédez à HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. En dessous se trouve une clé pour chaque fuseau horaire sur la machine; Windows 7 en a environ 90. Chaque clé a une valeur appelée Display qui est le nom textuel que vous souhaitez; recherchez la clé elle-même dans tzmappings pour trouver l'identifiant de fuseau horaire Java pour chacun).

0
Andrew Duffy

Ne pourriez-vous pas utiliser une liste d'ID de fuseau horaire personnalisés en utilisant la notation "GMT +/- Heures" (en ignorant les minutes)?

(MODIFIER: avec ma première suggestion, la transition de l'heure d'été n'est pas automatique. Pour résoudre ce problème, vous pouvez d'abord demander à l'utilisateur de sélectionner un décalage GMT, puis afficher une liste (liée) d'ID de fuseau horaire pour le décalage donné en utilisant:

public static String[] getAvailableIDs(int rawOffset) 

De cette façon, l'utilisateur pourrait choisir son fuseau horaire dans une liste plus courte (meilleure pour l'expérience utilisateur) et bénéficier d'un comportement d'heure d'été.)

0
Pascal Thivent

Si vous avez besoin de la granularité de choisir exactement à quoi ressemblerait la liste, j'utiliserais la meilleure liste codée en dur que je pourrais trouver ( c'est un bon exemple ) et je veillerais à ce qu'elle soit affichée et convertie aussi précisément que possible.

N'oubliez pas que chacun de ces 585 fuseaux horaires a une signification sémantique (comme DST par exemple) et que les utilisateurs peuvent vouloir choisir le meilleur fuseau horaire pour eux. Bien que je convienne que cette liste peut être beaucoup plus courte.

0
Yuval Adam

Avec autant, je n'essaierais pas de les chausse-pied dans une liste de sélection ... Je les mettrais sur une liste dans une boîte de dialogue modale distincte (ou une popup, si vous le devez), laissez l'utilisateur faire défiler la liste et cliquez sur le nom qu'ils veulent. Ils cliqueraient sur un lien dans la boîte de dialogue modale, et il remplirait un champ de texte avec le code correct, et vous pourriez ensuite le soumettre à votre serveur.

Mieux encore, demandez-leur de cliquer sur leur emplacement sur une carte du monde et d'utiliser une carte image pour traduire cet emplacement dans le fuseau horaire approprié.

0
Spike Williams