1

I want to validate a string to see if it is a valid date in the format YYYY-MM-DD. I'm not very good with regex, but I've managed to get it to validate strings with four 0-9 characters in the beginning followed by the hyphen, followed by two 0-9 chars, another hyphen, and two more 0-9 chars in the end. How could I make this regex match dates with only 1-12 in the month and 1-31 in the day?

Here's what I have so far:

([0-9]{4})-([0-9]{2})-([0-9]{2}) 
4
  • Leading zeros required? Commented Jul 20, 2014 at 23:22
  • Yes. The leading zeros are required. Commented Jul 20, 2014 at 23:25
  • Related: Regular Expression: Numeric range Commented Jul 20, 2014 at 23:54
  • FYI I've tested all three answers, the regexes are different but they all work. :) Commented Jul 20, 2014 at 23:57

2 Answers 2

1

A simple way:

$pattern = '~\A(\d{4})-(\d{2})-(\d{2})\z~'; if (preg_match($pattern, $str, $m) && checkdate($m[2], $m[3], $m[1])) { // TRUE } else { // FALSE } 

The advantage is that checkdate checks if the date exists (including cases of leap years). With this approach, there's no need to delegate more tasks to the regex part.

Sign up to request clarification or add additional context in comments.

Comments

0

Anchors First

The most important thing in this validation is that you use the ^ and $ anchors to prevent a substring from matching in the middle of your input.

As for the regex, this is what I would suggest (assuming years start with a 1 or 2)

^([12][0-9]{3})-(0[1-9]|1[012])-([012][1-9]|[123]0|31)$ 

This regex demo tests the day part of the regex, while this other demo tests the month part.

Explanation

  • The ^ anchor asserts that we are at the beginning of the string
  • For the year, [12][0-9]{3} matches a 1 or 2 followed by three digits
  • For the month, (0[1-9]|1[012] matches 0 then 1 through 9, or 1 then 0, 1 or 2
  • For the day, [012][1-9]|[123]0|31 matches a 0, 1 or 2 followed by a digit from 1 to 9, or 1, 2 or 3 followed by a 0, or 31
  • The $ anchor asserts that we are at the end of the string

1 Comment

FYI: after tweaking added a demo to test the month part of the regex, and a demo to test the day.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.