PHP Date and Time
Learn to work with dates in PHP: format with date(), set the timezone, parse strings with strtotime(), and do date math with DateTime.
Almost every web application has to deal with dates and times: timestamps on posts, expiry dates, "3 days ago" labels, scheduling, logging. PHP gives you two complementary tools for this — the procedural date() family of functions for quick formatting, and the object-oriented DateTime class for safer, more powerful date arithmetic.
This chapter shows you how to display the current date, control the timezone, turn human-readable strings into timestamps, and calculate the difference between two dates — along with the gotchas that trip people up.
How PHP represents time
Under the hood, PHP stores a point in time as a Unix timestamp: the number of seconds that have elapsed since midnight UTC on January 1, 1970. time() returns the current timestamp, and most date functions accept one as input:
<?php
echo time(); // e.g. 1750464000 (an integer)
echo date("Y-m-d"); // turns "now" into a readable string
?>A timestamp is timezone-independent — it is the same instant everywhere on Earth. The timezone only matters when you format that instant into a human-readable string, which is why setting the timezone correctly is important (see below).
Basic usage of date()
The date() function turns a timestamp into a formatted string:
date(string $format, ?int $timestamp = null): string$formatis a string of format characters describing how the output should look.$timestampis optional. If you omit it,date()uses the current time.
Here is the current date in dd/mm/yyyy form:
Any character that is not a format code is printed literally, so you can mix in separators and text:
<?php
echo date("l, F j, Y"); // e.g. Saturday, June 21, 2025
echo "\n";
echo date("Y-m-d H:i:s"); // e.g. 2025-06-21 14:30:05
?>Format codes
date() accepts dozens of format characters. These are the ones you will use most often:
| Code | Meaning | Example |
|---|---|---|
d | Day of month, 2 digits | 01 – 31 |
j | Day of month, no leading zero | 1 – 31 |
D | Day name, short | Mon – Sun |
l | Day name, full | Monday – Sunday |
m | Month, 2 digits | 01 – 12 |
n | Month, no leading zero | 1 – 12 |
M | Month name, short | Jan – Dec |
F | Month name, full | January – December |
Y | Year, 4 digits | 2025 |
y | Year, 2 digits | 25 |
H | Hour, 24-hour, 2 digits | 00 – 23 |
h | Hour, 12-hour, 2 digits | 01 – 12 |
i | Minutes, 2 digits | 00 – 59 |
s | Seconds, 2 digits | 00 – 59 |
A | AM / PM | AM, PM |
U | Unix timestamp | 1750464000 |
To print a letter that happens to be a format code (for example a literal H), escape it with a backslash: date('\H:i').
Setting the timezone
date() formats times according to the server's default timezone. Relying on the server default is a common source of "the time is off by a few hours" bugs. Set the timezone explicitly at the top of your script (or in php.ini):
<?php
date_default_timezone_set("America/New_York");
echo date("Y-m-d H:i:s"); // formatted for New York time
?>Use the IANA timezone names such as Europe/London, Asia/Tokyo, or UTC. For an overview of how PHP handles regions and daylight saving time, see the PHP Timezones chapter.
Parsing strings into timestamps
When a date arrives as text — from a form, an API, or a database — strtotime() converts it into a timestamp you can format or do math with. It understands both absolute dates and relative English phrases:
strtotime() is forgiving but ambiguous. A string like 01/02/2022 is read as month/day (American style). For predictable parsing of a known format, prefer DateTime::createFromFormat() (below). When strtotime() cannot understand the input it returns false, so always check the result. See the dedicated strtotime() chapter for the full list of accepted phrases.
The DateTime class
For anything beyond simple display, the object-oriented DateTime API is the modern, recommended approach. It avoids integer-overflow limits, handles timezones cleanly, and makes date math readable:
<?php
$date = new DateTime("2022-01-01 12:00:00");
// Format it
echo $date->format("l, F j, Y"); // Saturday, January 1, 2022
echo "\n";
// Add or subtract durations with DateInterval
$date->modify("+10 days");
echo $date->format("Y-m-d"); // 2022-01-11
?>DateTimeImmutable works the same way but never changes the original object — modify() returns a new instance instead. Prefer it when you pass dates around, so a method called elsewhere cannot silently mutate your value.
Calculating the difference between two dates
DateTime::diff() returns a DateInterval describing the gap between two dates, which is far safer than subtracting raw timestamps:
<?php
$start = new DateTime("2022-01-01");
$end = new DateTime("2022-03-15");
$diff = $start->diff($end);
echo $diff->days . " days total\n"; // 73 days total
echo $diff->format("%m months, %d days"); // 2 months, 14 days
?>For the function-style equivalent, see the date_diff() chapter.
Common gotchas
- The 2038 problem. On 32-bit systems,
date()andstrtotime()work with signed 32-bit integers and break at2038-01-19 03:14:07 UTC.DateTimeis not affected, so use it for far-future or far-past dates. date()is notDate(). PHP function names are case-insensitive, but format codes are case-sensitive:m(month) andM(month name) are different.- Missing timezone warning. Without a configured timezone, older PHP versions emit a warning. Call
date_default_timezone_set()early. strtotime()returnsfalse, not0, on failure — and0is a valid timestamp (the Unix epoch), so test with=== false.
Conclusion
PHP gives you a spectrum of tools for dates and times. Reach for date() and time() for quick formatting, strtotime() to parse incoming strings, and the DateTime / DateTimeImmutable classes for timezone-aware arithmetic and date comparisons. Set your timezone explicitly, validate parsed input, and prefer DateTime whenever you need to add, subtract, or compare dates.
Next, explore the building blocks in depth: the PHP date() function, strtotime(), and PHP Timezones.