Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

PHPにおける日付と時刻の混乱

PEARライブラリ活用 (1)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2007/11/06 14:00

PHPには日付や時刻を扱うための手段が複数用意されていて、それらのいずれもが何らかの問題を抱えています。この記事では、PHPで日時を扱う標準的な4つの方法と、それらを使用する上での注意点を紹介します。

目次

はじめに

 作成しているプログラムの中で、ある日付の翌日を取得したいという状況を想像してください。一見単純そうなタスクですが、自分で実装するとなると、かなり面倒だということは容易に想像できます。「日」が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:00JSTというのはタイムゾーンを表しています。デフォルトのタイムゾーンは次のように取得・変更できます。

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%Bstrftime()のフォーマット文字列です。詳細はマニュアルの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')」が実行されているとします。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

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

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2017年5月時点での登録メンバは52名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂き...

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

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:PEARライブラリ活用

もっと読む

All contents copyright © 2005-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5