是否有一种巧妙的方法可以从Locale的toString()
方法返回的“程序化名称”中获取Locale实例?一个明显而丑陋的解决方案是解析String然后根据它构建一个新的Locale实例,但也许有更好的方法/就绪解决方案呢?
我需要在SQL数据库中存储一些特定于语言环境的设置,包括Locales本身,但是将序列化的Locale对象放在那里会很难看。我宁愿存储他们的字符串表示,这些表示似乎非常详细。
答案 0 :(得分:117)
从commons-lang库中存在从字符串返回语言环境的方法:
LocaleUtils.toLocale(localeAsString)
答案 1 :(得分:55)
从Java 7开始,工厂方法Locale.forLanguageTag
和实例方法Locale.toLanguageTag
使用IETF language tags。
答案 2 :(得分:32)
请参阅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);
}
答案 3 :(得分:27)
Java提供了很多适当的实现,可以避免很多复杂性。这将返回 ms_MY 。
String key = "ms-MY";
Locale locale = new Locale.Builder().setLanguageTag(key).build();
Apache Commons有LocaleUtils
来帮助解析字符串表示。这将返回 en_US
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以探索更多方法。
答案 4 :(得分:12)
这个答案可能有点晚了,但事实证明解析字符串并不像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]);
}
我使用Locale.toString()文档中给出的所有示例对此进行了测试(在Java 7上):“en”,“de_DE”,“_ GB”,“en_US_WIN”,“de__POSIX”,“zh_CN_#Hans” ,“zh_TW_#Hant-x-java”和“th_TH_TH_#u-nu-thai”。
重要更新:根据documentation,建议不要在Java 7+中使用:
特别是,将toString的输出解析为语言,国家和变体字段的客户可以继续这样做(尽管强烈反对),尽管变体字段将包含其他信息。它是否存在脚本或扩展名。
请改用Locale.forLanguageTag和Locale.toLanguageTag,或者如果必须,请使用Locale.Builder。
答案 5 :(得分:11)
选项1:
org.apache.commons.lang3.LocaleUtils.toLocale("en_US")
选项2:
Locale.forLanguageTag("en-US")
请注意选项1 是语言和国家/地区之间的“下划线”,选项2 是“破折号”。
答案 6 :(得分:7)
老问题有很多答案,但这里有更多解决方案:
答案 7 :(得分:4)
如果您在项目中使用Spring框架,则还可以使用:
org.springframework.util.StringUtils.parseLocaleString("en_US");
将给定的String表示形式解析为语言环境
答案 8 :(得分:3)
似乎没有静态valueOf
方法,这有点令人惊讶。
一种相当丑陋但又简单的方法是迭代Locale.getAvailableLocales()
,将toString
值与您的值进行比较。
不是很好,但不需要字符串解析。您可以预先填充Map
字符串到语言环境,并在该映射中查找数据库字符串。
答案 9 :(得分:3)
您可以在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 :(得分:1)
好吧,我会存储Locale.getISO3Language()
,getISO3Country()
和getVariant()的字符串连接作为键,这将允许我后来调用Locale(String language, String country, String variant)
构造函数。
实际上,依赖于displayLanguage意味着使用locale语言来显示它,这使得它依赖于语言环境,与iso语言代码相反。
例如,en locale键可以存储为
en_EN
en_US
依旧......
答案 11 :(得分:1)
因为我刚刚实施了它:
在Groovy
/ Grails
中,它将是:
def locale = Locale.getAvailableLocales().find { availableLocale ->
return availableLocale.toString().equals(searchedLocale)
}