Как получить Locale из его строкового представления в Java? - PullRequest
95 голосов
/ 26 марта 2010

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

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

Ответы [ 12 ]

117 голосов
/ 25 января 2011

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

56 голосов
/ 17 октября 2012

Начиная с Java 7, существует фабричный метод Locale.forLanguageTag и метод экземпляра Locale.toLanguageTag с использованием языковых тегов IETF .

32 голосов
/ 26 марта 2010

См. 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);
}
27 голосов
/ 08 июля 2015
  1. Java обеспечивает множество вещей при правильной реализации, поэтому можно избежать больших сложностей. Это возвращает ms_MY .

    String key = "ms-MY";
    Locale locale = new Locale.Builder().setLanguageTag(key).build();
    
  2. Apache Commons имеет LocaleUtils, чтобы помочь разобрать строковое представление. Это вернет 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 , чтобы узнать больше методов.

12 голосов
/ 06 марта 2013

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

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) со всеми примерами, приведенными в документации Locale.toString (): "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "zh_CN_ # Hans" , "zh_TW_ # Hant-x-java" и "th_TH_TH_ # u-nu-thai".

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

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

Вместо этого используйте Locale.forLanguageTag и Locale.toLanguageTag или, если необходимо, Locale.Builder.

11 голосов
/ 16 мая 2017

Вариант 1:

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

Вариант 2:

Locale.forLanguageTag("en-US")

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

7 голосов
/ 11 декабря 2010

Старый вопрос с множеством ответов, но есть и другие решения:

5 голосов
/ 15 августа 2018

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

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

Документация

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

3 голосов
/ 25 августа 2014

Вы можете использовать это на 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;
}
3 голосов
/ 26 марта 2010

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

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

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

...