I am trying to make a date regex validator. The issue I\'m having is that I\'m using an input field with \"date\"
type, which works like a charm in Chrome; it o
Check and validate YYYY-MM-DD
date in one line statement
function isValidDate($date) {
return preg_match("/^(\d{4})-(\d{1,2})-(\d{1,2})$/", $date, $m)
? checkdate(intval($m[2]), intval($m[3]), intval($m[1]))
: false;
}
See the details in my answer here.
Don't use blindly DateTime::createFromFormat
to validate dates. Let's take non-existent date 2018-02-30
and see:
$d = DateTime::createFromFormat("Y-m-d", "2018-02-30");
var_dump((bool) $d); // bool(true)
Yes, it returns true
, not false
as you may expected. More interesting:
$d = DateTime::createFromFormat("Y-m-d", "2018-99-99");
var_dump((bool) $d); // bool(true)
Also true
... So, it validates just the number of digits. One more try:
$d = DateTime::createFromFormat("Y-m-d", "ABCD-99-99");
var_dump($d); // bool(false)
At last false
.
What is going on here we can see from this snippet:
$d = DateTime::createFromFormat("Y-m-d", "2018-02-30");
var_dump($d);
// var_dump OUTPUT
object(DateTime)#1 (3) {
["date"]=>
string(26) "2018-03-02 16:41:34.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
As you can see when we pass non-existent 2018-02-30
, the DateTime
object contains 2018-03-02
. I assume that it's because February 2018 has 28 days, i.e. the maximum date is 2018-02-28
, and when we pass the day 30
, createFromFormat just adds 30 days to the 2018-02-01
and create new date without any preceding date validation.