Как получить Locale из его представления String в Java?
Есть ли аккуратный способ получить Locale экземпляр из его "программного имени", возвращенный методом Locale toString()
? Очевидным и уродливым решением будет синтаксический анализ String, а затем создание нового экземпляра Locale в соответствии с этим, но, возможно, для этого есть лучшее решение/готовое решение?
Необходимо, чтобы я хотел сохранить некоторые специфические для локали настройки в базе данных SQL, включая сами Locales, но было бы уродливо размещать в нем сериализованные объекты Locale. Я предпочел бы хранить их представления String, которые, как представляется, достаточно адекватны.
Ответы
Ответ 1
Смотрите Locale.getLanguage()
, Locale.getCountry()
... Сохраните эту комбинацию в базе данных вместо "programatic name"
...
Когда вы хотите построить Locale назад, используйте 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);
}
Ответ 2
Метод, который возвращает языковой стандарт из строки, существует в библиотеке commons-lang:
LocaleUtils.toLocale(localeAsString)
Ответ 3
Так как Java 7 существует factory метод Locale.forLanguageTag
и метод экземпляра Locale.toLanguageTag
, используя теги языка IETF.
Ответ 4
Java предоставляет множество вещей с правильной реализацией. Многое можно избежать:
Примеры:
-
Это возвращает ms_MY.
String key = ms-MY;
Locale locale = new Locale.Builder().setLanguageTag(key).build();
-
Это вернет en_US
String str = "en-US";
Locale locale = LocaleUtils.toLocale(str);
System.out.println(locale.toString());
-
Вы также можете использовать конструкторы locale.
// 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 изучить дополнительные методы.
Ответ 5
Этот ответ может быть немного запоздалым, но оказывается, что разбор строки не так уродлив, как предполагал 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 в языке, стране и вариантах, могут продолжать делать это (хотя это сильно обескуражено), хотя поле варианта будет содержать дополнительную информацию в он, если присутствует script или расширения.
Вместо этого используйте Locale.forLanguageTag и Locale.toLanguageTag, или, если необходимо, Locale.Builder.
Ответ 6
Старый вопрос с большим количеством ответов, но здесь больше решений:
Ответ 7
Вариант 1:
org.apache.commons.lang3.LocaleUtils.toLocale("en_US")
Вариант 2:
Locale.forLanguageTag("en-US")
Обратите внимание: Вариант 1 является "подчеркиванием" между языком и страной, а Вариант 2 - "тире".
Ответ 8
Для этого не существует статического метода valueOf
, что немного удивительно.
Один довольно уродливый, но простой способ состоял бы в том, чтобы перебирать Locale.getAvailableLocales()
, сравнивая их значения toString
с вашим значением.
Не очень приятно, но не требуется синтаксический анализ строк. Вы можете предварительно заполнить строку Map
от строк до локалей и посмотреть строку своей базы данных на этой карте.
Ответ 9
Вы можете использовать это на 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;
}
Ответ 10
Ну, вместо этого я бы сохранил строковое конкатенацию Locale.getISO3Language()
, getISO3Country()
и getVariant(), что позволило бы мне вызвать конструктор Locale(String language, String country, String variant)
.
действительно, полагаясь на displayLanguage, подразумевает использование языка языкового стандарта для его отображения, что делает его зависимым от языка, вопреки языковому коде iso.
В качестве примера, ключ en locale будет сохраняться как
en_EN
en_US
и т.д.
Ответ 11
Потому что я только что реализовал его:
В Groovy
/Grails
это будет:
def locale = Locale.getAvailableLocales().find { availableLocale ->
return availableLocale.toString().equals(searchedLocale)
}