Dates7 min readExamples run on PHP 8.5.10

date_parse()

Learn how date_parse() breaks a date/time string into an array of parts, relative offsets, warnings and errors without creating a timestamp.

Signature

date_parse(string $datetime): array
Available since PHP 5.2.07.48.08.18.28.38.48.5All versions →

Purpose

date_parse() reads a date/time string and tells you what it found. It applies the same parsing rules as strtotime() and DateTimeImmutable::__construct(), but it does not build a timestamp or an object. It returns an associative array describing the pieces it recognized: year, month, day, time parts, timezone details, relative offsets, and any warnings or errors.

This makes it useful for inspecting user input, for checking whether a string was understood at all, and for learning how PHP interprets a particular format.

Signature

Parameters and defaults

$datetime is the only parameter and it has no default. It accepts any string that DateTimeImmutable::__construct() accepts, such as 2006-12-12 10:00:00.5, June 2nd, 2022 or +1 week.

Return value and failure cases

The function always returns an array. It does not return false for bad input. Instead you inspect two keys:

  • error_count and errors: problems that stop the string from being understood. The keys of errors are positions in the input and the values are messages.
  • warning_count and warnings: less serious issues, also keyed by position.

The errors and warnings arrays can hold fewer entries than their counts, because several problems at the same position share one key. Always trust the count when you only need to know whether something went wrong.

The core keys are year, month, day, hour, minute, second, fraction and is_localtime. A part that was not found is reported as false (or the key may be missing).

When the string contains a timezone, is_localtime is true and a zone_type key appears. Type 1 is a UTC offset and adds zone and is_dst. Type 2 is an abbreviation and adds tz_abbr and is_dst. Type 3 is an identifier such as Europe/London and adds tz_id. The manual's changelog notes that since PHP 7.2.0 the zone value is in seconds, with the sign inverted compared with earlier versions.

If the string has relative parts such as +3 days, the result includes a nested relative array with year, month, day, hour, minute and second, plus weekday or weekdays when needed.

Example 1: an absolute date and time

The fields of a complete string are filled in, and the fractional second is a float.

Example
<?php
$info = date_parse("2006-12-12 10:00:00.5");
echo json_encode([
    $info['year'], $info['month'], $info['day'],
    $info['hour'], $info['minute'], $info['second'],
    $info['fraction'], $info['is_localtime']
]), "\n";
Output
[2006,12,12,10,0,0,0.5,false]

Example 2: a minimal string

When the string has no time, the time parts are reported as false rather than 0. This lets you tell "midnight" apart from "no time given".

Example
<?php
$info = date_parse("June 2nd, 2022");
echo json_encode([
    'year' => $info['year'],
    'month' => $info['month'],
    'day' => $info['day'],
    'hour' => $info['hour'],
    'minute' => $info['minute'],
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"year":2022,"month":6,"day":2,"hour":false,"minute":false}

Example 3: relative parts and timezone identifiers

Relative text such as +1 week +1 hour does not change the absolute fields. It is collected in the relative array. A timezone identifier switches on is_localtime and adds zone_type and tz_id.

Example
<?php
$rel = date_parse("2006-12-12 10:00:00.5 +1 week +1 hour");
echo json_encode($rel['relative'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";

$tz = date_parse("June 2nd, 2022, 10:28:17 Europe/London");
echo json_encode([$tz['is_localtime'], $tz['zone_type'], $tz['tz_id']], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"year":0,"month":0,"day":7,"hour":1,"minute":0,"second":0}
[true,3,"Europe/London"]

Edge cases

  • Some words have side effects. In the manual's example, Thursday, June 2nd leaves year as false, but sets the time to 0:00:00 and adds a relative entry with weekday set to 4. Parsing the same text with DateTimeImmutable::__construct() would also reset the time.
  • A string made only of relative text, like +3 days, leaves the absolute fields as false and fills in relative.
  • The parser describes what it recognized. It does not prove the date exists on the calendar, so use checkdate() when you need to validate a year, month and day combination.
  • Timezone keys are only present if the input included timezone text.

Common mistakes

  1. Expecting false on failure. The function returns an array even for garbage input. Check error_count.
  2. Treating false as 0. An unset hour is false. Use strict comparison (=== false) when you need to distinguish them.
  3. Reading errors by count. Several errors at one position share an array key, so count($info['errors']) may be lower than error_count.
  4. Assuming a fixed format. date_parse() is flexible. If you require an exact layout such as d/m/Y, date_parse_from_format() is the better fit.
  5. Assuming it makes a timestamp. It only reports parts. Use strtotime() or a DateTimeImmutable object when you need a moment in time.
  • date_parse_from_format() parses a string against an explicit format.
  • checkdate() validates a Gregorian year, month and day.
  • getdate() returns details about a timestamp.
  • strtotime() turns a string into a Unix timestamp.

Recap

date_parse(string $datetime): array explains how PHP reads a date/time string. Check error_count and warning_count, remember that missing parts are false, and look in relative for offsets like +1 week. It is a diagnostic and inspection tool, not a validator or a timestamp builder.

Tested examples

Parse an absolute date and time
<?php
$info = date_parse("2006-12-12 10:00:00.5");
echo json_encode([
    $info['year'], $info['month'], $info['day'],
    $info['hour'], $info['minute'], $info['second'],
    $info['fraction'], $info['is_localtime']
]), "\n";
Output
[2006,12,12,10,0,0,0.5,false]
A minimal string leaves time parts false
<?php
$info = date_parse("June 2nd, 2022");
echo json_encode([
    'year' => $info['year'],
    'month' => $info['month'],
    'day' => $info['day'],
    'hour' => $info['hour'],
    'minute' => $info['minute'],
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"year":2022,"month":6,"day":2,"hour":false,"minute":false}
Relative parts and timezone identifier
<?php
$rel = date_parse("2006-12-12 10:00:00.5 +1 week +1 hour");
echo json_encode($rel['relative'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";

$tz = date_parse("June 2nd, 2022, 10:28:17 Europe/London");
echo json_encode([$tz['is_localtime'], $tz['zone_type'], $tz['tz_id']], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"year":0,"month":0,"day":7,"hour":1,"minute":0,"second":0}
[true,3,"Europe/London"]