Skip to main content

PHP Date Intervals

Introduction

When working with dates and times in PHP, you often need to handle periods or differences between dates. PHP's DateInterval class provides a powerful way to represent time periods - from seconds to years. Whether you need to add 3 months to a date, calculate the difference between two dates, or work with recurring events, DateInterval is your solution.

In this tutorial, you'll learn how to:

  • Create date intervals in different ways
  • Add or subtract intervals from dates
  • Format intervals for display
  • Calculate differences between dates
  • Work with practical examples

Understanding DateInterval Basics

The DateInterval class represents a period of time. It can represent any time span - from 5 seconds to 10 years and everything in between.

Creating DateInterval Objects

There are several ways to create a DateInterval object:

1. Using the Constructor with an Interval Specification

The most common way is using the constructor with an interval specification string:

php
// Create an interval of 2 days, 4 hours and 30 minutes
$interval = new DateInterval('P2DT4H30M');

// Create an interval of 1 year and 6 months
$interval = new DateInterval('P1Y6M');

The interval specification follows the ISO 8601 duration format:

  • It starts with P (for "period")
  • For date parts:
    • Y - years
    • M - months
    • D - days
  • T separates date and time parts
  • For time parts:
    • H - hours
    • M - minutes
    • S - seconds

2. Using the createFromDateString() Method

You can also create an interval using natural language:

php
// Create an interval of 2 weeks
$interval = DateInterval::createFromDateString('2 weeks');

// Create an interval of 3 months and 5 days
$interval = DateInterval::createFromDateString('3 months 5 days');

echo "Months: " . $interval->m; // Outputs: Months: 3
echo "Days: " . $interval->d; // Outputs: Days: 5

3. Using diff() Method Between Two Dates

You can create a DateInterval by finding the difference between two DateTime objects:

php
$date1 = new DateTime('2023-01-01');
$date2 = new DateTime('2023-02-15');

// Get the difference between the two dates
$interval = $date1->diff($date2);

echo "Difference: " . $interval->format('%m months, %d days');
// Outputs: Difference: 1 months, 15 days

DateInterval Properties

Each DateInterval object has properties representing different time units:

php
$interval = new DateInterval('P1Y2M3DT4H5M6S');

echo $interval->y; // 1 (year)
echo $interval->m; // 2 (months)
echo $interval->d; // 3 (days)
echo $interval->h; // 4 (hours)
echo $interval->i; // 5 (minutes)
echo $interval->s; // 6 (seconds)

Additionally:

  • $interval->days - Total number of days (only set when created using diff())
  • $interval->invert - 0 or 1, indicating if the interval is negative

Adding and Subtracting Intervals

You can add or subtract intervals from DateTime objects:

php
$date = new DateTime('2023-01-15');

// Add 1 month and 10 days
$date->add(new DateInterval('P1M10D'));
echo $date->format('Y-m-d'); // Outputs: 2023-02-25

// Subtract 2 weeks
$date->sub(new DateInterval('P14D'));
echo $date->format('Y-m-d'); // Outputs: 2023-02-11

With DateInterval::createFromDateString():

php
$date = new DateTime('2023-01-15');

// Add 3 weeks
$date->add(DateInterval::createFromDateString('3 weeks'));
echo $date->format('Y-m-d'); // Outputs: 2023-02-05

// Subtract 5 days
$date->sub(DateInterval::createFromDateString('5 days'));
echo $date->format('Y-m-d'); // Outputs: 2023-01-31

Formatting DateInterval

The format() method allows you to display intervals in a readable format:

php
$interval = new DateInterval('P1Y2M3DT4H30M');
echo $interval->format('%y years, %m months, %d days, %h hours, %i minutes');
// Outputs: 1 years, 2 months, 3 days, 4 hours, 30 minutes

Format specifiers:

  • %y - Years
  • %m - Months
  • %d - Days
  • %h - Hours
  • %i - Minutes
  • %s - Seconds
  • %R - Sign (+/-)
  • %a - Total days
  • %r - Full period as string (similar to ISO 8601)

Date Differences and Comparison

To calculate the difference between two dates:

php
$birthDate = new DateTime('1990-05-15');
$currentDate = new DateTime('now');

$age = $birthDate->diff($currentDate);

echo "You are " . $age->format('%y years, %m months, and %d days old');
// Outputs something like: You are 33 years, 3 months, and 12 days old

Check if a date interval is negative:

php
$date1 = new DateTime('2023-01-15');
$date2 = new DateTime('2022-12-25');

$interval = $date1->diff($date2);

if ($interval->invert === 0) {
echo "date2 is in the future compared to date1";
} else {
echo "date2 is in the past compared to date1";
// This will be the output in this example
}

DatePeriod: Working with Recurring Intervals

The DatePeriod class works with DateInterval to handle recurring events:

php
// Create a period from today, recurring weekly, for 5 occurrences
$start = new DateTime('now');
$interval = new DateInterval('P1W'); // 1 week
$recurrences = 5;

$period = new DatePeriod($start, $interval, $recurrences);

foreach ($period as $date) {
echo $date->format('Y-m-d') . "<br>";
}
// Outputs 5 dates, each 1 week apart

Practical Examples

Example 1: Subscription Management

Managing subscription periods:

php
function extendSubscription($userId, $extensionPeriod) {
// Get user's current subscription end date from database
// For this example, we'll just create one
$subscriptionEnd = new DateTime('2023-06-30');

// Parse and add the extension period
$interval = DateInterval::createFromDateString($extensionPeriod);
$subscriptionEnd->add($interval);

// Here you would update the database
echo "Subscription extended to: " . $subscriptionEnd->format('Y-m-d');
}

// Usage
extendSubscription(123, '3 months');
// Outputs: Subscription extended to: 2023-09-30

Example 2: Age Verification

Verify if a user is above a certain age:

php
function isOldEnough($birthDate, $minimumAge) {
$birth = new DateTime($birthDate);
$today = new DateTime('today');

$age = $today->diff($birth);

return $age->y >= $minimumAge;
}

// Check if someone born on 2005-05-15 is at least 18 years old
if (isOldEnough('2005-05-15', 18)) {
echo "Access granted to age-restricted content";
} else {
echo "Sorry, you must be at least 18 years old";
}

Example 3: Project Deadline Tracker

Calculate days remaining until deadline:

php
function deadlineStatus($projectDeadline) {
$deadline = new DateTime($projectDeadline);
$today = new DateTime('today');

// If deadline has passed
if ($today > $deadline) {
$interval = $today->diff($deadline);
return "Project is overdue by " . $interval->format('%a days');
} else {
$interval = $today->diff($deadline);
return "Time remaining: " . $interval->format('%a days');
}
}

echo deadlineStatus('2023-12-31');
// Might output: "Time remaining: 245 days"

echo deadlineStatus('2023-01-15');
// Might output: "Project is overdue by 32 days"

Handling Time Zones

When working with intervals across time zones, be aware that some operations can be affected:

php
// Create two dates with different time zones
$date1 = new DateTime('2023-01-15', new DateTimeZone('America/New_York'));
$date2 = new DateTime('2023-01-15', new DateTimeZone('Europe/London'));

// The diff() accounts for the time zone difference
$interval = $date1->diff($date2);
echo "Hour difference: " . $interval->h; // Typically outputs: Hour difference: 5

Common Pitfalls and How to Avoid Them

Pitfall 1: Month-End Behavior

Adding months can lead to unexpected results when dealing with month ends:

php
$date = new DateTime('2023-01-31'); // January 31st
$date->add(new DateInterval('P1M')); // Add 1 month

echo $date->format('Y-m-d'); // Outputs: 2023-02-28
// Note: Not March 3rd but February 28th (or 29th in leap years)

This happens because February doesn't have 31 days, so PHP adjusts to the last day of February.

Pitfall 2: Not Accounting for DST Changes

When working across Daylight Saving Time changes:

php
$date = new DateTime('2023-03-11'); // Day before DST starts in many places
echo $date->format('Y-m-d H:i:s') . "
";

$date->add(new DateInterval('P1D')); // Add 1 day
echo $date->format('Y-m-d H:i:s') . "
";
// The hour will jump forward by 1 due to DST

Summary

PHP's DateInterval class provides powerful tools for working with time periods and date differences:

  • Create intervals using ISO 8601 duration format, natural language, or date differences
  • Add or subtract intervals from dates
  • Format intervals for readable display
  • Calculate precise differences between dates
  • Handle recurring time periods

Mastering date intervals helps you manage time-based features like subscriptions, age verification, deadlines, and scheduling with accuracy and flexibility.

Additional Resources

Exercises

  1. Create a function that calculates a person's age in years, months, and days.
  2. Write code to determine if a given date falls within a specific time range.
  3. Build a subscription system that calculates the next billing date based on different billing cycles (monthly, quarterly, yearly).
  4. Create a function that returns all Mondays between two given dates.
  5. Implement a feature to display "time ago" (e.g., "5 minutes ago", "3 days ago") using DateInterval.


If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)