It's probably better to use another mechanism for this.
The modern solution, with DateTime
:
$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());
This validates the input too: $dt !== false
ensures that the date can be parsed with the specified format and the array_sum
trick is a terse way of ensuring that PHP did not do "month shifting" (e.g. consider that January 32 is February 1). See DateTime::getLastErrors()
for more information.
Old-school solution with explode
and checkdate
:
list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);
This validates that the input is a valid date as well. You can do that with a regex of course, but it's going to be more fuss -- and February 29 cannot be validated with a regex at all.
The drawback of this approach is that you have to be very careful to reject all possible "bad" inputs while not emitting a notice under any circumstances. Here's how:
explode
is limited to return 3 tokens (so that if the input is "1-2-3-4", $d
will become "3-4")ctype_digit
is used to make sure that the input does not contain any non-numeric characters (apart from the dashes)array_pad
is used (with a default value that will cause checkdate
to fail) to make sure that enough elements are returned so that if the input is "1-2" list()
will not emit a notice