Как получить Locale из его строкового представления в Java?
есть ли аккуратный способ получить язык экземпляр из его "программного имени", возвращаемогоtoString()
способ? Очевидным и уродливым решением будет разбор строки, а затем построение нового экземпляра Locale в соответствии с этим, но, возможно, есть лучший способ / готовое решение для этого?
необходимость в том, что я хочу сохранить некоторые параметры локали в базе данных SQL, включая сами локали, но было бы некрасиво помещать сериализованные Объекты локали там. Я бы предпочел сохранить их строковые представления, которые кажутся вполне адекватными в деталях.
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);
}
метод, возвращающий локаль из строки, существует в библиотеке commons-lang:
LocaleUtils.toLocale(localeAsString)
С Java 7 есть заводской метод Locale.forLanguageTag
и метод экземпляра Locale.toLanguageTag
С помощью языковые теги IETF.
Java предоставляет много вещей с правильной реализацией много сложности можно избежать:
примеры:
-
возвращает ms_MY.
String key = ms-MY; Locale locale = new Locale.Builder().setLanguageTag(key).build();
-
вернет язык
String str = "en-US"; Locale locale = LocaleUtils.toLocale(str); System.out.println(locale.toString());
-
вы также можете использовать конструкторы язык.
// 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 (): "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 в поля языка, страны и варианта, могут продолжать делать это (хотя это приветствуется), хотя поле 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
значения со значением.
не очень хорошо, но не требуется синтаксический анализ строк. Вы можете предварительно заполнить 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 подразумевает использование языка locale для его отображения, что делает его зависимым от языка, в отличие от кода языка iso.
в качестве примера ключ локали en будет храниться как
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");
проанализируйте данное строковое представление в Locale