Question
I have two dates in this format:
$startDate = '2007-03-24';
$endDate = '2009-06-26';
I want to calculate the difference between them and display the result in a readable format like:
2 years, 3 months and 2 days
How can I do this in PHP?
Short Answer
By the end of this page, you will understand how to calculate the difference between two dates in PHP using DateTime and DateInterval. You will learn the correct syntax, how PHP breaks a date gap into years, months, and days, how to format the result, and how to avoid common mistakes such as treating dates as plain strings or manually calculating month lengths.
Concept
PHP provides built-in date tools that make date calculations much easier and safer than manual math. The main idea is:
- Convert date strings into
DateTimeobjects - Compare them using the
diff()method - Read the result from a
DateIntervalobject
This matters because dates are not simple numbers:
- Months have different lengths
- Leap years exist
- Time zones can affect calculations
- Manual subtraction often produces incorrect results
In PHP, this is the usual workflow:
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
The diff() method returns a DateInterval object containing parts such as:
yfor yearsmfor monthsdfor daysdaysfor total number of days
For your example, PHP can represent the difference as:
- 2 years
- 3 months
- 2 days
This is better than trying to split strings or estimate month lengths yourself.
Mental Model
Think of date difference as a calendar-based journey, not simple arithmetic.
If you travel from one date to another, PHP does not just count raw days and guess the rest. Instead, it moves through the calendar in parts:
- First count full years
- Then count remaining full months
- Then count leftover days
So the gap is like saying:
- "I walked 2 full years"
- "Then 3 more full months"
- "Then 2 extra days"
That is why DateTime and diff() are useful: they understand the calendar rules for you.
Syntax and Examples
Basic syntax
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
echo $interval->y . ' years, ' . $interval->m . ' months, and ' . $interval->d . ' days';
Example output
2 years, 3 months, and 2 days
Full beginner-friendly example
<?php
$startDate = '2007-03-24';
$endDate = '2009-06-26';
$start = new DateTime($startDate);
$end = new DateTime($endDate);
$interval = $start->diff($end);
echo $interval->y . ' years, ' . $interval->m . ' months, and ' . $interval->d . ' days';
What this does
new DateTime(...)converts a date string into a date object$start->diff($end)calculates the difference$interval->y,$interval->m, and$interval->dgive the calendar difference parts
Using format() for cleaner output
<?php
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
echo $interval->format('%y years, %m months, and %d days');
This is often cleaner than building the string manually.
Step by Step Execution
Consider this code:
<?php
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
echo $interval->format('%y years, %m months, and %d days');
Step 1: Create the start date
$start = new DateTime('2007-03-24');
PHP creates a DateTime object representing March 24, 2007.
Step 2: Create the end date
$end = new DateTime('2009-06-26');
PHP creates another DateTime object representing June 26, 2009.
Step 3: Calculate the difference
$interval = $start->diff($end);
PHP compares the two dates and creates a DateInterval object.
For this example, that object contains values similar to:
y = 2m = 3d = 2
Step 4: Format the result
echo $interval->format('%y years, %m months, and %d days');
PHP inserts the values into the string and prints:
2 years, 3 months, and 2 days
Important note
This is a calendar difference, not just a raw total-day subtraction. That is why the result is expressed in years, months, and days.
Real World Use Cases
Date difference calculations are common in real applications.
Common examples
- Age calculation: find a person's age from their birth date
- Subscriptions: show how long a user has been subscribed
- Projects: calculate duration between start and end dates
- Booking systems: measure time between reservation dates
- HR software: calculate employee service length
- Reporting tools: show how long ago an event happened
Example: age calculation
<?php
$birthDate = new DateTime('1995-08-10');
$today = new DateTime();
$age = $birthDate->diff($today);
echo 'Age: ' . $age->y . ' years';
Example: membership duration
<?php
$joined = new DateTime('2022-01-15');
$now = new DateTime();
$membership = $joined->diff($now);
echo $membership->format('%y years, %m months, %d days');
Real Codebase Usage
In real PHP projects, developers usually do more than just call diff(). They combine it with validation, formatting, and business rules.
Common patterns
Validation before calculating
<?php
$startDate = '2007-03-24';
$endDate = '2009-06-26';
$start = DateTime::createFromFormat('Y-m-d', $startDate);
$end = DateTime::createFromFormat('Y-m-d', $endDate);
if (!$start || !$end) {
die('Invalid date format.');
}
$interval = $start->diff($end);
This avoids calculating with invalid inputs.
Guard clauses
<?php
function getDateDifference(string $startDate, string $endDate): string
{
$start = DateTime::createFromFormat('Y-m-d', $startDate);
$end = DateTime::createFromFormat('Y-m-d', $endDate);
if (!$start || !$end) {
return 'Invalid date';
}
$interval = $start->diff($end);
return $interval->format('%y years, %m months, %d days');
}
Guard clauses make code safer and easier to read.
Handling reversed dates
<?php
$start = new DateTime('2009-06-26');
$end = new DateTime('2007-03-24');
$interval = $start->diff($end);
echo $interval->invert; // 1 means negative direction
Developers may use invert when order matters.
Human-friendly output
In production code, developers often hide zero values.
Example:
0 years, 0 months, 5 daysbecomes5 days1 years, 1 months, 1 daysbecomes1 year, 1 month, 1 day
This makes the result more natural for users.
Common Mistakes
1. Treating date strings like normal strings
Broken code:
<?php
$start = '2007-03-24';
$end = '2009-06-26';
echo $end - $start;
Why it is wrong:
- These are strings, not date objects
- Subtracting them does not produce a meaningful calendar difference
Use this instead:
<?php
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
2. Assuming every month has the same number of days
Broken idea:
<?php
$totalDays = 824;
$months = $totalDays / 30;
Why it is wrong:
- Months can have 28, 29, 30, or 31 days
- This gives approximate values, not true calendar differences
3. Using the wrong date format
Broken code:
<?php
$date = DateTime::createFromFormat('d-m-Y', '2007-03-24');
Why it is wrong:
- The string is
Y-m-d, notd-m-Y - PHP may fail or misread the date
Correct version:
<?php
$date = DateTime::createFromFormat('Y-m-d', '2007-03-24');
4. Confusing d with total days
Important difference:
$interval->d= leftover days after years and months are removed$interval->days= total number of days between the dates
Example:
<?php
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
echo $interval->d; // leftover day part
echo $interval->days; // total days
5. Forgetting that order can matter
<?php
$start = new DateTime('2009-06-26');
$end = new DateTime('2007-03-24');
$interval = $start->diff($end);
echo $interval->invert;
If dates are reversed, invert can show that the interval is negative.
Comparisons
| Approach | Best for | Pros | Cons |
|---|---|---|---|
DateTime + diff() | Most date difference tasks | Accurate, built-in, calendar-aware | Slightly more code than simple subtraction |
| Unix timestamps | Total seconds or days | Good for exact time differences | Not ideal for years/months/days calendar output |
| Manual string parsing | Rarely recommended | Can help in learning formats | Easy to get wrong |
DateInterval parts vs total days
| Value | Meaning |
|---|---|
$interval->y | Year part of the difference |
$interval->m | Month part after years are removed |
$interval->d | Day part after years and months are removed |
$interval->days | Total number of days between the dates |
diff() vs timestamp subtraction
<?php
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
echo $interval->format('%y years, %m months, %d days');
vs
<?php
$days = (strtotime('2009-06-26') - strtotime('2007-03-24')) / 86400;
echo $days;
Use:
diff()when you want years, months, and days- timestamp subtraction when you want raw total time difference
Cheat Sheet
Quick syntax
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
Useful properties
$interval->y; // years
$interval->m; // months
$interval->d; // days
$interval->days; // total days
$interval->invert; // 1 if negative, 0 if positive
Quick formatting
echo $interval->format('%y years, %m months, %d days');
Parse known format safely
$start = DateTime::createFromFormat('Y-m-d', '2007-03-24');
Remember
- Use
DateTimefor date math - Use
diff()for calendar-aware differences dis not the same as total days- Avoid manual month calculations
- Validate input format when dates come from users or APIs
FAQ
How do I calculate the difference between two dates in PHP?
Use DateTime objects and the diff() method:
$start = new DateTime('2007-03-24');
$end = new DateTime('2009-06-26');
$interval = $start->diff($end);
How do I get years, months, and days separately in PHP?
Read them from the DateInterval object:
$interval->y;
$interval->m;
$interval->d;
What is the difference between $interval->d and $interval->days?
$interval->dis the remaining day part$interval->daysis the full total number of days between the dates
Can I calculate date differences using strtotime()?
Yes, but it is better for total seconds or days. For calendar-based output like years, months, and days, DateTime::diff() is the better choice.
What happens if the start date is after the end date?
PHP still calculates the interval, and $interval->invert will indicate the direction.
How do I format the interval as text in PHP?
Use:
echo $interval->format('%y years, %m months, %d days');
Is DateTime better than manual subtraction?
Yes. It correctly handles month lengths, leap years, and calendar rules.
Mini Project
Description
Build a small PHP utility that accepts two dates and prints a human-readable difference such as 2 years, 3 months, 2 days. This demonstrates how to parse date input, validate it, calculate a difference with DateTime::diff(), and format the result cleanly.
Goal
Create a reusable PHP function that returns the difference between two Y-m-d dates in a readable format.
Requirements
- Accept two date strings in
Y-m-dformat. - Validate both dates before calculating the difference.
- Return the result as years, months, and days.
- Handle reversed dates safely.
- Print an error message if either date is invalid.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.