for 文で日付を回そうと思ったのだけど、以下のようにとんでもないことになってしまった。
<?php for( $date = DateTime::createFromFormat('Y/m/d', '2012/01/01', new DateTimeZone('Asia/Tokyo')), $end = DateTime::createFromFormat('Y/m/d', '2012/12/31', new DateTimeZone('Asia/Tokyo')); $date->diff($end)->format('%R') === '+'; $date->add(new DateInterval('P1D')) ){ // 2012/01/01 から 2012/12/31 まで1日毎に日付を回すfot文 }これはいくらなんでも微妙すぎだと思っていたんだけど、その後DatePeriodクラスというものを知った。
期間を設定してやれば foreach 文で日付を回せるらしい。百聞は一見に如かず。
<?php $start = DateTime::createFromFormat('Y/m/d', '2012/01/01', new DateTimeZone('Asia/Tokyo')); $end = clone $start; // clone でオブジェクトを複製 $end->add(new DateInterval('P1Y')); $period = new DatePeriod($start, new DateInterval('P1D'), $end); foreach($period as $date){ // 2012/01/01 から 2012/12/31 まで1日毎に日付を回すfoteach文 }とってもスッキリして読みやすくなりました。
しかし地味にバグがあって、終了日の時刻が"00:00:00"だと終了日がイテレーションに含まれないらしいです。
バグレポートはされていてオプションで対応するみたいですが、まだ使えないみたいです。
参考: DatePeriod::INCLUDE_END_DATE - ゆっくり*ゆっくり
そのため上記の例では1日毎に日付を回すので+1の 2013/01/01 ということで 1年足しました。
さりげなく DateTime::createFromFormat では作らずに clone でオブジェクトを複製しました。
PHP: オブジェクトのクローン作成 - Manual
細かい説明は抜きに下のコードをhttp://codepad.viper-7.com/で試してみてください。
<?php $date = DateTime::createFromFormat('Y/m/d', '2012/01/01', new DateTimeZone('Asia/Tokyo')); $copy = $date; $copy->add(new DateInterval('P1Y')); echo $date->format('Y/m/d'); // 2013/01/01 echo $copy->format('Y/m/d'); // 2013/01/01 $date = DateTime::createFromFormat('Y/m/d', '2012/01/01', new DateTimeZone('Asia/Tokyo')); $copy = clone $date; $copy->add(new DateInterval('P1Y')); echo $date->format('Y/m/d'); // 2012/01/01 echo $copy->format('Y/m/d'); // 2013/01/01clone を使わないと $copy の変更で $date も変更されてしまっていたでしょう?
つまりそういうことです。
ということで、ちょっと脱線してしまったけど DatePeriod クラスの使い方はこれでおしまい。
綺麗にforeach 文が書けてチョーイイネ!サイコー!