PHPで日付を扱う際、特定の期間内の日付をループさせて処理したい時があります。これを素朴な$i = 0; $i < $n; $i++;
的な数字ループでやろうとすると月をまたぐ時に苦労します。日時オブジェクトを使うことで実は簡単にできます。この記事ではその方法を紹介します。
具体的には次のようにして特定の範囲内の日付ループを書けます。
<?php $startDate = new DateTime('2024-08-15'); // 開始日 $endDate = new DateTime('2024-09-10'); // 終了日 for ($date = $startDate; $date <= $endDate; $date->modify('+1 day')) { echo $date->format('Y-m-d') . "\n"; }
PHP組み込みクラスであるDateTimeはオブジェクトですが、その日付の大小関係を比較できます。これと日をずらすメソッドを組み合わせることで日付のforループを書けます。例のコードであれば1日ずつ過不足なく範囲内の日付をechoしてくれます。
PHPには日付の期間や間隔を表現するためのクラスである DatePeriod や DateDateInterval があります。もし一定間隔の日付を扱うことのみが目的ならばこちらを使うのも便利です。これは次のように書けます。
<?php $startDate = new DateTime('2024-08-15'); // 開始日 $endDate = new DateTime('2024-09-10'); // 終了日 // $startDateから1日間隔で$endDateまでの期間 $datePeriod = new DatePeriod($startDate, new DateInterval('P1D'), $endDate); // ↑で定義した期間を出力 foreach ($datePeriod as $date) { echo $date->format('Y-m-d') . "\n"; }
DateTime と for を使う利点として、進み方が不ぞろいのループでも表現できる点があります。例えば次のように、指定した日とその日以降の木曜日を表現できます。このコードのループは2024-09-04(水)、2024-09-05(木)、2024-09-12(木)、…という順で値を処理しています。
<?php $startDate = new DateTime('2024-09-04'); // 開始日 $endDate = new DateTime('2024-10-10'); // 終了日 // 次の木曜日、次の次の木曜日、…とループする for ($date = $startDate; $date <= $endDate; $date->modify('next thursday')) { // ループの初期値の日は木曜日じゃないかもしれないので if でチェック if ($date->format('w') === '4') { // 木曜日の日付を出力 echo $date->format('Y-m-d'), PHP_EOL; } }
また時刻を使うこともできます。次の例では7時間ずつ進めています。
<?php $start = new DateTime('2024-09-04 09:00:00'); // 開始日時 $end = new DateTime('2024-09-07 00:00:00'); // 終了日時 // 7時間ずつ進める for ($date = $start; $date < $end; $date->modify('+7 hours')) { echo $date->format('Y-m-d H:i:s'), PHP_EOL; } /* 2024-09-04 09:00:00 2024-09-04 16:00:00 2024-09-04 23:00:00 2024-09-05 06:00:00 2024-09-05 13:00:00 2024-09-05 20:00:00 2024-09-06 03:00:00 2024-09-06 10:00:00 2024-09-06 17:00:00 */
こんな感じで日付をいい感じに繰り返し処理できます。例には出しませんでしたが年単位、月単位でももちろん使えます。暦は複雑であり暦の操作を手計算で行うと何かミスしやすいです。PHPのDateTimeやDatePeriodを使えば、煩雑な日付計算もシンプルに行えます。これらを活用することで、さまざまな間隔や条件に応じた日付のループ処理が柔軟に実現できるでしょう。