PHPDates & Times

Dates & Times

Almost every real application eventually has to answer "what time is it?" or "how many days until X?" PHP's oldest answer to that question is a set of procedural functions built around the Unix timestamp — the number of seconds elapsed since midnight UTC on January 1st, 1970. Before reaching for the more powerful DateTime classes, it's worth understanding this procedural layer, because timestamps still show up everywhere: database columns, API payloads, file metadata, and cache expiry logic.

time() and the Unix timestamp

time() takes no arguments and returns the current Unix timestamp as a plain integer. Because it's just a number, timestamps are easy to store, compare, and do arithmetic on — subtracting one timestamp from another gives you a duration in seconds with no extra work.

Getting the current timestamp

PHP
<?php
$now = time();
echo $now, "\n";

$later = $now + 3600; // one hour from now, in seconds
echo $later, "\n";
1735689600
1735693200

Those raw integers aren't very readable, which is where date() comes in — it converts a timestamp into a formatted string using a set of single-letter format characters.

date(): formatting a timestamp

date(string $format, ?int $timestamp = null) accepts a format string built out of special characters, each standing for a piece of the date or time. If you omit the timestamp argument, date() uses the current time, equivalent to calling time() yourself.

Common date() formats

PHP
<?php
$timestamp = 1735689600;

echo date('Y-m-d', $timestamp), "\n";
echo date('Y-m-d H:i:s', $timestamp), "\n";
echo date('D, d M Y', $timestamp), "\n";
echo date('l jS \of F Y', $timestamp), "\n";
2025-01-01
2025-01-01 00:00:00
Wed, 01 Jan 2025
Wednesday 1st of January 2025

Notice the backslash before "of" in the last line — any character in the format string that isn't a recognized format letter is printed literally, but letters that happen to also be format characters (like the "f" hiding inside a word) need to be escaped with a backslash so date() doesn't try to interpret them.

A quick reference for format characters

Character

Meaning

Example

Y

Four-digit year

2025

y

Two-digit year

25

m

Month, zero-padded

01

n

Month, no padding

1

d

Day of month, zero-padded

05

j

Day of month, no padding

5

H

24-hour, zero-padded

09

G

24-hour, no padding

9

i

Minutes, zero-padded

07

s

Seconds, zero-padded

03

D

Short weekday name

Wed

l

Full weekday name

Wednesday

M

Short month name

Jan

F

Full month name

January

strtotime(): parsing human-readable strings

strtotime() goes the other direction — it takes a string written in a loosely English, human-friendly format and tries to parse it into a Unix timestamp. It's surprisingly capable with relative phrases, which makes it convenient for quick scripts, though its forgiving nature is also a source of subtle bugs.

Parsing relative and absolute dates

PHP
<?php
echo date('Y-m-d', strtotime('2025-03-15')), "\n";
echo date('Y-m-d', strtotime('next Monday')), "\n";
echo date('Y-m-d', strtotime('+2 weeks')), "\n";
echo date('Y-m-d', strtotime('first day of next month')), "\n";

$result = strtotime('not a real date');
var_dump($result);
2025-03-15
2025-03-17
2025-03-29
2025-04-01
bool(false)

When strtotime() can't make sense of the input, it returns false rather than throwing an error, so any code that feeds user-supplied strings into it should explicitly check the return value before passing it along to date() — formatting false as a timestamp silently coerces it to 0, which is January 1st, 1970, not an error you'll notice right away.

Doing date arithmetic by hand is fragile
It's tempting to compute "30 days from now" as `time() + 30 * 86400` and mostly get away with it, but that shortcut quietly breaks around daylight saving time transitions in timezones that observe them, and it gets error-prone fast once you need to add months or years, since months don't have a fixed number of seconds. Prefer `strtotime('+30 days')` for simple cases, and reach for the `DateTime`/`DateInterval` classes for anything more involved.
checkdate(): validating a calendar date

Before trusting user input as a real calendar date, checkdate(int $month, int $day, int $year) verifies that the combination actually exists — catching things like February 30th or a day count that ignores leap years.

Validating month, day, and year

PHP
<?php
var_dump(checkdate(2, 29, 2024)); // 2024 is a leap year
var_dump(checkdate(2, 29, 2023)); // 2023 is not
var_dump(checkdate(13, 1, 2025)); // month 13 doesn't exist
bool(true)
bool(false)
bool(false)
Why procedural functions eventually fall short

date(), time(), and strtotime() cover a lot of ground, but they all revolve around plain integers and strings with no object to hold onto. That becomes awkward once a program needs to carry a "date" around as a value — pass it into functions, compare two dates for equality, or perform a chain of calculations like "add three months, then subtract five days, then find the difference from another date." Doing that with raw timestamps means constantly converting back and forth between strings and integers and re-deriving components like "day of week" by hand. PHP's DateTime and DateTimeImmutable classes exist specifically to give dates a proper object representation with methods for exactly this kind of arithmetic and comparison.

  • time() returns the current Unix timestamp as a plain integer.

  • date($format, $timestamp) turns a timestamp into a formatted string using single-letter format codes.

  • strtotime($string) parses a human-readable string into a timestamp, returning false on failure.

  • checkdate($month, $day, $year) checks whether a month/day/year combination is a real calendar date.

  • Raw timestamp arithmetic works for seconds and days but gets unreliable for months, years, and DST-aware calculations.

Note
All of these functions operate in whatever timezone PHP is currently configured to use, which is controlled by `date_default_timezone_set()` or the `date.timezone` setting in `php.ini`. Getting that setting wrong is one of the most common sources of "off by a few hours" bugs in PHP applications.
Tip
For quick, one-off scripts and simple display formatting, the procedural functions are perfectly fine and often less verbose than instantiating a `DateTime` object. Reach for the object-oriented API as soon as you need to store a date as a value, perform more than one calculation on it, or compare dates from different sources.