I\'m trying to check that dates entered by end users are in the YYYY-MM-DD. Regex has never been my strong point, I keep getting a false return value for the preg_match() I
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