Javaの文字列表現からロケールを取得する方法は?


109

Localeのメソッドによって返される「プログラム名」からLocaleインスタンスを取得する適切な方法はありますtoString()か?明白で醜い解決策は、文字列を解析し、それに従って新しいLocaleインスタンスを作成することですが、より良い方法/準備ができている解決策があるでしょうか?

必要なのは、ロケール自体を含むいくつかのロケール固有の設定をSQLデータベースに保存することですが、シリアル化されたLocaleオブジェクトをそこに配置するのは醜いでしょう。私はむしろそれらの文字列表現を保存したいと思っています。

回答:


34

参照してください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
これもコンパイルされません。
エイドリアン

1
@rajなぜtokenizerを使用するのか、Javaが準備ができているメソッドを提供する場合は?例:toLocale(String str)。回答の例をご覧ください
VdeX 2015

9
Locale.forLanguageTag(String)を使用する必要があります
Rian

126

文字列からロケールを返すメソッドはcommons-langライブラリに存在します: LocaleUtils.toLocale(localeAsString)


2
LocaleUtils.toLocaleは「zh-Hans」、「pt-PT」などの文字列をサポートしていません
Hans van Dodewaard

10
-ロケールパーツの間にハイフンがある場合、IETF BCP 47タグを処理しますLocale.forLanguageTag
。Java7を

59

Java 7以降、IETF言語タグを使用するファクトリメソッドLocale.forLanguageTagとインスタンスメソッドがあります。Locale.toLanguageTag


8
Locale.forLanguageTagIETFロケール文字列(つまりen-US)で機能し、ISOロケール文字列(つまりen_US)では機能しないことを強調したいだけです
Fabian

34
  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)

このLocaleUtilsとこのLocaleを確認して、他のメソッドを調べてください。


1
LocaleUtils.toLocale(localeStringRepresentation)は仕事をきちんと行います。また、このメソッドの実装を見ると、非常に包括的です!
2017

15

オプション1 :

org.apache.commons.lang3.LocaleUtils.toLocale("en_US")

オプション2:

Locale.forLanguageTag("en-US")

オプション1は言語と国の間の「アンダースコア」であり、オプション2は「ダッシュ」であることに注意してください。


呼び出しにはAPIレベル21(現在の最小値は17)が必要です:java.util.Locale#forLanguageTag
Vlad

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]);
}

私はこれを(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の出力を言語、国、バリアントフィールドに解析するクライアントは、これを続行できます(ただし、これは強くお勧めしません)。ただし、スクリプトまたは拡張機能が存在する場合、バリアントフィールドには追加情報があります。

代わりにLocale.forLanguageTagとLocale.toLanguageTagを使用してください。必要であればLocale.Builderを使用してください。


5
ジャワ7は、Locale.forLanguageTagハイフン(と、IETFのBCP 47に示すように符号化された言語のタグにのみ適用される-)ではなく下線(_のリターンのように)LocaletoString方法
ハイメHablutzelを

1
あなたが正しい。既存のロケール表現をBCP47形式に変換する方法がまだ必要です。私の意図は、今後、LocalesをそのtoString形式で保存するのではなくtoLanguageTagLocaleより簡単かつ正確に変換できる形式で保存することを提案することでした。
アンディ2013年

この方法には、インデックスが範囲外になる可能性のあるエッジケースが多数あるのではないでしょうか。
user2524908

@ user2524908:要素にアクセスする前に常に配列の長さをテストしているので、私はそうは思わない。ソリューションには、適切に機能しないが「範囲外のインデックス」ではない多くのエッジケースがある可能性があります
MestreLion

9

プロジェクトでSpringフレームワークを使用している場合は、以下も使用できます。

org.springframework.util.StringUtils.parseLocaleString("en_US");

ドキュメンテーション

指定された文字列表現をロケールに解析します


これに関するドキュメントは、それが具体的には逆であると言いますLocale#toString()-完璧です!:)
ジョクル


3

これには静的valueOfメソッドがないようで、少し意外です。

どちらかと言えば醜いですが、単純な方法は、を反復してLocale.getAvailableLocales()、それらのtoString値を自分の値と比較することです。

あまり良くありませんが、文字列の解析は必要ありません。Map文字列をロケールに事前入力して、そのマップでデータベース文字列を検索できます。


ああ、反復はかなり合理的な解決策かもしれません。確かに、ロケールに静的メソッドがないのは驚くべきことです。
Joonas Pulakka

事前定義されたLocaleインスタンスは、有効なロケールのみの非常に小さいサブセットを表します。それは決して完全ではありません。
BetaRide

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;
}

1

ええと、代わりにの文字列連結を保存し、キーとしてgetVariant()を格納します。これによりLocale.getISO3Language()getISO3Country()後でLocale(String language, String country, String variant)コンストラクタを呼び出すことができます。

実際、displayLanguageに依存することは、ロケールの言語を使用して表示することを意味し、iso言語コードとは異なり、ロケールに依存するようになります。

例として、enロケールキーは次のように保存できます。

en_EN
en_US

等々 ...


1

私はそれを実装したばかりなので:

Groovy/ Grailsそれは次のようになります。

def locale = Locale.getAvailableLocales().find { availableLocale ->
      return availableLocale.toString().equals(searchedLocale)
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.