是否有一种巧妙的方法可以从Locale 方法返回的“程序名称” 中获取Locale实例toString()
?一个明显且丑陋的解决方案是解析String,然后根据该字符串构造一个新的Locale实例,但是也许有一种更好的方法/现成的解决方案?
我需要将一些特定于语言环境的设置(包括语言环境本身)存储在SQL数据库中,但是将序列化的语言环境对象放在那里是很难的。我宁愿存储它们的String表示形式,在细节上似乎也足够了。
是否有一种巧妙的方法可以从Locale 方法返回的“程序名称” 中获取Locale实例toString()
?一个明显且丑陋的解决方案是解析String,然后根据该字符串构造一个新的Locale实例,但是也许有一种更好的方法/现成的解决方案?
我需要将一些特定于语言环境的设置(包括语言环境本身)存储在SQL数据库中,但是将序列化的语言环境对象放在那里是很难的。我宁愿存储它们的String表示形式,在细节上似乎也足够了。
Answers:
见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)
-
处理的是IETF BCP 47标签,则在语言环境部分之间使用连字符,如果您使用的是Java 7,则可以使用Locale.forLanguageTag
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以探索更多方法。
这个答案可能有点晚了,但是事实证明,解析字符串并不像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”。
重要更新:根据文档,不建议在Java 7+中使用它:
特别是,将toString的输出解析为语言,国家和变量字段的客户可以继续这样做(尽管强烈建议不要这样做),尽管如果存在脚本或扩展名,则变量字段中将包含其他信息。
请改用Locale.forLanguageTag和Locale.toLanguageTag,或者如果需要,请使用Locale.Builder。
Locale.forLanguageTag
仅适用于在IETF的BCP 47所示,用连字符(编码语言标签-
),而不是下划线(_
)在返回Locale
的toString
方法
Locale
s不应以其toString
形式存储,而应以其形式存储,这种形式toLanguageTag
可以Locale
更轻松,更准确地转换回去。
您可以在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;
}