Dates7 min readExamples run on PHP 8.5.10

date_get_last_errors()

Learn how date_get_last_errors() reports warnings and errors from the most recent date parse in PHP 8.4, with tested examples and common pitfalls.

Signature

date_get_last_errors(): array|false
Available since PHP 5.3.07.48.08.18.28.38.48.5All versions →

Purpose

date_get_last_errors() tells you what went wrong, or what looked suspicious, the last time PHP parsed a date string. Functions such as date_create() and date_create_from_format() return false when parsing fails, but the boolean says nothing about the reason. This function supplies the details: how many warnings and errors occurred and what the messages were.

It is the procedural alias of DateTimeImmutable::getLastErrors(). Use it when your code is written in the procedural style. Object-oriented code would normally call the static method instead.

Signature

Parameters and defaults

The function takes no parameters, so there is nothing to default. It always inspects the state left behind by the most recent date or time parse.

Return value

When the last parse produced at least one warning or error, you get an array with four keys:

  • warning_count: the number of warnings.
  • warnings: an array of warning messages keyed by the position in the input string where each was noticed.
  • error_count: the number of errors.
  • errors: an array of error messages, also keyed by position.

When the last parse produced neither warnings nor errors, the function returns false. That is the normal result for clean input, so treat false as meaning "nothing to report" rather than as a failure of the function itself. It does not throw exceptions.

Example 1: clean input returns false

A valid string leaves nothing to report.

Example
<?php
date_default_timezone_set('UTC');
$date = date_create('2024-02-29 12:00:00');
var_dump(date_get_last_errors());
Output
bool(false)

Example 2: a warning on an overflowing date

A warning does not stop an object from being created. Parsing 2024-02-31 with a format succeeds, but PHP notes that the date does not exist and rolls it over into March.

Example
<?php
date_default_timezone_set('UTC');
$date = date_create_from_format('Y-m-d', '2024-02-31');
$info = date_get_last_errors();
echo json_encode([
    'created' => $date !== false,
    'warnings' => $info['warning_count'],
    'errors' => $info['error_count'],
    'message' => array_values($info['warnings'])[0],
    'date' => $date->format('Y-m-d'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"created":true,"warnings":1,"errors":0,"message":"The parsed date was invalid","date":"2024-03-02"}

The message is read with array_values() because the warnings are keyed by string position, not by a simple list index. This is how you validate that a date really exists: a created object plus a non-zero warning count means PHP adjusted the value.

Example 3: failures, and state that resets

The reported state belongs to the latest parse only. A later successful parse replaces it.

Example
<?php
date_default_timezone_set('UTC');
$bad = date_create('not a date');
$first = date_get_last_errors();
$good = date_create('2024-01-15');
$second = date_get_last_errors();
echo json_encode([
    'badResult' => $bad,
    'hasErrors' => $first !== false && $first['error_count'] > 0,
    'afterGood' => $second,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"badResult":false,"hasErrors":true,"afterGood":false}

Edge cases

  • Warnings are not failures. A parse can return a usable object and still report warnings, as the overflow example shows. Check both the return value and the error details when strict validation matters.
  • Errors usually mean false. If error_count is greater than zero, the creating function normally returned false, so there is no object to use.
  • Positions are keys. Do not assume warnings[0] exists. Use array_values(), array_key_first() or foreach instead.
  • Only the latest parse counts. Any intervening date parse can overwrite the information, so read it immediately.

Common mistakes

  1. Expecting an array every time. Code like date_get_last_errors()['error_count'] triggers problems when the result is false. Test for false first.
  2. Treating false as a bug. It is the signal for a clean parse.
  3. Reading the details too late. Other date parsing between the call and your check may replace the state.
  4. Ignoring warnings. Checking only that the object exists will let impossible dates such as February 31 slip through silently.
  5. Looking for a parameter. There is none; it cannot be pointed at a specific object.
  • DateTimeImmutable::getLastErrors(): the method this function aliases.
  • date_create() and date_create_immutable(): parse free-form date strings.
  • date_create_from_format(): parse using an explicit format.
  • checkdate(): validate a month, day and year directly.

Recap

date_get_last_errors() takes no arguments and returns either false or an array with warning and error counts and messages from the most recent date parse. Always handle the false case, read the result straight after parsing, and use the warning data to catch dates that PHP accepted only by adjusting them.

Tested examples

Clean input returns false
<?php
date_default_timezone_set('UTC');
$date = date_create('2024-02-29 12:00:00');
var_dump(date_get_last_errors());
Output
bool(false)
A warning on an overflowing date
<?php
date_default_timezone_set('UTC');
$date = date_create_from_format('Y-m-d', '2024-02-31');
$info = date_get_last_errors();
echo json_encode([
    'created' => $date !== false,
    'warnings' => $info['warning_count'],
    'errors' => $info['error_count'],
    'message' => array_values($info['warnings'])[0],
    'date' => $date->format('Y-m-d'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"created":true,"warnings":1,"errors":0,"message":"The parsed date was invalid","date":"2024-03-02"}
Failures, and state that resets
<?php
date_default_timezone_set('UTC');
$bad = date_create('not a date');
$first = date_get_last_errors();
$good = date_create('2024-01-15');
$second = date_get_last_errors();
echo json_encode([
    'badResult' => $bad,
    'hasErrors' => $first !== false && $first['error_count'] > 0,
    'afterGood' => $second,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
{"badResult":false,"hasErrors":true,"afterGood":false}