Generating Recurring Dates with PHP DatePeriod
Managing recurring events like weekly newsletters, monthly billing
cycles, or annual anniversaries is a common task in web development.
This article provides a straightforward guide on how to use PHP’s
built-in DatePeriod class to easily generate a series of
recurring dates. You will learn how to configure the class using
DateTime and DateInterval objects, control the
number of recurrences, and exclude start dates through practical,
ready-to-use code examples.
Understanding the DatePeriod Class
The DatePeriod class allows you to traverse through a
set of dates that recur at regular intervals over a given period. To
create a DatePeriod instance, you need three main
components:
- Start Date: A
DateTimeorDateTimeImmutableobject marking the beginning of the period. - Interval: A
DateIntervalobject representing the duration between each recurrence (e.g., daily, weekly, monthly). - End Point: This can be either an end
DateTimeobject or an integer specifying the number of recurrences.
Method 1: Generating Dates Using a Start and End Date
If you know the exact start and end dates of your schedule, you can
pass both dates along with the interval to the DatePeriod
constructor.
The following example generates a weekly schedule for the month of October:
<?php
$start = new DateTime('2024-10-01');
$interval = new DateInterval('P1W'); // Interval of 1 week (P = Period, 1W = 1 Week)
$end = new DateTime('2024-11-01');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
echo $date->format('Y-m-d') . "\n";
}Output:
2024-10-01
2024-10-08
2024-10-15
2024-10-22
2024-10-29
Note: The end date is exclusive by default. If the last recurrence falls exactly on the end date, it will not be included in the output.
Method 2: Generating Dates Using a Number of Recurrences
If you want to generate a specific number of recurring events rather
than defining an end date, you can pass an integer as the third argument
instead of an end DateTime object.
The following example generates the next 5 monthly billing dates starting from October 1st:
<?php
$start = new DateTime('2024-10-01');
$interval = new DateInterval('P1M'); // Interval of 1 month (P = Period, 1M = 1 Month)
$recurrences = 5; // Generate 5 additional occurrences
$period = new DatePeriod($start, $interval, $recurrences);
foreach ($period as $date) {
echo $date->format('Y-m-d') . "\n";
}Output:
2024-10-01
2024-11-01
2024-12-01
2025-01-01
2025-02-01
2025-03-01
Excluding the Start Date
By default, the initial start date is included as the first result in
your loop. If you want the recurrences to begin strictly after
the start date, you can pass the flag
DatePeriod::EXCLUDE_START_DATE as the fourth parameter to
the constructor.
<?php
$start = new DateTime('2024-10-01');
$interval = new DateInterval('P2D'); // Every 2 days
$end = new DateTime('2024-10-10');
// Pass the exclusion flag as the fourth argument
$period = new DatePeriod($start, $interval, $end, DatePeriod::EXCLUDE_START_DATE);
foreach ($period as $date) {
echo $date->format('Y-m-d') . "\n";
}Output:
2024-10-03
2024-10-05
2024-10-07
2024-10-09