date_parse_from_format

Parses a date/time string against a given format and returns its components plus any errors and warnings.

Signature
date_parse_from_format(string $format, string $datetime): array
  • Added in PHP 5.3.0

Parameters

ParameterTypeDescription
$formatstringThe format the string is expected to follow, using the same characters as DateTimeImmutable::createFromFormat().
$datetimestringThe date/time string to parse.

Return value

arrayAn associative array with year, month, day, hour, minute, second and fraction (false when the format did not supply them), timezone details when the format contained a zone, and the error_count, errors, warning_count and warnings elements.

Errors

Throws a ValueError if datetime contains NUL bytes (PHP 8.0.21, 8.1.8 and 8.2.0 onward). Ordinary parse failures are reported in the errors and warnings elements instead.

Changelog

  • PHP 8.0.21Throws a ValueError when datetime contains NUL bytes. Also applies from 8.1.8 and 8.2.0 onwards.
  • PHP 7.2.0The zone element is now the UTC offset in seconds with the natural sign, instead of minutes with an inverted sign.

date_parse_from_format is the strict sibling of date_parse. Instead of guessing at the layout, you state it — 'd/m/Y', 'Y-m-d\TH:i:sP', 'j.n.Y H:iP' — and the function reports how well the string matched.

When to reach for it

Use it for input whose format you control or advertise: a CSV column from a partner, an Y-m-d query parameter, a legacy log file. Ambiguity is the reason. date_parse('03/04/2025') has to guess between 3 April and 4 March; given an explicit 'd/m/Y' there is nothing to guess.

It is also the diagnostic tool for DateTimeImmutable::createFromFormat(). When that constructor returns false or a surprising date, running the same format and string through date_parse_from_format shows you the exact character position where the parser gave up.

Two levels of failure

A string that does not fit the format produces entries in errors. A string that fits but describes an impossible date — 31/02/2025 against 'd/m/Y' — produces no errors at all, only a warning. Validation must check both counters.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Validating a supplier's CSV date column against the exact layout the contract specifies
  • Diagnosing why DateTimeImmutable::createFromFormat returned false for a particular string
  • Rejecting ambiguous input by requiring one specific format instead of letting PHP guess

Frequently asked questions

What is the difference between date_parse and date_parse_from_format?

date_parse guesses the layout from the string, while date_parse_from_format requires you to declare it. Declare the format whenever the input could be ambiguous, such as 03/04/2025.

Why does date_parse_from_format return no errors for an invalid date?

Because the string matched the format even though the date does not exist. Impossible dates such as 31/02/2025 are reported through warning_count, so check that as well.

Should I use this instead of DateTimeImmutable::createFromFormat?

Use createFromFormat when you want an object and date_parse_from_format when you want to know exactly what failed. They use the same format characters, so one is a drop-in diagnostic for the other.

More examples

A strict format validator

04/07/2025 and 4/7/2025 both pass — the d and m format characters accept one or two digits, so zero padding is optional. The ISO string fails outright (four errors), and 31 February matches the layout but is rejected by the warning check.

Example · php
<?php
function matchesFormat(string $format, string $value): bool {
    $p = date_parse_from_format($format, $value);
    return $p['error_count'] === 0 && $p['warning_count'] === 0;
}

foreach (['04/07/2025', '4/7/2025', '2025-07-04', '31/02/2025'] as $value) {
    printf("%-12s %s\n", $value, matchesFormat('d/m/Y', $value) ? 'accepted' : 'rejected');
}

No guessing about day and month order

The same string yields 3 April or 4 March depending on the format you declare. This is why format-driven parsing beats letting PHP guess for anything coming from outside your system.

Example · php
<?php
$value = '03/04/2025';

$dmy = date_parse_from_format('d/m/Y', $value);
$mdy = date_parse_from_format('m/d/Y', $value);

printf("as d/m/Y: %04d-%02d-%02d\n", $dmy['year'], $dmy['month'], $dmy['day']);
printf("as m/d/Y: %04d-%02d-%02d\n", $mdy['year'], $mdy['month'], $mdy['day']);
echo 'date_parse guessed: ', date_parse($value)['month'], "\n";

Locating a parse failure

The errors array is keyed by character offset, pointing at exactly where the input ran out. createFromFormat only tells you false, so this is the faster way to see what went wrong.

Example · php
<?php
$p = date_parse_from_format('Y-m-d H:i:s', '2025-07-04 14:30');

echo 'error_count: ', $p['error_count'], "\n";
foreach ($p['errors'] as $position => $message) {
    echo "at offset {$position}: {$message}\n";
}
var_dump(DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2025-07-04 14:30'));

Discussion

  • Be the first to comment on this lesson.