【JavaGold】ローカライズ

# ローカライズ

### java.util.Locale

言語や国ごとに異なるものの表記規則を示す。
＃ 例：単位・記号・日付・通貨など

アプリケーションを使用した国毎に、表示を変えたい場合などにロケールを利用する。
（アプリを使用する国によって文字を日本語・英語と分けたり等）

インスタンス生成方法は主に以下3種類ある。

* new
* Localクラスの定数
* getDefault()メソッド
* IETF言語タグを使用

**■ 主なコンストラクタ・メソッド**

<table>
  <thead>
    <tr>
      <th>コンストラクタ</th>
      <th>内容</th>
    </tr>
  </thead>
  <tr>
    <td>Local(String language, String country)</td>
    <td>引数の言語/国コードからオブジェクトを生成</td>
  </tr>
</table>

```java
// newによるインスタンス生成
// ja・en：言語名コード ｜ JP・US：国名コード
Locale localeJp = new Locale("ja","JP");  // 日本のロケール
Locale localeUs = new Locale("en","US");  // アメリカのロケール

// Localeクラスの定数によるインスタンス生成
Locale localeJp = Locale.JAPAN;
Locale localeUs = Locale.US;

// getDefault()メソッドによるインスタンス生成
// 日本で実行すると日本のLocaleインスタンスが生成される
Locale localeJp = Locale.getDefault();

// IETF言語タグを使用
Locale locale = Locale.forLanguageTag("en-US-x-lvariant-POSIX");
```

<table>
  <thead>
    <tr>
      <th>メソッド</th>
      <th>内容</th>
    </tr>
  </thead>
  <tr>
    <td>static getDefault()</td>
    <td>デフォルトロケールの現在の値を取得</td>
  </tr>
  <tr>
    <td>final String getDisplayCountry()</td>
    <td>ロケールの国名を返却</td>
  </tr>
  <tr>
    <td>final String getDisplayLanguage()</td>
    <td>ロケールの言語名を返却</td>
  </tr>
  <tr>
    <td>String getCountry()</td>
    <td>ロケールの国名コードを返却</td>
  </tr>
  <tr>
    <td>String getLanguage()</td>
    <td>ロケールの言語名コードを返却</td>
  </tr>
</table>

```java
// ja_JP が格納される（OSが日本の場合）
Locale locale = Locale.getDefault();

// 日本 が格納される
String country = locale.getDisplayCountry();

// 日本語 が格納される
String language = locale.getDisplayLanguage();

// JP が格納される
String country_code = locale.getCountry();

// ja が格納される
String language_code = locale.getLanguage();

// 備考：他のインスタンス生成方法
Locale locale = new Locale.Builder().setLanguage("ja")
                                    .setRegion("JP")
                                    .setScript("Jpan")
                                    .build();
// setScript()：引数はISO 15924 alpha-4スクリプトコード（Javadoc参照）
// build()：Locale.Builderのメソッドで、Localオブジェクトを生成
```

プロパティファイルに記述するキーと値の表記
「キー=値」、「キー:値」

#### `setDefault(Locale newLocale)`
Localeのカテゴリを指定して、Localの参照を受け取る。
```java:実装例
Locale.setDefault(Locale.JAPANESE);
```

#### `setDefault(Locale.Category category, Locale newLocale)`
Localeのカテゴリを指定して、Localの参照を受け取る。
```java:実装例
Locale.setDefault(Locale.Category.FORMAT, Locale.JAPANESE);
```

### Propertiesクラス
#### listメソッド
引数にjava.io.PrintStream型やjava.io.PrintWriter型の引数を受け取りプロパティファイルの中身を一覧表示する。
```java:実装例
// プロパティファイルの値を一覧表示
public class Sample {
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();
        prop.load(new FileReader("db_settings.properties"));
        prop.list(System.out);
    }
}
```

#### 値の一覧を表示するコード
```java
// 値の一覧を表示する
Properties prop = new Properties();
prop.load(new FileReader("sample.properties"));
prop.list(System.out);

// 値の一覧を表示する
Set keys = prop.keySet();
for(Object key: keys) {
    System.out.println(prop.get(key));
}

// 値の一覧を表示する
prop.forEach((k, v) -> System.out.println(v));
```

#### Propertiesオブジェクトからキーを取り出す
#### `public V get​(Object key)`
* メソッドの引数がObject型
```java
Set keys = prop.keySet();
for(Object key: keys) {
    System.out.println(prop.get(key));
}
```

#### `public String getProperty​(String key)`
* メソッドの引数がString型
```java
public class Sample {
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();
        prop.load(new FileReader("sample.properties"));
        String value = prop.getProperty("key");
        System.out.println(value);
    }
}
```

```:Unicode表記に変換したプロパティファイルを出力するためのコマンド
native2ascii input.properties output.properties
```

```:プロパティファイルを記述するときに使用できる文字コード
ISO-8859-1
UTF-8
```

デフォルトのロケール情報が「ja_jp」の環境でプロパティファイルが「sample.properties」、「sample_ja_jp.properties」が存在する場合は、「sample_ja_jp.properties」に記述したキー「test」の値が表示される
```java
public class Sample {
    public static void main(String[] args) throws Exception {
        // パッケージ名.ファイル名を指定
        ResourceBundle resource 
            = ResourceBundle.getBundle("sample");
        System.out.println(resource.getString("test"));
    }
}
```

```:問
ロケール情報に対応するプロパティファイルが存在しなかった場合に発生する例外
```
```:答え
MissingResourceException
```

```:問
デフォルトのロケールが日本という環境で、英語で内容を記述した「sample_en_US.properties」というプロパティファイルを読み込む方法。
```
```:答え
ResourceBundleクラスのgetBundleメソッドの第2引数にロケール情報を渡す。
```

Propertiesクラスのlistメソッドに、PrintWriter型のオブジェクトへの参照を渡す。

通貨を表す数値のフォーマットを実行するにはNumberFormatクラスのgetCurrencyInstanceメソッドを使用


### java.time.format.FormatStyle

<table>
  <caption>FormatStyleの列挙子による日付の書式(2021年4月1日の例)</caption>
  <thead>
    <tr>
      <th>列挙子</th>
      <th>書式</th>
    </tr>
  </thead>
  <tr>
    <td>FULL</td>
    <td>Thursday, April 1, 2021</td>
  </tr>
  <tr>
    <td>LONG</td>
    <td>April 1, 2021</td>
  </tr>
  <tr>
    <td>MEDIUM</td>
    <td>Apr 1, 2021</td>
  </tr>
  <tr>
    <td>SHORT</td>
    <td>4/1/21</td>
  </tr>
</table>


### java.time.format.DateTimeFormatter

<table>
  <caption>DateTimeFormatterの定数</caption>
  <thead>
    <tr>
      <th>定数</th>
      <th>意味</th>
      <th>使用例</th>
    </tr>
  </thead>
  <tr>
    <td>BASIC_ISO_DATE</td>
    <td>基本的なISO日付書式</td>
    <td>20111203</td>
  </tr>
  <tr>
    <td>ISO_LOCAL_DATE</td>
    <td>ローカルのISO日付書式</td>
    <td>2011-12-03</td>
  </tr>
  <tr>
    <td>ISO_LOCAL_TIME</td>
    <td>ローカルのISO時刻書式</td>
    <td>10:15:30</td>
  </tr>
  <tr>
    <td>ISO_ORDINAL_DATE</td>
    <td>年および年の日付の書式</td>
    <td>2012-337</td>
  </tr>
</table>

#### `DateTimeFormatter ofPattern​(String pattern)`
日付の書式を表すパターンを文字列として、受け取る。

```java:実装例
LocalDate date = LocalDate.of(2021, 4, 1);
DateTimeFormatter formatter =
    DateTimeFormatter.ofPattern("yyyy'年' MMMM d'日' eeee");
System.out.println(formatter.format(date));
```
```:実行結果
2021年 4月 1日 木曜日
```