Как получить Locale из его строкового представления в Java?


есть ли аккуратный способ получить Locale экземпляр из его "программного имени", возвращенного Locale toString() способ? Очевидным и уродливым решением было бы разбор строки, а затем построение нового экземпляра Locale в соответствии с этим, но, возможно, есть лучший способ / готовое решение для этого?

необходимость в том, что я хочу сохранить некоторые настройки локали в базе данных SQL, включая сами локали, но было бы некрасиво помещать сериализованные Локали объектов нет. Я бы предпочел хранить их строковые представления, которые кажутся вполне адекватными подробно.

12 86

12 ответов:

посмотреть Locale.getLanguage(),Locale.getCountry()... Сохраните эту комбинацию в базе данных вместо "programatic name"...
Если вы хотите построить Локаль обратно, используйте public Locale(String language, String country)

вот пример кода :)

// May contain simple syntax error, I don't have java right now to test..
// but this is a bigger picture for your algo...
public String localeToString(Locale l) {
    return l.getLanguage() + "," + l.getCountry();
}

public Locale stringToLocale(String s) {
    StringTokenizer tempStringTokenizer = new StringTokenizer(s,",");
    if(tempStringTokenizer.hasMoreTokens())
    String l = tempStringTokenizer.nextElement();
    if(tempStringTokenizer.hasMoreTokens())
    String c = tempStringTokenizer.nextElement();
    return new Locale(l,c);
}

метод, который возвращает locale из строки существует в библиотеке commons-lang: LocaleUtils.toLocale(localeAsString)

Так как Java 7 есть заводской метод Locale.forLanguageTag и метод экземпляра Locale.toLanguageTag С помощью языковые теги IETF.

Java предоставляет много вещей с правильной реализацией много сложности можно избежать:

примеры:

  1. возвращает ms_MY.

    String key = ms-MY;
    Locale locale = new Locale.Builder().setLanguageTag(key).build();
    
  2. вернет en_US

    String str = "en-US";
    Locale locale =  LocaleUtils.toLocale(str);
    System.out.println(locale.toString());
    
  3. вы также можете использовать конструкторы язык.

    // Construct a locale from a language code.(eg: en)
    new Locale(String language)
    // Construct a locale from language and country.(eg: en and US)
    new Locale(String language, String country)
    // Construct a locale from language, country and variant.
    new Locale(String language, String country, String variant)
    

пожалуйста, проверьте это LocaleUtils и Locale to узнать больше методов.

этот ответ может быть немного запоздалым, но оказывается, что разбор строки не так уродлив, как предполагал ОП. Я нашел его довольно простым и лаконичным:

public static Locale fromString(String locale) {
    String parts[] = locale.split("_", -1);
    if (parts.length == 1) return new Locale(parts[0]);
    else if (parts.length == 2
            || (parts.length == 3 && parts[2].startsWith("#")))
        return new Locale(parts[0], parts[1]);
    else return new Locale(parts[0], parts[1], parts[2]);
}

Я проверил это (на Java 7) со всеми примерами, приведенными в локали.метод toString() документация: "Ан", "сайт", "_GB", "en_US_WIN", "Де__в POSIX", "zh_CN_#Ганс", "zh_TW_#Хант-х-Ява" и "th_TH_TH_#у-ню-тай".

ВАЖНОЕ ОБНОВЛЕНИЕ: это не рекомендуется для использования в Java 7+ по к документация:

в частности, клиенты, которые анализируют выходные данные toString в поля language, country и variant, могут продолжать это делать (хотя это приветствуется), хотя поле вариант будет иметь дополнительную информацию в нем, если сценарий или расширения присутствуют.

Использовать Локаль.forLanguageTag и Locale.toLanguageTag вместо этого, или если вы должны, Locale.Строитель.

Вариант 1 :

org.apache.commons.lang3.LocaleUtils.toLocale("en_US")

Вариант 2 :

Locale.forLanguageTag("en-US")

обратите внимание 1 это "подчеркивание" между языком и страной , и 2 "дефис".

старый вопрос с большим количеством ответов, но вот еще решения:

там, кажется, нет статического valueOf способ для этого, что немного удивительно.

один довольно уродливый, но простой, способ, было бы перебирать Locale.getAvailableLocales(), сравнивая их toString значения со значением.

не очень приятно, но не требуется разбор строк. Вы можете предварительно заполнить a Map строк в локали, и посмотрите на строку базы данных в этой карте.

вы можете использовать это на Android. Отлично работает для меня.

private static final Pattern localeMatcher = Pattern.compile
        ("^([^_]*)(_([^_]*)(_#(.*))?)?$");

public static Locale parseLocale(String value) {
    Matcher matcher = localeMatcher.matcher(value.replace('-', '_'));
    return matcher.find()
            ? TextUtils.isEmpty(matcher.group(5))
                ? TextUtils.isEmpty(matcher.group(3))
                    ? TextUtils.isEmpty(matcher.group(1))
                        ? null
                        : new Locale(matcher.group(1))
                    : new Locale(matcher.group(1), matcher.group(3))
                : new Locale(matcher.group(1), matcher.group(3),
                             matcher.group(5))
            : null;
}

Ну, я бы сохранил вместо этого конкатенацию строк Locale.getISO3Language(),getISO3Country() и getVariant () как ключ, который позволит мне последний вызов Locale(String language, String country, String variant) конструктор.

в самом деле, опираясь на displayLanguage подразумевает использование языковый локали для отображения, которые делают его иждивении язык, вопреки стандарту ISO код языка.

в качестве примера, основные локаль ванной будет хранимые как

en_EN
en_US

и так далее ...

потому что я только что реализовал его:

на Groovy/Grails что будет:

def locale = Locale.getAvailableLocales().find { availableLocale ->
      return availableLocale.toString().equals(searchedLocale)
}

Если вы используете Spring framework в своем проекте, вы также можете использовать:

org.springframework.util.StringUtils.parseLocaleString("en_US");

документация:

разбор данного строкового представления в Локаль