導入
業務システムにおいて、カレンダー生成や営業日計算、あるいは特定の曜日のみを対象としたスケジュール管理機能の実装は頻出タスクです。「特定の日付から一年間の土日を抽出したい」といったケースでは、単なるループ処理以上に、PHPの強力な日付操作クラスである DateTime クラスを活用することが、メンテナンス性と正確性の向上につながります。本記事では、DateTime と DatePeriod を活用した、モダンで効率的な特定曜日の抽出方法を解説します。
基礎知識
PHPで日付を扱う際、昔ながらの date() 関数や mktime() 関数を使うのは推奨されません。現在は DateTime、DateTimeImmutable、DateInterval、そして DatePeriod を組み合わせるのが標準です。
DateTimeImmutable を使うと、オブジェクトの書き換えを防ぎ、副作用のない堅牢なコードが書けます。また、DatePeriod を活用すれば、ループの開始と終了、間隔を定義するだけで簡単に日付のリストを生成できます。
実装/解決策
特定曜日を抽出する際、閏年の判定を自前で行うのはバグの元です。DatePeriod を使い、期間の終端を「翌年の元旦」に設定することで、閏年か平年かを意識せずにループを完結させることができます。以下の実装では、指定した期間内で特定の曜日にマッチする日付を抽出します。
サンプルプログラム
format(‘w’), $targetDays)) {
// 条件に一致する日付を配列に格納
$result[] = $date->format(“Y-m-d (D)”);
}
}
// 結果の出力
foreach ($result as $day) {
echo $day . PHP_EOL;
}
応用・注意点
現場でこの処理を実装する際、以下の点に注意してください。
1. タイムゾーンの明示
サーバーの設定に依存しないよう、DateTime インスタンス作成時は必ず明示的にタイムゾーンを指定しましょう。`new DateTimeImmutable(‘now’, new DateTimeZone(‘Asia/Tokyo’))` のように記述するのが鉄則です。
2. パフォーマンスへの配慮
今回のように一年分程度であれば問題ありませんが、数十年単位の広範囲なループを処理する場合、配列に全データを詰め込むとメモリ消費が増大します。必要に応じてジェネレータ(yield)を使用して、逐次処理を行う設計に変更してください。
3. 祝日との兼ね合い
実務では「土日」だけでなく「祝日」を除外したいケースがほとんどです。その場合は、別途祝日リストの配列または外部APIを用意し、`in_array` で判定する条件に含めることで、より実用的な営業日計算ロジックへ発展させることができます。