date_interval_format()
Learn how to use PHP's DateInterval::format() method to format the difference between two dates. Format codes, padding, sign handling, and runnable examples.
Introduction
DateInterval::format() turns a date interval — the gap between two moments in time — into a human-readable string. You decide exactly what to show (days, hours, the sign, and so on) by passing a format string built from % placeholders.
This page covers the syntax, every format code, the all-important difference between %a and %d, how padding and the sign work, and several runnable examples.
What is a DateInterval?
A DateInterval represents a span of time (for example "1 year, 3 months, 12 days"), not a specific date. You almost always obtain one from DateTime::diff(), which subtracts one date from another:
<?php
$start = new DateTime('2022-03-03 00:00:00');
$end = new DateTime('2023-06-15 14:30:00');
$interval = $start->diff($end); // returns a DateInterval object
echo $interval->format('%y years, %m months, %d days');1 years, 3 months, 12 daysformat() is the method that renders that object as a string. (You can also build intervals directly with the DateInterval constructor or apply them to dates with DateTime::add() and DateTime::sub().)
Syntax
public DateInterval::format(string $format): string$format— a string containing literal text plus%format codes.- Returns the formatted interval as a string.
Any character that is not part of a % code is printed literally, so %d days produces something like 12 days. To print a literal percent sign, use %%.
%a vs %d — the most common gotcha
These two look similar but mean different things:
%ais the total number of days across the whole interval.%dis the days left over after whole years and months are accounted for.
<?php
$start = new DateTime('2022-03-03');
$end = new DateTime('2023-06-15');
$interval = $start->diff($end);
echo $interval->format('%a total days') . "\n"; // every day, counted flat
echo $interval->format('%y y, %m m, %d d') . "\n"; // broken into parts469 total days
1 y, 3 m, 12 dReach for %a when you want a single "how many days apart" number, and %d when you are displaying years/months/days together.
Format codes
| Code | Meaning | Example |
|---|---|---|
%y / %Y | Years (%Y is zero-padded to 2 digits) | 1, 01 |
%m / %M | Months | 3, 03 |
%d / %D | Days within the period | 12, 12 |
%a | Total number of days | 469 |
%h / %H | Hours | 14, 14 |
%i / %I | Minutes | 30, 30 |
%s / %S | Seconds | 5, 05 |
%R / %r | Sign — %R gives +/-, %r gives - or empty | +, - |
%% | A literal % | % |
The lowercase codes give the raw value; the uppercase codes are zero-padded to at least two digits. There is no built-in code for total hours, minutes or seconds — only %a aggregates.
<?php
$start = new DateTime('2022-03-03 00:00:00');
$end = new DateTime('2023-06-15 14:30:05');
$interval = $start->diff($end);
echo $interval->format('Padded: %Y-%M-%D %H:%I:%S');Padded: 01-03-12 14:30:05Example 1: Total days between two dates
Show a signed day count
Output:
+365 days%R prints the sign of the interval and %a prints the total number of days. Because $datetime2 is after $datetime1, the sign is +. Swap the two dates (or use diff() the other way) and %R becomes -.
Example 2: Days, hours and minutes
Combine several units in one string
Output:
+365 days 00 hours 00 minutesThe times are both midnight, so the hours and minutes are zero. Note they still print as 00 because %h and %i already pad single-digit results that are zero — but for values 1–9 the lowercase codes are not padded; use %H / %I if you always want two digits.
When would I use this?
- "Member since" / "X days ago" labels — compute the difference with
diff(), then format%a days. - Countdowns — show
%d days %h hours %i minutesuntil a deadline. - Duration reports — render a stored
DateInterval(e.g. a task duration) for a UI or invoice.
To format an actual date or time instead of an interval, use DateTime::format() or the procedural date() function — they share a completely different placeholder set from DateInterval::format().
Conclusion
DateInterval::format() renders the gap between two dates using %-prefixed codes. Remember the two key rules: %a is the total day count while %d is the leftover days, and uppercase codes zero-pad while lowercase ones do not. For more on producing the interval in the first place, see DateTime::diff().