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).