手を動かして覚えるPHP 5.3新機能 日付(DateTime,DateInterval)編

PHP
Students and Teacher in a Classroom at Cathedral High School in New Ulm, Minnesota...
重要なことだから最初に伝えておくと、PHP5.3からは日付や時間の計算にUNIXTIMEなんて使わないでね。
2038年問題とかパッとみて、「これ何日間なの?」とか計算するのは、さよならしましょう。
手元にPHP5.3環境がある人は、インタラクティブモードを利用して実践しながら読むことをおすすめします。
さぁ、コンソールをひらいて、下記のコマンドを実行しましょう。

$ php -a
スポンサーリンク

DateTimeオブジェクト

PHP5.3から導入された新機能として、日付に関するオブジェクトが増えました。
それが、DateTimeオブジェクトです。

$now = new DateTime();
echo $now->format("Y-m-d H:i:s") . PHP_EOL;
2010-12-28 23:00:20+09:00

昨日、明日、来週、来月はこんな感じ。

$yesterday = new DateTime("-1 day");
echo $yesterday->format($format) . PHP_EOL;
2010-12-27 23:00:20+09:00
$tomorrow  = new DateTime("1 day");
echo $tomorrow->format($format) . PHP_EOL;
2010-12-29 23:00:20+09:00
$nextWeek  = new DateTime("1 week");
echo $nextWeek->format($format) . PHP_EOL;
2011-01-04 23:00:20+09:00
$nextMonth = new DateTime("1 month");
echo $nextMonth->format($format);
2011-01-28 23:00:20+09:00

もちろん、UNIXTIMEからもDateTimeオブジェクトをつくれるけど注意が必要。

$now = new DateTime('@' . time());
echo $now->format($format) . PHP_EOL;
2010-12-28 14:00:20+00:00

なんと、タイムゾーンがUTCになってしまいます。

$now = new DateTime('@' . time(), new DateTimeZone('Asia/Tokyo'));
echo $now->format($format) . PHP_EOL;
2010-12-28 14:00:20+00:00

引数をつけてもダメです。
インスタンスがつくられてから、あらためてタイムゾーンを設定してください。

$now = new DateTime('@' . time());
$now->setTimezone(new DateTimeZone('Asia/Tokyo'));
echo $now->format($format) . PHP_EOL;
2010-12-28 23:00:20+09:00

DateIntervalオブジェクト

DateTimeオブジェクトが日付をあらわすオブジェクトだとすると、
日付の間隔をあらわすのがDateIntervalオブジェクトです。
今日と1週間後の差分を取得してみます。

$now = new DateTime();
$nextWeek  = new DateTime("1 week");
$interval = $now->diff($nextWeek);
echo $interval->format('%R%d days') . PHP_EOL;
+7 days

DateIntervalオブジェクト単体で生成するには

$interval = DateInterval::createFromDateString("+7 month");

加算処理(add)

今日、1週間後、2週間後を日付の加算処理で求めます。

$now = new DateTime();
$nextWeek  = new DateTime("1 week");
$cloneDateTime = clone $nextWeek;
$twoWeeks = $cloneDateTime->add($interval);
echo $now->format($format) . PHP_EOL;
2010-12-28 23:00:20+09:00
echo $nextWeek->format($format) . PHP_EOL;
2011-01-04 23:00:20+09:00
echo $twoWeeks->format($format) . PHP_EOL;
2011-01-11 23:00:20+09:00

減算処理(sub)

今日、1週間前を日付の減算処理で求めます。

$now = new DateTime();
$cloneDateTime = clone $now;
$weekAgo = $cloneDateTime->sub($interval);
echo $now->format($format) . PHP_EOL;
2010-12-28 23:00:20+09:00
echo $weekAgo->format($format) . PHP_EOL;
2010-12-21 23:00:20+09:00

致し方なくUNIXTIMEをつかうとき…

PHPから他の処理系へ渡す時にどうしてもUNIXTIMEを使わなければならないとき、

$now = new DateTime();
echo $now->format('U') . PHP_EOL;
1292940020

まとめ

PHP5.3からはUNIXTIMEを使うことなく日付時間の処理が可能である。
Propel1.5とDoctrine2もDateTimeインスタンスを返してくるようになる。
DateTimeとDateIntervalを身につけないと、2011年のPHPについていけなくなってしまう。
PHPマニュアルに詳しい内容は書いてある。
PHP5.3がリリースされた当初には、一部不足している内容があったが今は追加されている。

DateTimeオブジェクトのformatは % 必要ないのに、DateInterval は % が必要なんですかね?腹立ちますね!

とか、いろいろアレな点もありますが…。
自分の部下には「パーフェクトPHP」を読んでおいてもらいたい理由5つなど、PHP界隈で絶賛の評価がされているパーフェクトPHPも、もちろんこの内をバッチリ押さえている。

小川 雄大¥ 3,780
タイトルとURLをコピーしました