通貨の表示
I18Nv2は通貨の表記もサポートしています(通貨の表記は組み込みの関数money_format()でもサポートされているのですが、この関数はWindowsでは実装されていません)。早速試してみましょう。
$loc=new I18Nv2_Locale('ja'); echo $loc->formatCurrency(100.01); //JPY 100.01 echo '<br />'; $loc=new I18Nv2_Locale('en_US'); echo $loc->formatCurrency(100.01); //USD 100.01
数値の前に通貨の表記が追加されていることが分かります(場合によって100.01円になったり100.01ドルになったりするというのでは実用にはなりませんが、その問題はここでは追求しません)。
通貨にはもう一つの表記法があります。
$loc=new I18Nv2_Locale('ja'); $loc->setCurrencyFormat(I18Nv2_CURRENCY_LOCAL); echo $loc->formatCurrency(100.01); //\100.01 echo '<br />'; $loc=new I18Nv2_Locale('en_US'); $loc->setCurrencyFormat(I18Nv2_CURRENCY_LOCAL); echo $loc->formatCurrency(100.01); //$100.01
通貨が1文字で表現されます。アメリカドルはこれでいいのですが、円記号がバックスラッシュになってしまっています。MS明朝など一部のフォントではバックスラッシュと円記号の区別がつかないので気づかない人もいるかもしれません(U+5CとU+A5、HTML中なら「\」あるいは「¥」と書いて表示される文字の区別が付かないフォントは、開発時には使わないことをお勧めします)。表にまとめました。
バックスラッシュ | 円記号 | |
Shift_JIS | 0x5C | |
Windows-31J(CP932) | 0x5C | 0xA5 |
Unicode | U+5C | U+A5 |
MS明朝 | ||
Times New Roman | ||
Times New Roman(Word2007のデフォルト表示) |
本題からは外れますが、Shift_JISの0x5Cが円記号だということを不思議に思う人は規格を確認してください。IANAによれば、Shift_JISはJISX0208で規定されています。JISX0208によれば、ビット組み合わせ21~7Eの1バイト符号の領域には、JISX0201のラテン文字用図形文字集合の2/1~7/14を割り当てることになっています。そしてJISX0201によれば、0x5Cは円記号なのです(JISの規格書は日本工業標準調査会で閲覧できます。「X0208」などとして検索してください)。
通貨記号を正しく直すために、次のようなコードを「ja.php」に追記してください。
$this->currencyFormats[I18Nv2_CURRENCY_LOCAL][0]='¥'; //通貨記号(円記号)
円記号はそのまま書いてもいいのですが、環境によってはバックスラッシュと区別が付かなくなるので文字参照を使いました。あまりないケースだと思いますが、これらのファイルをWordで作成していると、表に示したように、Times New Romanのような、バックスラッシュと円記号を区別できるはずのフォントでも、区別できなくなってしまいます。これは、バックスラッシュで表示される画像を円記号の字形にするという、意義の不明な機能が有効になっているためです。Word 2007の場合、Wordの[オプション]-[詳細設定]で「バックスラッシュを円記号に変換する」をオフにすることで、この機能を無効にできます(オンになっていても、変換されるのは見た目だけなので混乱します)。Mac OSの場合は、optionキーを押しながら円記号の印字されたキーを押すとバックスラッシュが入力されます(逆に設定することもできます)。
よく分からない人は、円記号にはいわゆる全角の「¥」を使うようにするといいでしょう。
数値の表示
I18Nv2は数値の表示もサポートしています。数値の表記の違いにはあまりなじみがないかもしれません。例えば、日本や米国では小数点を「.」で表しますが、フランスでは「,」を使います。試してみましょう。
$loc=new I18Nv2_Locale('en_US'); $loc->setNumberFormat(I18Nv2_NUMBER_INTEGER); echo $loc->formatNumber(1000.01); //1,000 echo '<br />'; $loc->setNumberFormat(I18Nv2_NUMBER_FLOAT); echo $loc->formatNumber(1000.01); //1,000.01
数値の書式には整数(INTEGER)と1未満あり(FLOAT)の2種類があります。言語をフランス語にすると、小数点が変わります。
$loc=new I18Nv2_Locale('en_US'); //英語/米国の場合 $loc->setNumberFormat(I18Nv2_NUMBER_INTEGER); echo $loc->formatNumber(1000.01); //1 000 echo '<br />'; $loc->setNumberFormat(I18Nv2_NUMBER_FLOAT); echo $loc->formatNumber(1000.01); //1 000,01
これまでと同様、日本語用には書式設定を用意しなければなりません。次のようなコードを「ja.php」に追記すると、英語/米国の場合と同じ結果が得られます。
$this->numberFormats[I18Nv2_NUMBER_FLOAT][0] = '2'; //小数点以下の桁数 $this->numberFormats[I18Nv2_NUMBER_FLOAT][1] = '.'; //小数点 $this->numberFormats[I18Nv2_NUMBER_FLOAT][2] = ','; //桁区切り $this->numberFormats[I18Nv2_NUMBER_INTEGER][0] = '0'; //小数点以下の桁数 $this->numberFormats[I18Nv2_NUMBER_INTEGER][1] = '.'; //小数点 $this->numberFormats[I18Nv2_NUMBER_INTEGER][2] = ','; //桁区切り
おわりに
PEAR::I18Nv2を用いて日時と通貨・数値の表示を国際化する方法とその際の注意点を紹介しました。
国際化は開発のかなり早い段階で意識することが必要です。開発が進んでからアプリケーションを国際化しようとすると、大量のコードを修正しなければならなくなります。大切なのは、「ロケールに依存する書式などの情報を、コードに直接書かないようにすること」です。国際化が必要になる可能性のあるアプリケーションを開発する際には、最初からこのことを意識して開発するようにするといいでしょう。
国際化のためには、ここで紹介したことのほかに、メッセージ文字列の翻訳という大切な作業がありますが、それは別の機会に紹介しましょう(PEAR::Translation2で実現します)。