如何从Java中的String表示中获取Locale?

时间:2010-03-26 09:47:20

标签: java locale

是否有一种巧妙的方法可以从Locale的toString()方法返回的“程序化名称”中获取Locale实例?一个明显而丑陋的解决方案是解析String然后根据它构建一个新的Locale实例,但也许有更好的方法/就绪解决方案呢?

我需要在SQL数据库中存储一些特定于语言环境的设置,包括Locales本身,但是将序列化的Locale对象放在那里会很难看。我宁愿存储他们的字符串表示,这些表示似乎非常详细。

12 个答案:

答案 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)

  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)
    
  4. 请检查此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");

Documentation

  

将给定的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)
}