PHP DateTime accepting invalid date

You have to make use of DateTime::getLastErrors() which will contain the error The parsed date was invalid.

$badDate = '2010-13-03';
$date = DateTime::createFromFormat('Y-m-d', $badDate);
if( DateTime::getLastErrors()['warning_count'] > 0 ){
 //not a correct date
}else{
 //correct date
 print $date->format('Y-m-d');
}

I found example where validation based on DateTime::getLastErrors() will fail, so better solution would be to compare inputed date with generated date.

Code:

function validateDate($date, $format = 'Y-m-d')
{
    $dt = DateTime::createFromFormat($format, $date);
    return $dt && $dt->format($format) == $date;
}

Use example:

var_dump(validateDate('2012-02-28')); # true
var_dump(validateDate('2012-02-30')); # false

# you can validate and date/time format
var_dump(validateDate('14:50', 'H:i')); # true
var_dump(validateDate('14:99', 'H:i')); # false

# this is the example where validation with `DateTime::getLastErrors()` will fail
var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', DateTime::RSS)); # true
var_dump(validateDate('Tue, 27 Feb 2012 12:12:12 +0200', DateTime::RSS)); # false

DateTime::createFromFormat doesn't throw exception/return false when the given date is impossible. It try to guess the expected date.

If you give it '2010-01-32' (as in Januar, 32th), it will return a DateTime object containing Februar, 1st (Januar 31th + 1 day). Must be logical... in some weird twisted way.

To check the validity, you must check the DateTime::getLastErrors() which contains warning, like for my case :

array(4) {
  ["warning_count"]=>
  int(1)
  ["warnings"]=>
  array(1) {
    [10]=>
    string(27) "The parsed date was invalid"
  }
  ["error_count"]=>
  int(0)
  ["errors"]=>
  array(0) {
  }
}

This behavior seems to come from the UNIX timestamp which PHP calculate, based on the year, month and date you give it (even if the date is invalid).

Tags:

Datetime

Php

Date