Interactive reference: test format strings, look up parameters, and try strtotime() expressions.
{{ dateResult }}
<?php echo date("{{ dateFormat }}"); ?>
| {{ __t('th_character') }} | {{ __t('th_description') }} | {{ __t('th_example') }} | |
|---|---|---|---|
| {{ group.title }} | |||
{{ p.char }} |
{{ p.desc }} | {{ getParamExample(p.char) }} | |
{{ strtotimeResult.timestamp }}
{{ strtotimeResult.formatted }}
{{ strtotimeResult.relative }}
{{ strtotimePhpCode }}
| {{ __t('th_expression') }} | {{ __t('th_description') }} | {{ __t('label_result') }} |
|---|---|---|
{{ ref.expr }} |
{{ ref.desc }} | {{ getStrtotimeExample(ref.expr) }} |
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).
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".
date() works internallydate(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.
These letters cover 95 % of all real-world applications. The complete list is in the PHP manual (php.net/manual/en/datetime.format.php).
d (01-31, padded), j (1-31, unpadded), D (Mon-Sun), l (Monday-Sunday), N (1-7 ISO weekday).m (01-12), n (1-12), M (Jan-Dec), F (January-December), t (days in month, 28-31).Y (2024), y (24), o (ISO-8601 week-numbering year — beware year boundaries), L (1 if leap year).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).e (Europe/Berlin), O (+0200), P (+02:00), T (CEST), c (ISO 8601), r (RFC 2822), U (Unix seconds).date("Y-m-d") — ISO date: 2025-03-15date("d.m.Y") — German format: 15.03.2025date("Y-m-d H:i:s") — MySQL Datetimedate("c") — ISO 8601: 2025-03-15T14:30:00+01:00date("r") — RFC 2822: Sat, 15 Mar 2025 14:30:00 +0100date("U") — Unix timestampThese 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).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.
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.date() and DateTime::format()?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.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.strtotime('2024-02-30') not return false?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().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.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.