2021.03.08

「ロケール」のおはなし


本投稿記事の中で御紹介しているソースコードは FU_box(福岡大学公認クラウドストレージ)に格納してあります。

動画や画像は本ブログ記事投稿者が管理する本学内のウェブサーバに置いてあります。

いずれも自由に御利用ください。


コンピュータ用語としての「ロケール」は,「ユーザの用いる言語や居住国/地域等々に対応した様々な言語関連情報の集合」のことを言います。

コンピュータのソフトウェアは,こうした「言語関連情報の集合」を参照することで,ユーザが用いる言語の変更だけに留まらず,対象の国/地域の文化に根ざした様々な表記法(年月日,数値,度量衡,通貨記号,等々)にも正確に対応することができるようになります。

本「大学院ブログ」(CMS の WordPress をベースにしているようです)でも,「日本語・英語」による「ユーザインタフェースの切り替え」の背後では「ロケール」が働いています(のはずです)。

あるロケールに対応することは「localis[z]ation」(綴りが長いので途中の文字列の連なりを「数」に置き換え「L10N」と記されたりもします.L が大文字で表記されるのは,小文字の l だと次の数字の 1 と紛らわしくなってしまうためです)と呼ばれますが,複数のロケールに対応することは「internationalis[z]ation」(i18n)と言います。

ロケールの「識別子」(identifier)は,「ja_JP.UTF-8」や「de_DE.UTF-8」のように「言語コード(ja 日本語; de ドイツ語),国/地域コード(JP 日本; DE ドイツ),文字コード(UTF-8 ユニコード)」といった複数のコードセットで構成されています。

ラテン字2文字から成る言語コードは「国際標準化機構(ISO: International Organization for Standardization)」の定める ISO 639-1 に,また,国/地域コードは ISO 3166-1 alpha-2 に,それぞれ従った書式です。文字コード UTF-8 は ISO/IEC 10646 で定義されています。

最近の PC は,OS が Windows であれ Mac であれ Linux であれ,最初から「i18n」対応済みとなっていることが多いと思います。もっとも Linux の軽量ディストリビューションのように,主要な言語用に少数のロケールだけが予め使えるようになっていて,他のロケールは「寝かされている」場合もあります。

こういう場合は,システム内に含まれる locale.gen(テキストファイル)を編集し,必要なロケールを「起こして」やり(=必要とするロケール識別子の行頭にある「#」記号を外して保存する),管理者権限で locale-gen プログラム(=シェルスクリプトです)を実行すれば,後は全自動で必要な設定がなされる,というような仕組みになっています。

UNIX 系のシステム(= Mac, Linux, Windows Subsystem for Linux など C 言語の標準ライブラリを含むシステム)であれば,現在のロケールは「locale」コマンドを使えば直ぐに参照できます。

実際にロケールを切り替えるには,「export」コマンドを使って「LANG 環境変数」の引数に切り替えたいロケールの識別子を指定するだけです。例えば,「ドイツ国のドイツ語」であれば「export LANG=de_DE.UTF-8」,同じドイツ語でも「オーストリア国のドイツ語」であれば「export LANG=de_AT.UTF-8」,とします。

オーストリアのドイツ語ロケールであれば,例えば「1月」は標準ドイツ語の Januar ではなく「Jänner」と出力される,という具合です。

前回のブログ投稿記事(「プログラム『世界の言葉でごあいさつ』を書いてみました」)で御紹介させていただいたシェルスクリプト・プログラムでは,この export コマンドを用いてロケールをその都度「英語(イギリス・アメリカ),ドイツ語,フランス語,スペイン語,ロシア語,中国語(標準語・台湾・香港),韓国語,日本語」に切り替え,その後 date コマンドを発行し,その出力を say コマンドに引き渡すことで,その時点での「年月日および時分秒」が「使用言語そして国/地域」に最適化された上でコンピュータの人工音声に読み上げられるような仕掛けを施した次第です。

今回御紹介させていただく動画は,こうした「ロケール」切り替えの挙動をさらに詳しく確認していただけるように,PHP (PHP: Hypertext Preprocessor) で書いたプログラムを Linux 上で走らせた(正確には Linux を遠隔操作し Mac のターミナルに読み込んでいます.当該 Linux 機には「デスクトップ環境」を構築していないため,そこでの録画ができないためです)際の様子を録画したものです(無音.再生時間:7分47秒)。

ソースコードの中で使っている setlocale(ロケールをセットする),date_default_timezone_set(タイムゾーンをセットする),等々といった「関数」は,全て PHP に予め準備されている「組み込み関数」であり,特別なことは何もしていません。

ロケールやタイムゾーンを切り替えた後は,strftime (string format time) 関数により,ロケール下の当該言語による「完全な曜日名(%A),完全な月名(%B),日付・時間の短縮表現セット(%c)」が,「(%A のような)変換指定子」を記述してやるだけで,全て自動的に正しく出力されるようになります。

オーストリアのドイツ語「1月 Jänner」を出力させる箇所では,strtotime (string to time) 関数を使って「年月日を一時的に 2021-01-01 にセット」しています。

money_format 関数は,与えられた数値を当該ロケールにおける「金額文字列(通貨記号も含む)」に自動変換してくれます(%.2n は「小数点以下2位までのフォーマット」を指示する変換指定子)。

動画を御覧くださる際は,言語表記の違いだけではなく,各国における時差,通貨記号,少数「点」(ピリオド,コンマの別),3桁毎の区切符号(コンマ,ピリオド,空白スペースの別)等々に至るまで,自動的に各ロケールが反映された出力となっている様もチェックしてくださると有難いです。

動画(無音)の流れは以下のようになっております。本動画は「2021-03-06(土)の夕刻」に録画しました。

  1. locale コマンドで「現在のロケール設定(de_DE.UTF-8)」を確認
  2. date および cal (calendar) コマンドで de_DE.UTF-8 ロケールにおける「日時」と「今月のカレンダー」の出力を確認
  3. export コマンドで「ロケールを ja_JP.UTF-8 に切り替え」,locale コマンドで「切り替わったロケール設定(ja_JP.UTF-8)」を確認
  4. ja_JP.UTF-8 における「日時」と「今月のカレンダー」の出力を確認
  5. (次に 6. の ls コマンドを打ち込もうとしたが,誤って sl と叩いてしまった際のターミナルの反応! sl: steam locomotive)
  6. ls(list segments)コマンドで「現在作業中のディレクトリに存在するファイル一覧」の確認
  7. cat(concatenate)および less コマンドで「PHP プログラム locale_test_cli.php の中身を画面をスクロールしながら閲覧」
  8. php コマンドで「locale_test_cli.php を PHP で処理させた結果」を確認(less でスクロールさせながら)
  9. 最後に,locale_test_cli.php とほぼ同じ中身の locale_test_web.php をウェブページとしてブラウザで閲覧

白黒の地味な動画ですが,「ジョーク・コマンド(sl)」も一つだけ仕込んであります。お楽しみいただけると嬉しいです。

ロケールのテスト(PHP)画像
ロケールのテスト(PHP)Web ページ

上の画像は,locale_test_cli.php とほぼ同じ中身の locale_test_web.php をウェブページとしてブラウザで閲覧した際のものです。なお,locale_test_web.php が動作しているウェブサーバはプログラム動作確認のための実験機ですので,インターネット上に公開はしておりません。

プログラム locale_test_cli.php のソースファイルは

に置いてあります。locale に興味を持ってくださった方は,どうぞ,御自由にお試しください。PHP が動く環境であれば,Mac, Linux, Windows Subsystem for Linux のいずれでも追試 OK です(お使いのシステムによっては,欠けているロケールがあるかもしれません)。

P.S.

今回の PHP ソースでは,「通貨」箇所の出力に money_format 関数を使っていますが,この関数は PHP 8.0.0 バージョン以降では使えないことがアナウンスされています。PHP 8 系列以降では,代わりに NumberFormatter::formatCurrency あるいは numfmt_format_currency 関数を使うようにとのことですが,これらのシンタクス(構文規則)は money_format のようにシンプルではないため,あえて money_format を使ったプログラムのままにしてあります。今回のプログラムを動かした投稿者の環境における PHP のバージョンは 7.4.15 です。