SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

PEARライブラリ活用

I18Nv2による日時と通貨・数値の表記国際化

PEARライブラリ活用 (2)


  • X ポスト
  • このエントリーをはてなブックマークに追加

I18Nv2の基本

 I18Nv2を使えば、コードからロケールに特有の書式を排除することができます。

 まず、I18Nv2の基本的な使い方を確認します。次のコードによって、ブラウザの言語設定をPHP側で取得・設定することができます。

require_once 'I18Nv2/Negotiator.php';
require_once 'I18Nv2/Locale.php';

$i18n=new I18Nv2_Negotiator();
echo $i18n->getLocaleMatch();

 ロケールが正しく設定されたことは、次のように確認できます。ブラウザの言語設定を英語/米国にして試してみましょう。

echo setlocale(LC_ALL,0);
//English_United States.1252(日本語ならJapanese_Japan.932)

 このような自動設定は便利なのですが、ユーザーによっては、自分のブラウザの設定とは違う言語でページを閲覧したいということもあるでしょう。Webアプリを作る際には、そのようなユーザーのためのインターフェイスは何かしら用意しておくべきです。そのようなインターフェイスがあったとして、それを通じて実際に手動でロケールを切り替えるには、次のようなコードを実行します。

$loc=new I18Nv2_Locale('en_US'); //英語/米国に
$loc=new I18Nv2_Locale('ja'); //日本語に
$loc=new I18Nv2_Locale('English_United States'); //英語/米国に

 上のコードにI18Nv2を導入するメリットの一つが現れています。組み込みのsetlocaleを利用する際には、WindowsとWindows以外でその設定方法を変えなければなりませんでした。しかし、I18Nv2を用いると、この例のように、Windowsでも「en_US」のような表記が可能になるのです。

日付の表示

 I18Nv2を使って日付を表示してみましょう。ブラウザの言語設定を英語/米国にして以下のコードを実行すると、日付が米国式に表示されます。

echo $loc->formatDate(mktime()); //18-Feb-2008

 日本語を試す前に、formatDateの機能をもう少し紹介しましょう。日付の表示には、shortとmedium、long、fullという4つの形式が用意されています(指定しなければmediumになります)。

$loc->setDateFormat(I18Nv2_DATETIME_SHORT);
echo $loc->formatDate(mktime()); //18/02/08
echo '<br />';

$loc->setDateFormat(I18Nv2_DATETIME_MEDIUM);
echo $loc->formatDate(mktime()); //18-Feb-2008
echo '<br />';

$loc->setDateFormat(I18Nv2_DATETIME_LONG);
echo $loc->formatDate(mktime()); //18 February 2008
echo '<br />';

$loc->setDateFormat(I18Nv2_DATETIME_FULL);
echo $loc->formatDate(mktime()); //Monday, 18 February 2008

日本語への対応

 ブラウザの言語設定を日本語にして上のコードを試してみましょう。もし、ほとんど何も表示されなくなってしまったとしたら、それは、日本語用の書式が用意されていないためです。

 次のような内容のファイル「ja.php」を作って(UTF-8形式)、PHPがインストールされたディレクトリの下の「PEAR/I18Nv2/Locale」に置いてください(筆者の環境では「C:\xampp\php\PEAR\I18Nv2\Locale」)。

ja.php(文字エンコードはUTF-8)
<?php
$this->dateFormats=array( //日付の書式
  I18Nv2_DATETIME_SHORT=>'%y/%m/%d',
  I18Nv2_DATETIME_DEFAULT=>'%Y/%m/%d',
  I18Nv2_DATETIME_MEDIUM=>'%Y/%m/%d',
  I18Nv2_DATETIME_LONG=>'%Y年%m&#x6708;%d日',
  I18Nv2_DATETIME_FULL=>'%Y年%m&#x6708;%d日'
);
?>

 もう一度実行すれば、期待通りの結果が得られるはずです。

時刻の表示

 時刻も日付と同様で、4つの書式を使い分けることができます。まずは、ブラウザの言語設定を英語/米国にして実行してみましょう。

$loc->setTimeFormat(I18Nv2_DATETIME_SHORT);
echo $loc->formatTime(mktime()); //17:36
echo '<br />';

$loc->setTimeFormat(I18Nv2_DATETIME_MEDIUM);
echo $loc->formatTime(mktime()); //17:36:04
echo '<br />';

$loc->setTimeFormat(I18Nv2_DATETIME_LONG);
echo iconv('SJIS-WIN','UTF-8',$loc->formatTime(mktime()));
//17:36:04 東京 (標準時)
echo '<br />';

$loc->setTimeFormat(I18Nv2_DATETIME_FULL);
echo iconv('SJIS-WIN','UTF-8',$loc->formatTime(mktime()));
//17:36 o'clock 東京 (標準時)

 formatTimeは内部的でstrftimeを呼んでいるのですが、タイムゾーン(%Z)が国際化されていないようです。しかもSJIS-WIN(Windows-31JあるいはCP932)で出力されるので、UTF-8に変換しています(注1)。

注1
 これはいい解決策ではありません。あとで問題が拡大します。%Zを使わないように英語/米国の書式を変更するか、%Zを国際化するのが正しい解決ですが、ここではこのまま先に進みます。

日本語への対応

 日付の表示の際に初めて日本語に対応した(つまり、もともと日本語への対応がなされていなかった)場合には、ここでも日本語用の書式を用意しなければなりません。以下のコードを、先に作成した「ja.php」に追記してください。

ja.phpに追記
$this->timeFormats=array( //時刻の書式
  I18Nv2_DATETIME_SHORT=>'%H:%M',
  I18Nv2_DATETIME_DEFAULT=>'%H:%M:%S',
  I18Nv2_DATETIME_MEDIUM=>'%H:%M:%S',
  I18Nv2_DATETIME_LONG=>'%H&#x6642;%M&#x5206;%S&#x79D2;',
  I18Nv2_DATETIME_FULL=>'%H&#x6642;%M&#x5206;%S&#x79D2; %Z'
);

 文字参照を使っています(「時」はU+6642、「分」はU+5206、「秒」はU+79D2です)。「%H時%M分%S秒」と書きたいところなのですが、さきほどタイムゾーンが国際化されていない問題を回避するために、SJIS-WIN(Windows-31JあるいはCP932)をUTF-8に変換するコードを書いてしまったので、ここでUTF-8の文字列を使うと文字化けが発生してしまいます。

 タイムゾーンの問題に伴う文字コードの変換がなかったとしても、日付の「月」の時と同じ問題が発生するので、やはり文字参照を使うのが安全でしょう。

 「ja.php」をShift_JIS(あるいはCP932)で書いて、スクリプト側ですべて変換することにしておけばよいと思うかもしれませんが、その方法で対応できるのは日本語と英語など、ごく一部の言語だけです。国際化のために使える文字コードはUnicodeしかありません。

日付と時刻をまとめて表示

 日付(setDateFormatで書式を設定しformatDateで表示する)と時刻(setTimeFormatで書式を設定しformatTimeで表示する)のほかに、日付と時刻をまとめて表示するメソッドも用意されています。setDateTimeFormatで書式を設定し、formatDateTimeで表示します。書式の設定方法や使い方は日付や時刻と同じです。

日時を表現する際の注意

 メソッドformatDateformatTimeformatDateTimeには、引数としてint型のタイムスタンプを与えます。そのため、『PHPにおける日付と時刻の混乱』で紹介した2038年問題がここでも発生します。1901-12-13T20:45:52+0000より前と2038-01-19T03:14:07+0000より後の日時を使う可能性のある状況では、I18Nv2を使うべきではありません。

次のページ
通貨の表示

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
PEARライブラリ活用連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 矢吹 太朗(ヤブキ タロウ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2311 2008/04/02 17:44

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング