Edited at

iOS 13時代の Locale (言語と地域)基本おさらい【重要】


Locale (ロケール)とは「言語 Language」+「地域 Region」

en_JP (英語 + 日本地域)

これを Locale identifier (ロケール識別子・アイデンティファイア)と呼ぶ。

「言語」+「地域」が基本形だが例外もある。「地域」が無い場合や「字体」「方言」が付く場合など。

Locale が決まると『小数点 decimal separator』『ケタ区切り文字 grouping separator』『通貨記号 currency symbol』などが自動的に決まる。

なにを基準にして決まっているか? → 「世界の実情に合わせて決まる」。

「言語」だけで決まるわけでも「地域」だけで決まるわけでもない。

例:

[スペイン語] + [スペイン地域] = 小数点はカンマ ,

[スペイン語] + [アメリカ地域] = 小数点はピリオド . 

[日本語] + [スペイン地域] = 小数点はピリオド .

[日本語] + [アメリカ地域] = 小数点はピリオド .

おおまかな印象では、英語では「地域」を根拠に、英語以外では「言語」を根拠に決まることが多いがそれ以外のケースもある。


実際の確認方法

iOS 13 の入った端末上の[設定アプリ]>[一般]>[言語と地域]で、言語と地域を変更する。すると下のほうに「地域に応じた書式の例」が実際に表示されるので、確かめてみる。

(※ もしも、端末の言語変更してメニューが読めなくなって混乱した場合は、あわてずに、別のiOS端末やXcodeの端末シミュレーターと見比べて操作すれば元に戻せます)

日本では「3桁区切りでカンマ」「小数点はピリオド」があたりまえに思えるが、世界で使われる数字の表記ルール慣習はさまざま。正確に取り組みたい場合は、世界各地の実情について調査・把握する必要あり。

(欧州で少しづつ違いがあったり、特殊なインドや、桁区切りに空白を用いたり桁区切りを使わない地域もあります)


【重要】アプリ内コードから Locale.current で取得されるロケールは、いまiOS端末に設定されている「言語+地域」ではない!

ではどうやってそのアプリのcurrentロケールが決まるのか?

→ そのアプリが対応しているローカライズ言語(Localizable.stringsファイルの存在)のなかから、iOS端末で『使用する言語の優先順位』で設定された言語のはじめから該当する言語をさがして一致したもの、それを「言語」とし、それに、iOS端末で設定されている「地域(リージョン)」を組み合わせて、アプリ独自のロケールidentifierがセットされる。

[そのアプリが用意してある言語のなかから該当する言語] + [端末に設定された地域] → 新たなロケールidentifier

または、

そのアプリがiOS端末上の[設定アプリ]内項目に表示される Settings.bundle を持っていて、そこからアプリが用意してあるローカライズ言語を選べる場合は、そこで選択決定した言語と、iOS端末で設定されている「地域」を組み合わせて、アプリ独自のロケールがセットされる。

もちろん、アプリ内で必要なときは、自由に独自のロケールを生成することもできる。

let tmpLocale = Locale(identifier: "fr_JP")


ロケールidentifier の仕様(書き方)は統一されていない

現在、コンピュータの世界には ロケールidentifier を

_ アンダースコア でつなげて書く方式と

- ハイフン でつなげて書く方式(Windows系など)

の二種類があるようです。 例: en_JP または en-JP

iOS 13.2 現在、Locale.current も NSLocale.current も同じように動作して アンダースコア入りの identifier が取得される。また、

let all = Locale.availableIdentifiers

print("all = \(all)")

iOS で利用できる全identifierを確認するとアンダースコア入りの結果になっているので、iOSアプリ単体では アンダースコア を用いるのが妥当。

iOS 13.2 現在、ロケール生成時のリテラルにどちらの書き方をしても正しく動作する。

注意:

・iOS 13.2 現在、Locale.preferredLanguages で取得されるロケール配列の中身は - ハイフン 方式の [String] 

・インターネット連携やマルチプラットフォームの場合はプロジェクト全体の仕様をよく確認する。

・iOS の古いバージョンでは、中国などのロケール表現でハイフンとアンダースコアの両方が含まれるロケールidentifier も存在した。  


おまけ:

端末の「地域」を「アメリカ」にしてiOSのアップデートを行うとその地域だけで開始されているサービスを試すことができます。(例・Apple公式 Newsアプリ )


以上をふまえて、NumberFormatter 、DateFormatter 、および ローカライズ関連の理解をすすめていくとよさそうです。


参考: Apple 公式ドキュメント(英語)

https://developer.apple.com/documentation/foundation/locale


付記:

・通貨記号など、国の体制が変われば将来変わる可能性もあります。

・ロケールまわりの検証はシミュレーターではなく実機上でのテストをおすすめします。

・「設定アプリ」という呼称は不正確です。

・以前、情報整理が不十分でかえって混乱のもとになる内容で投稿してしまったので、その記事は削除して内容刷新して再投稿しました。

・iOSには進化の歴史があり Locale まわりの仕様も大きく変化しています。検索で見つかる過去の記事は先人たちの非常に役立つありがたい情報ですが、内容によっては最新の環境に合致しない場合もあるので、注意しながら理解をすすめる必要があります。


環境: 2019/10/31 update(検証済み)

iOS 13.2 + iPad(5th)実機

Xcode 11.2

macOS 10.15.1

JBOYSOFT Junji Suzuki