Подтвердить что ты не робот

Часовой пояс в Java

Я разрешаю пользователям моего веб-приложения планировать события на основе часовых поясов по их выбору.

Я хочу предоставить пользователю полный список часовых поясов, а затем легко преобразовать его в объект java.util.TimeZone на сервере.

String[] TimeZone.getAvailableIds() - это то, что я мог бы использовать, но проблема в том, что он печатает около 585 идентификаторов часовых поясов.

Каков наилучший способ представить пользователю краткий список часовых поясов (например, окно Windows для настроек часового пояса) и легко преобразовать объект TimeZone на конец сервера, используя его идентификатор?

4b9b3361

Ответ 1

Список часовых поясов очень специфичен для приложений и локалей. Только вы знаете, какие зоны наиболее применимы для ваших пользователей. У нас фактически есть разные списки для разных регионов.

Вот наш список для американских пользователей для вашей справки,

    "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",

Ответ 2

Я только что написал небольшую утилиту Java, которая предоставляет список часовых поясов Windows (зоны в диалоговом окне выбора часового пояса в Windows) и связанные с ними объекты Java TimeZone. См. https://github.com/nfergu/Java-Time-Zone-List

Это основано на сопоставлениях CLDR в http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml

Ответ 3

Вы можете уменьшить список с помощью идентификаторов TZ, которые соответствуют только следующему регулярному выражению

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

Ответ 4

Не могли бы вы использовать список пользовательских идентификаторов часовых поясов, используя нотацию "GMT +/- Hours" (пропущенные минуты)?

(EDIT: с моим первым предложением переход на летнее время не является автоматическим. Для решения этой проблемы вы можете сначала попросить пользователя выбрать смещение по GMT, а затем показать (связанный) список идентификаторов часовых поясов для данного смещение с использованием:

public static String[] getAvailableIDs(int rawOffset) 

Таким образом, пользователь сможет выбрать свой часовой пояс в более коротком списке (лучше для пользователей) и получить выгоду от поведения с учетом летнего времени.)

Ответ 5

Если вам нужна гранулярность выбора именно того, как будет выглядеть список, я бы использовал лучший список из жесткого кодирования, который я смог найти (это хороший пример) и убедитесь, что он отображается и преобразовывается как можно точнее.

Просто имейте в виду, что каждый из этих 585 часовых поясов имеет семантическое значение (например, DST), и пользователи могут захотеть выбрать для них лучший часовой пояс. Хотя я согласен, что список может быть намного короче.

Ответ 6

Я сделал это для компании, которой я больше не владею, поэтому не могу предоставить код. JVM в Windows поставляется с файлом под названием tzmappings (смотрите C:\Program Files\Java\jre6\lib или аналогичным), который отображает временные зоны Windows в форме зоны Континент/Город на основе зоны zoneinfo.

К сожалению, текстовые имена в tzmappings ужасны, поэтому вам нужно сделать несколько минут табуляции. Откройте regedit и перейдите к HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. Под этим ключом для каждого часового пояса на машине; Windows 7 имеет около 90. Каждый ключ имеет значение Display, которое является желаемым текстовым именем; найдите ключ в tzmappings, чтобы найти идентификатор часового пояса Java для каждого из них.

Ответ 7

С этим многие, я бы не пытался перекопать их в список выбора. Я бы поместил их в список в отдельном модальном диалоговом окне (или всплывающем окне, если нужно), позвольте пользователю прокручивать и нажмите имя, которое они хотят. Они нажимают на ссылку в модальном диалоге и заполняют текстовое поле правильным кодом, и вы можете отправить его на свой сервер.

Еще лучше, попросите их щелкнуть по их местоположению на карте мира и использовать карту изображений для перевода этого местоположения в соответствующий часовой пояс.

Ответ 8

Чтобы дополнить ответ tbruyelle, я добавил еще несколько стран (например, в Канаду), удалил часть "/" фильтра и предоставил средство для сортировки списка.

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