Signature
date_parse(string $datetime): arrayPurpose
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_countanderrors: problems that stop the string from being understood. The keys oferrorsare positions in the input and the values are messages.warning_countandwarnings: 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.
$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";[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".
$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";{"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.
$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";{"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 2ndleavesyearasfalse, but sets the time to0:00:00and adds arelativeentry withweekdayset to4. Parsing the same text withDateTimeImmutable::__construct()would also reset the time. - A string made only of relative text, like
+3 days, leaves the absolute fields asfalseand fills inrelative. - 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
- Expecting
falseon failure. The function returns an array even for garbage input. Checkerror_count. - Treating
falseas0. An unset hour isfalse. Use strict comparison (=== false) when you need to distinguish them. - Reading
errorsby count. Several errors at one position share an array key, socount($info['errors'])may be lower thanerror_count. - Assuming a fixed format.
date_parse()is flexible. If you require an exact layout such asd/m/Y,date_parse_from_format()is the better fit. - Assuming it makes a timestamp. It only reports parts. Use
strtotime()or aDateTimeImmutableobject when you need a moment in time.
Related functions
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
$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";
[2006,12,12,10,0,0,0.5,false]
$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";
{"year":2022,"month":6,"day":2,"hour":false,"minute":false}
$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";
{"year":0,"month":0,"day":7,"hour":1,"minute":0,"second":0}
[true,3,"Europe/London"]