はじめに
作成しているプログラムの中で、ある日付の翌日を取得したいという状況を想像してください。一見単純そうなタスクですが、自分で実装するとなると、かなり面倒だということは容易に想像できます。「日」が27以下の場合は単に1を加えればいいのですが(実はこれは間違いです)、「日」が28以上になると、日数は月によって異なるため、まず、それが何月なのかを調べなければなりません。さらに、もし2月だったら閏年なのかどうかをチェックする必要もあります。「『年』が4の倍数なら閏年」というような単純な話ではないことはご存じでしょう。
幸運なことに、現在広く使われているプログラミング言語の多くは、日付や時刻の計算のためのライブラリやクラスを持っているので、暦の詳細を知らなくても、日時を扱うことができるようになっています。
PHPにも日付や時刻を扱うための手段が用意されていて、簡単に使うことができます。困ったことに、複数の手段がある上に、それらのいずれもが何らかの問題を抱えています。この記事では、PHPで日時を扱う標準的な方法と、それらの使用上の注意点を紹介します。ここで紹介するのは次の4つの方法です。
- エポックタイムスタンプ
- PEAR Date
- DateTime
- ユリウス日
対象読者
- PHPで日付や時刻を処理することがある方
- 暦について興味がある方
必要な環境
この記事の内容をすべて実行するためには、PHP 5.1以上が動作する環境が必要です。一部はPHP 4でも動作します(筆者の環境はXAMPP for Windows 1.6.3a上のPHP 5.2.3です)。
エポックタイムスタンプ
date()
以下のようにして現在時刻を表示できます。
echo date('r'); // Tue, 16 Oct 2007 16:50:06 +0900 // (現在時刻をRFC 2822フォーマットで表示)
「r
」はdate()
のフォーマット文字です。フォーマット文字はほかにもたくさんあるので、マニュアルのdete()の項を参照してください。フォーマットを指定することでさまざまな形式で表示できるのですが、次のような標準的なフォーマットがあらかじめ用意されています。
echo date(DATE_ATOM); // 2007-10-16T16:50:06+09:00 echo date(DATE_COOKIE); // Tuesday, 16-Oct-07 16:50:06 JST echo date(DATE_ISO8601); // 2007-10-16T16:50:06+0900 echo date(DATE_RFC822); // Tue, 16 Oct 07 16:50:06 +0900 echo date(DATE_RFC850): // Tuesday, 16-Oct-07 16:50:06 JST echo date(DATE_RFC1036); // Tue, 16 Oct 07 16:50:06 +0900 echo date(DATE_RFC1123); // Tue, 16 Oct 2007 16:50:06 +0900 echo date(DATE_RFC2822); // Tue, 16 Oct 2007 16:50:06 +0900 echo date(DATE_RFC3339); // 2007-10-16T16:50:06+09:00 // (DATE_ATOMと同じ) echo date(DATE_RSS); // Tue, 16 Oct 2007 16:50:06 +0900 echo date(DATE_W3C); // 2007-10-16T16:50:06+09:00
+900
や+09:00
、JST
というのはタイムゾーンを表しています。デフォルトのタイムゾーンは次のように取得・変更できます。
echo date_default_timezone_get(); // Asia/Tokyo date_default_timezone_set('GMT'); // タイムゾーンをGMTに変更 echo date('r'); // Tue, 16 Oct 2007 07:50:06 +0000
以下では特に断らない限り、タイムゾーンをGMT(グリニッジ標準時)とします。ちなみに、現在の公式な時刻はUTC(協定世界時)です。UTCはセシウム133が9192631770回振動する時間を単位にしたもので、天体観測によって定まるGMTとの差を埋めるために、適宜閏秒が挿入されます。利用可能なタイムゾーンはList of Supported Timezonesに列挙されています。
strftime()
strftime()
もdate()
と並ぶ標準的な関数です。strftime()
を使って現在時刻を表示してみましょう。
//現行ロケールでの標準的な形式 echo strftime('%c'); // 10/16/07 07:50:06 //表示フォーマットを指定 echo strftime('%A, %d %B'); // Tuesday, 16 October //date()でも同じことができる echo date('l, d F'); // Tuesday, 16 October
%A
や%d
、 %B
はstrftime()
のフォーマット文字列です。詳細はマニュアルのstrftime()の項を参照してください。
strftime()
の出力はロケールに依存します。まず、現行のロケールを確認しましょう。
echo setlocale(LC_ALL,0);
LC_COLLATE=C;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=C; LC_NUMERIC=C;LC_TIME=C
文字の分類・変換日時の設定だけが日本語・日本・CP932(文字コード、別名Windows-31J)になっていて、それ以外はC(C言語のための最低限の情報のみ)になっていることが分かります。日時の形式も日本語にしましょう。利用可能なロケールについてはマニュアルのsetlocale()の項を参照してください。
// setlocale(LC_ALL,'Japanese_Japan')でもよい setlocale(LC_TIME,'Japanese_Japan'); echo strftime('%c'); // 2007/10/16 7:50:06 echo iconv('CP932','UTF-8',strftime('%A, %d %B')); // 火曜日, 16 10月 echo date('l, d F'); // Tuesday, 16 October(dateはロケールによらない)
「Japanese_Japan
」のようなロケールを指定する文字列はOSによって変わることに注意してください。Windows以外のOSでは「ja_JP
」となります(この煩わしさから解放される方法は別の機会に紹介しましょう)。
以下では特に断らない限り、ロケールは「C」つまり「setlocale(LC_ALL,'C')
」が実行されているとします。