PHP date() & strtotime()

Interactive reference: test format strings, look up parameters, and try strtotime() expressions.

date(" ")
{{ dateResult }}
<?php echo date("{{ dateFormat }}"); ?>
{{ __t('th_character') }} {{ __t('th_description') }} {{ __t('th_example') }}
strtotime(" ")
{{ strtotimeResult.timestamp }}
{{ strtotimeResult.formatted }}
{{ strtotimeResult.relative }}
{{ strtotimePhpCode }}
{{ __t('alert_expression_not_recognized') }}
{{ cat.title }}
{{ __t('th_expression') }} {{ __t('th_description') }} {{ __t('label_result') }}
{{ ref.expr }} {{ ref.desc }} {{ getStrtotimeExample(ref.expr) }}

PHP date() — Format Parameters

The function date(string $format, ?int $timestamp = null) formats a Unix timestamp or the current time into a readable string. The format string consists of placeholders like Y (four-digit year), m (month with leading zero), d (day) or H:i:s (hours:minutes:seconds in 24h format).

PHP strtotime() — Relative Time Expressions

strtotime(string $datetime, ?int $baseTimestamp = null) converts English text descriptions into Unix timestamps. Typical inputs: "now", "+1 day", "next monday", "first day of next month", "last day of december 2025". The function is extremely flexible and also understands combined expressions like "+2 weeks 3 days".

How date() works internally

date(string $format, ?int $timestamp = null): string has been a wrapper around libc time functions since PHP 4, but it is completely re-implemented internally so that every format letter works the same across platforms. Without a timestamp, PHP calls time(), which returns the current Unix timestamp (seconds since 1970-01-01T00:00:00Z). Output is always in the script's default timezone, set via date_default_timezone_set() or the date.timezone INI directive. With no value set, PHP 5.4+ falls back to UTC, a common source of bugs in locally-developed applications.

The format letters originate from the ISO standard for date output formats and are intentionally case-sensitive: m is the month number with leading zero (01-12), M is the three-letter English month name (Jan), n is the month number without leading zero. To output a literal letter, escape it with a backslash — date('\W\o\c\h\e W') produces Woche 23. Beware of confusion: Y is the four-digit year, y is the two-digit year, o is the ISO-8601 week-numbering year, which can differ from Y by one at year boundaries. That difference is the famous "December 31 shows the wrong year" bug.

Since PHP 5.5 the modern recommendation is DateTimeImmutable with format() — it accepts exactly the same format letters but is thread-safe, carries its own timezone and supports microseconds (u) and milliseconds (v). strtotime() in contrast is a standalone parser that translates natural-language time expressions into a Unix timestamp. It follows GNU date's "Date Input Formats" syntax with extensions — and is notorious for ambiguity: strtotime('15/10/2024') is read as October 15 (slash interpreted as US format with day and month swapped?), strtotime('2024-15-10') returns false. For unambiguous input, use DateTimeImmutable::createFromFormat() instead.

The most important format letters

These letters cover 95 % of all real-world applications. The complete list is in the PHP manual (php.net/manual/en/datetime.format.php).

  • Day: d (01-31, padded), j (1-31, unpadded), D (Mon-Sun), l (Monday-Sunday), N (1-7 ISO weekday).
  • Month: m (01-12), n (1-12), M (Jan-Dec), F (January-December), t (days in month, 28-31).
  • Year: Y (2024), y (24), o (ISO-8601 week-numbering year — beware year boundaries), L (1 if leap year).
  • Time: H (00-23), G (0-23), h (01-12), g (1-12), i (00-59 minute), s (00-59 second), a (am/pm), A (AM/PM), v (milliseconds).
  • Timezone & composites: e (Europe/Berlin), O (+0200), P (+02:00), T (CEST), c (ISO 8601), r (RFC 2822), U (Unix seconds).

Common Formats

  • date("Y-m-d") — ISO date: 2025-03-15
  • date("d.m.Y") — German format: 15.03.2025
  • date("Y-m-d H:i:s") — MySQL Datetime
  • date("c") — ISO 8601: 2025-03-15T14:30:00+01:00
  • date("r") — RFC 2822: Sat, 15 Mar 2025 14:30:00 +0100
  • date("U") — Unix timestamp

Concrete examples from everyday PHP work

These strings show up in many frameworks and standards — copy them and adapt to your use cases.

  • date("Y-m-d H:i:s")2024-06-09 14:32:01. MySQL DATETIME standard, fits into DATETIME/TIMESTAMP columns without further conversion.
  • date("c")2024-06-09T14:32:01+02:00. Full ISO 8601 string with timezone offset — the standard for REST APIs and JSON payloads.
  • date("r")Sun, 09 Jun 2024 14:32:01 +0200. RFC 2822 format used in HTTP Date: headers and email headers.
  • date("d.m.Y")09.06.2024. German standard format, identical to strftime("%d.%m.%Y") (the deprecated counterpart).
  • date("W/o")23/2024. ISO calendar week with the correct week-numbering year — date("W/Y") would be wrong on January 1, 2024 (01/2024 instead of 52/2023).

Known pitfalls

The most common trap is the timezone. PHP uses the date.timezone INI directive — if it is not set, PHP falls back to UTC and your times are shifted by hours. On shared hosting, date_default_timezone_set('Europe/Berlin') at the start of the script is mandatory. Second: strtotime() has unpredictable behaviour on ambiguous input — strtotime('2024-02-30') does not return false but March 1. Third: the Y2038 problem. time() on 32-bit PHP is a signed int32 and overflows on January 19, 2038 at 03:14:08 UTC — all 64-bit PHP builds are safe, but databases with INT columns for timestamps need migration. Fourth: date() has no localization, D and F always return English. For multilingual output you need IntlDateFormatter from the intl extension. Fifth: DST switches — strtotime('+1 day') on a DST night can add 23 or 25 hours instead of 24, because the function operates in local time.

Frequently asked questions about PHP date output

How do I get the current date in German?
date() cannot do it directly — the function always returns D and F in English. Use IntlDateFormatter instead: (new IntlDateFormatter('de_DE', IntlDateFormatter::LONG, IntlDateFormatter::NONE))->format(new DateTimeImmutable()) yields 9. Juni 2024.
What is the difference between date() and DateTime::format()?
Format letters are identical. But date() always operates in the global default timezone, while a DateTime object carries its own timezone. DateTimeImmutable is also thread-safe and is not mutated by modify() calls — for new code, always prefer DateTimeImmutable.
How do I convert a Unix timestamp to a date?
date("Y-m-d H:i:s", $timestamp) or, object-oriented, (new DateTimeImmutable())->setTimestamp($timestamp)->format("Y-m-d H:i:s"). Watch out for timezones: a timestamp is always UTC-based, the formatted output is in the configured zone.
Why does strtotime('2024-02-30') not return false?
Because strtotime() is overflow-tolerant — February 30 is interpreted as "2 days after the 28th", i.e. March 1 or 2 depending on leap year. For strict validation use DateTimeImmutable::createFromFormat('!Y-m-d', $input) with the leading ! and then check DateTime::getLastErrors().
How do I add business days instead of calendar days?
Neither date() nor DateTime::add() know that concept. Pragmatic loop: $d = new DateTimeImmutable(); $days = 5; while ($days > 0) { $d = $d->modify('+1 day'); if ((int)$d->format('N') < 6) $days--; }. You have to subtract holidays yourself because PHP has no built-in list.
Why does the date show the wrong timezone?
In 99 % of cases because date.timezone is not set in php.ini and PHP falls back to UTC. Check what your app uses via date_default_timezone_get() and set date_default_timezone_set('Europe/Berlin') globally in the bootstrap or in php.ini.

Related tools