モジュール java.base
パッケージ java.util

クラスLocale

java.lang.Object
java.util.Locale
すべての実装されたインタフェース:
Serializable, Cloneable

public final class Locale extends Object implements Cloneable, Serializable
Localeオブジェクトは、地理的、政治的、または文化的に特定の地域を表します。 ある操作でLocaleを必要とするタスクがある場合、その操作をロケールに依存する操作といいます。この場合、情報はLocaleによりユーザーに合わせて調整されます。 たとえば、数値を表示することは、ロケールに依存する操作です。数値は、ユーザーの母国、地域、文化の習慣や慣習に従ってフォーマットする必要があります。

Localeクラスは、RFC 4647「Matching of Language Tags」およびRFC 5646「Tags for Identifying Languages」で構成されるIETF BCP 47を実装し、ロケール・データ交換用のLDML (UTS#35「Unicode Locale Data Markup Language」) BCP 47互換拡張をサポートします。

Localeは、論理的には下記のフィールドで構成されます。

language
ISO 639 alpha-2またはalpha-3言語コード、または最大8文字の英字の登録済み言語サブタグ(将来の拡張のため)。 言語にalpha-2コードとalpha-3コードの両方がある場合は、alpha-2コードを使用する必要があります。 有効な言語コードの完全なリストはIANA言語サブタグ・レジストリで参照できます(「Type: language」を検索)。 言語フィールドの大文字と小文字は区別されませんが、Localeでは常に小文字に正規化されます。
整形式の言語の値は、[a-zA-Z]{2,8}という形式です。 これは、extlangを除外するため、完全なBCP47言語本番ではありません。 これらは最新の3文字の言語コードで置き換えられるため、必要ありません。
例: "en" (英語)、"ja" (日本語)、"kok" (コンカニ語)
script
ISO 15924 alpha-4スクリプト・コード。 有効なスクリプト・コードの完全なリストはIANA言語サブタグ・レジストリで参照できます(「Type: script」を検索)。 スクリプト・フィールドの大文字と小文字は区別されませんが、Localeでは常にタイトル・ケース(最初の文字は大文字、残りの文字は小文字)に正規化されます。
整形式のスクリプトの値は、[a-zA-Z]{4}という形式です。
例: "Latn" (ラテン)、"Cyrl" (キリル)
country (region)
ISO 3166 alpha-2の国コードまたはUN M.49 numeric-3の地域コード。 有効な国コードおよび地域コードの完全なリストはIANA言語サブタグ・レジストリで参照できます(「Type: region」を検索)。 国(地域)フィールドの大文字と小文字は区別されませんが、Localeでは常に大文字に正規化されます。
整形式の国/地域の値は、[a-zA-Z]{2}|[0-9]{3}という形式です。
例: "US" (米国)、"FR" (フランス)、"029" (カリブ)
variant
Localeのバリエーションを示すために使用される任意の値。 それぞれ独自のセマンティックスを示すバリアント値が2つ以上存在する場合、これらの値は重要度によって順序付けるべきで、もっとも重要なものから始めて、下線(「_」)で区切るようにします。 バリアント・フィールドの大文字と小文字は区別されません。
ノート: IETF BCP 47では、バリアント・サブタグに構文上の制限が規定されています。 また、BCP 47のサブタグは、言語、スクリプト、および地域のサブタグのどの組み合わせでも表されない、言語またはその方言を定義する追加のバリエーションを指定するためだけに使用されます。 有効なバリアント・コードの完全なリストはIANA言語サブタグ・レジストリで参照できます(「Type: variant」を検索)。

ただし、Localeのバリアント・フィールドは従来、言語のバリエーションだけでなく任意の種類のバリエーションに使用されてきました。 たとえば、Java SE Runtime Environmentで使用可能なサポートされているバリアントには、カレンダの種類や数値のスクリプトなど、別の文化的動作を示すものがあります。 BCP 47では、言語を識別するものではないこのような情報は、拡張サブタグまたは私用サブタグでサポートされます。

整形式のバリアント値はSUBTAG (('_'|'-') SUBTAG)*形式で、SUBTAG = [0-9][0-9a-zA-Z]{3} | [0-9a-zA-Z]{5,8}です。 (ノート:BCP 47は区切り文字としてハイフン(「-」)だけを使用するのに対し、この方が緩やかです。)
例: "polyton" (ギリシャ語Polytonic)、"POSIX"
extensions
言語の識別とは別の拡張を示す、単一文字キーから文字列値へのマップ。 Localeの拡張は、BCP 47の拡張サブタグおよび私用サブタグのセマンティックスと構文を実装します。 拡張の大文字と小文字は区別されませんが、Localeではすべての拡張キーと値が小文字に正規化されます。 拡張に空の値を指定することはできません。
整形式のキーは、[0-9a-zA-Z]のうちの単一文字です。 整形式の値は、SUBTAG ('-' SUBTAG)*という形式です。ここで、キー「x」についてはSUBTAG =[0-9a-zA-Z]{1,8}、ほかのキーについてはSUBTAG =[0-9a-zA-Z]{2,8}です(つまり、「x」では単一文字のサブタグが許可されます)。
例: key="u"/value="ca-japanese" (和暦)、key="x"/value="java-1-7"
ノート: BCP 47では、フィールド値がIANA言語サブタグ・レジストリに登録されている必要がありますが、Localeクラスでは検証機能は提供されていません。 Builderは、個々のフィールドが構文要件を満たしている(整形式である)かどうかだけを確認し、値自体の検証は行いません。 詳細は、Locale.Builderを参照してください。

Unicodeロケール/言語拡張

UTS#35「Unicode Locale Data Markup Language」では、ロケールに関連付けられているデフォルト動作をオーバーライドまたは変更するための、オプションの属性とキーワードが定義されています。 キーワードは、キーとタイプのペアで表されます。 たとえば、「nu-thai」は、数値のフォーマット(キー:「nu」)にタイのローカル数字(値:「thai」)を使用することを指定します。

キーワードは、拡張キー「u」(UNICODE_LOCALE_EXTENSION)を使用してBCP 47拡張値にマップされます。 前述の例の"nu-thai"は、拡張子"u-nu-thai"になります。

したがって、LocaleオブジェクトにUnicodeロケール属性およびキーワードが含まれている場合、getExtension(UNICODE_LOCALE_EXTENSION)はこの情報を表すStringを返します("nu-thai"など)。 LocaleクラスではgetUnicodeLocaleAttributes()getUnicodeLocaleKeys()、およびgetUnicodeLocaleType(java.lang.String)も提供されているため、Unicodeロケール属性およびキーとタイプのペアに直接アクセスできます。 文字列で表現されたUnicodeロケール拡張では、属性がアルファベット順に一覧表示され、続いてキーとタイプがキーのアルファベット順に一覧表示されます(キーのタイプを構成するサブタグの順序は、タイプが定義されたときに固定されます)。

整形式のロケール・キーは、[0-9a-zA-Z]{2}という形式です。 整形式のロケール・タイプは、""|[0-9a-zA-Z]{3,8} ('-' [0-9a-zA-Z]{3,8})*という形式です(空、または3-8文字の英数字から成る一連のサブタグ)。 整形式のロケール属性は、[0-9a-zA-Z]{3,8}という形式です(ロケール・タイプ・サブタグと同じ形式の単一のサブタグ)。

Unicodeロケール拡張は、ロケールに依存するサービスのオプションの動作を指定します。 LDML仕様ではさまざまなキーと値が定義されていますが、Java Runtime Environmentにおける実際のロケール依存サービスの実装では、特定のUnicodeロケール属性やキーとタイプのペアがサポートされていない場合があります。

ロケールの取得

Localeオブジェクトを取得するには、いくつかの方法があります。

Builder

Locale.Builderを使用して、BCP 47構文に適合するLocaleオブジェクトを構築できます。

ファクトリ・メソッド

メソッドforLanguageTag(java.lang.String)は、整形式のBCP 47言語タグのLocaleオブジェクトを取得します。 メソッドof(String, String, String)とそのオーバーロードは、前述の指定されたlanguagecountryまたはvariant、あるいはその両方からLocaleオブジェクトを取得します。

ロケール定数

Localeクラスには、一般的に使用されるロケールのLocaleオブジェクトを取得するために使用できる便利な定数が多数用意されています。 たとえば、Locale.USは米国のLocaleオブジェクトです。

デフォルトのロケール

Localeが引数として明示的に指定されていない場合(DateFormat.getInstance()など)、ロケール依存のメソッドにはデフォルトのロケールが指定されます。 デフォルトのロケールは、Javaランタイムの起動時に決定され、次の3つのフェーズで確立されます。

  1. 次に示すロケール関連のシステム・プロパティは、ホスト環境から確立されます。 一部のシステム・プロパティ(user.languageを除く)には、ホスト環境からの値がない場合があります。
    プロパティ・キーと対応する値を示します
    ロケール関連のシステム・プロパティ・キー 説明
    user.language デフォルトのロケールの場合はlanguage ("en" (英語)など)
    user.script デフォルトのロケールの場合はscript ("Latn" (ラテン語)など)
    user.country デフォルトのロケールの場合はcountry ("US" (アメリカ合衆国)など)
    user.variant デフォルトのロケール("POSIX"など)の場合はvariant
    user.extensions デフォルトのロケールの場合はextensions ("u-ca-japanese" (日本語カレンダ)など)
  2. これらのシステム・プロパティの値は、起動時に指定された値によってオーバーライドできます。 user.extensionsプロパティの上書き値が解析できない場合、その値は無視されます。 他のプロパティのオーバーライド値は、構文または妥当性のチェックは行われず、デフォルトのロケールで直接使用されます。 (通常、システム・プロパティ値は、ランチャの-Dコマンドライン・オプションを使用して指定できます。 たとえば、-Duser.extensions=foobarbazを指定すると、拡張子のないデフォルトのロケールになりますが、-Duser.language=foobarbazを指定すると、言語が"foobarbaz"のデフォルトのロケールになります。)
  3. デフォルトのLocaleインスタンスは、これらのシステム・プロパティの値から構築されます。

System.setProperties(Properties)/ System.setProperty(String, String)でシステム・プロパティ値を変更しても、デフォルトのロケールには影響しません。

デフォルトのロケールが確立されると、アプリケーションはgetDefault()を使用してデフォルトのロケールを問い合せ、setDefault(Locale)を使用して変更できます。 デフォルトのロケールがsetDefault(Locale)で変更された場合、対応するシステム・プロパティは変更されません。 アプリケーションでは、これらのシステム・プロパティを読み取って、値が古い可能性があるため解析または解釈することはお薦めしません。

Locale.Categoryに固有の詳細なデフォルトのロケールがあります。 これらのカテゴリ固有のデフォルトのロケールは、getDefault(Category)で照会し、setDefault(Category, Locale)で設定できます。 これらのカテゴリ固有のデフォルトのロケールの構築は、対応するシステム・プロパティによって決定されます。このプロパティは、前述のベース・システム・プロパティで構成され、カテゴリに応じて".display"または".format"のサフィクスが付きます。 たとえば、user.language.displayシステム・プロパティの値は、Locale.Category.DISPLAYカテゴリのデフォルト・ロケールのlanguage部分で使用されます。 カテゴリ固有のシステム・プロパティがない場合、前の例のuser.languageなど、"category-less"システム・プロパティが使用されます。

ロケール・マッチング

国際化されていて複数のロケールのためのローカライズされたリソースを提供するアプリケーションまたはシステムは、ユーザー固有の設定を満たす1つ以上のロケール(または言語タグ)を見つける必要がある場合があります。 このロケール・マッチングの説明では、言語タグとロケールが同じ意味で使用されます。

ユーザーが優先するロケールを言語タグ・セットにマッチングするために、RFC 4647 Matching of Language Tagsはフィルタリングおよびルックアップという2つのメカニズムを定義しています。 フィルタリングはマッチングするすべてのロケールを取得するために使用され、ルックアップはもっともよくマッチングするロケールを選択するために使用されます。 マッチングは大文字と小文字の区別なしで行われます。 これらのマッチング・メカニズムについては、この後のセクションで説明します。

ユーザーの設定は言語優先度リストと呼ばれ、言語範囲のリストとして表されます。 構文的には、基本と拡張という2つのタイプの言語範囲があります。 詳細は、Locale.LanguageRangeを参照してください。

フィルタリング

フィルタリング操作はすべてのマッチングする言語タグを返します。 RFC 4647では次のように定義されています: 「フィルタリングでは、各言語範囲は受け入れ可能なマッチングである最小固有言語タグ(つまり、サブタグがもっとも少ない言語タグ)を表します。 タグのマッチング・セット内のすべての言語タグは、言語範囲以上のサブタグを持ちます。 言語範囲内のワイルドカードでないすべてのサブタグは、マッチングするすべての言語タグに出現します。」

フィルタリングには次の2つのタイプがあります: 基本言語範囲用のフィルタリング(「基本フィルタリング」といいます)と拡張言語範囲用のフィルタリング(「拡張フィルタリング」といいます)です。 これらは、指定された言語優先度リストに含まれる言語範囲の種類によって異なる結果を返す場合があります。 Locale.FilteringModeは、フィルタリングを実行する方法を指定するパラメータです。

検索

ルックアップ操作はもっともマッチングする言語タグを返します。 RFC 4647では次のように定義されています: 「フィルタリングとは対照的に、各言語範囲は受け入れ可能なマッチであるもっとも固有なタグを表します。 最初に見つかったマッチング・タグは、ユーザーの優先度に従ってもっとも近いマッチと見なされ、返される項目です。」

たとえば、言語優先度リストが2つの言語範囲("zh-Hant-TW""en-US"、優先度順)から構成される場合は、ルックアップ・メソッドはもっともマッチングする言語タグを見つけるために次の言語タグを段階的に検索します。

    1. zh-Hant-TW
    2. zh-Hant
    3. zh
    4. en-US
    5. en
 
前述の言語範囲に完全にマッチする言語タグがある場合、その言語タグが返されます。

"*"は特殊な言語範囲で、ルックアップ時に無視されます。

サブタグ'*'が言語範囲に含まれるために複数の言語タグがマッチする場合は、言語タグのCollectionに対するIteratorによって返される最初のマッチする言語タグは、もっとも一致する言語タグとして処理されます。

ロケールの使用

Localeを取得したら、それ自体に関する情報を問い合せることができます。 国(または地域)コードを取得するにはgetCountry、言語コードを取得するにはgetLanguageを使用します。 getDisplayCountryを使用すれば、ユーザーへの表示に適した国の名前を取得できます。 同じように、getDisplayLanguageを使用すれば、ユーザーへの表示に適した言語の名前を取得できます。 興味深いことに、getDisplayXXXメソッドは、それ自身がロケール依存で、2つのバージョンを持ちます: 一方はデフォルトのDISPLAYロケールを使用し、他方は引数として指定されたロケールを使用します。

Javaプラットフォームには、ロケールに依存する操作を行ういくつかのクラスがあります。 たとえば、NumberFormatクラスは、数値や通貨、パーセントをロケールに依存する形でフォーマットします。 NumberFormatなどのクラスには、この型のオブジェクトを作成するための簡易メソッドがいくつかあります。 たとえば、NumberFormatクラスには、デフォルトのNumberFormatオブジェクトを作成するために次の3つの簡易メソッドがあります。

    NumberFormat.getInstance();
    NumberFormat.getCurrencyInstance();
    NumberFormat.getPercentInstance();
これらのメソッドにはそれぞれ2つのバリアントがあります。明示的なロケールを持つものと、持たないものです。後者はデフォルトのFORMATロケールを使用します。
    NumberFormat.getInstance(myLocale);
    NumberFormat.getCurrencyInstance(myLocale);
    NumberFormat.getPercentInstance(myLocale);
Localeは、どのオブジェクト(NumberFormat)を取得するかを指定するためのメカニズムです。 ロケールは、オブジェクトを指定するための単なるメカニズムであり、オブジェクト自体のコンテナではありません

互換性

互換性を維持するために、LocaleコンストラクタはJava Runtime Environmentバージョン1.7より前の動作を保持します。 toStringメソッドについても概して同じことが言えます。 したがって、Localeオブジェクトは以前と同様に使用できます。 特に、toStringの出力を解析して言語、国、およびバリアント・フィールドを取得しているクライアントは、引き続きそうすることができます(ただし、そのようにしないことが強く推奨されます)。ただし、スクリプトまたは拡張が存在する場合は、バリアント・フィールドに追加の情報が含まれることになります。

また、Localeのコンストラクタでは規定されていない構文制限がBCP 47では規定されています。 これは、ロケールとBCP 47言語タグの間の変換で、情報が失われる場合もあることを意味します。 したがって、ロケールの言語、国、またはバリアントがBCP 47に適合していない場合、そのようなロケールの状態をtoLanguageTagで表すことはできません。

このような問題があるため、クライアントは非準拠ロケールを構築することから移行して、代わりにforLanguageTagおよびLocale.Builder APIを使用することをお薦めします。 完全なロケールを表す文字列が必要な場合、クライアントはこの目的にはいつでもtoLanguageTagを利用できます。

特例として

互換性を維持するため、2つの非準拠ロケールが特例として扱われます。 ja_JP_JPおよびth_TH_THです。 これらは、バリアントが短すぎるため、BCP 47では整形式ではありません。 BCP 47への移行を容易にするため、これらは構築時に特別に扱われます。 コンストラクタはこれら2つの場合に限り例外を生成し、ほかの値ではJava 7より前とまったく同様に動作します。

Javaでは、ja_JP_JPを使用して日本で使用されている日本語を和暦とともに表しています。 Unicodeロケール・キーca ("calendar"の場合)を指定し、japaneseと入力することで、Unicodeロケール拡張を使用して表示できるようになりました。 Localeコンストラクタが引数"ja", "JP", "JP"で呼び出されると、拡張「u-ca-japanese」が自動的に追加されます。

Javaでは、タイでタイ語とタイ語とともに使用されるタイ語を表すためにth_TH_THが使用されています。 また、Unicodeロケール・キーnu ("number"の場合)および値thaiを指定して、Unicodeロケール拡張を使用して表示できるようになりました。 Localeコンストラクタが引数"th", "TH", "TH"で呼び出されると、拡張「u-nu-thai」が自動的に追加されます。

直列化

直列化の際、拡張も含めすべてのフィールドがwriteObjectによって出力ストリームに書き込まれます。

直列化復元の際、th_TH_THおよびja_JP_JPの2つの場合のみ、「特例」で説明されている拡張がreadResolveによって追加されます。

レガシー言語コード

ロケールのコンストラクタは、常に3つの言語コードを以前の廃止された形式に変換しました: heiwにマップされ、yijiにマップされ、idinにマップされます。 Java SE 17以降は該当しません。 各言語が新しい形式にマップされ、iwheにマップされ、jiyiにマップされ、inidにマップされます。

下位互換性のある動作の場合、システム・プロパティjava.locale.useOldISOCodesは、Java SE 17より前の動作に戻ります。 システム・プロパティがtrueに設定されている場合、現在の3つの言語コードが下位互換性のあるフォームにマップされます。 このプロパティはJavaランタイム起動時にのみ読み取られ、System.setProperty()に対する後続のコールには影響しません。

1.7で追加されたAPIは、古い言語コードと新しい言語コードの間でマッピングされ、ロケール (getLanguageおよびtoStringが、java.locale.useOldISOCodesシステム・プロパティに依存するマップされたコードを反映するようにします)に内部でマッピングされたコードを保持しますが、BCP 47言語タグAPI (toLanguageTagが新しいものを反映するようにします)で新しいコードを使用します。 これにより、ロケールの構築に使用されるコードやAPIにかかわらず、ロケール間の等価関係が維持されます。 Javaのデフォルト・リソース・バンドルのルックアップ・メカニズムはこのマッピングも実装するため、どちらかの命名規則でもリソースの名前を指定できます。ResourceBundle.Controlを参照してください。

3文字の言語/国(地域)コード

Localeのコンストラクタでは、言語および国のパラメータの長さは2文字であると指定されてきましたが、実際には任意の長さが受け入れられていました。 この仕様が緩和され、2文字から8文字までの言語コードと、2文字から3文字までの国(地域)コードが許可されるようになりました。特に、IANA言語サブタグ・レジストリに指定されている3文字の言語コードと3桁の地域コードが許可されます。 互換性のため、実装では引き続き長さの制約は課されません。

導入されたバージョン:
1.1
外部仕様
関連項目: