The simplest of the regular example: \d{4}-\d{2}-\d{2}
But the reality is not so simple, to consider, the effectiveness and leap years and other issues .....
For a valid range of dates, different scenarios will vary. The valid range of DateTime objects defined in MSDN is: 0001-01-01 00:00:00 to 9999-12-31 23:59:59.
The Unix timestamp is 0 according to the ISO 8601 specification: 1970-01-01t00:00:00z.
First three rules regardless of year, year can be unified writing
(?! 0000) [0-9]{4}
The following only takes into account the month and day of the regular
1. The months of all years, including common year, are inclusive of 1-28 days
(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])
2. All years, including common year, are inclusive of 29 and 30th, except February
(0[13-9]|1[0-2])-(29|30)
3. All years including common year 1, 3, 5, 7, 8, 10, December inclusive of 31st
(0[13578]|1[02])-31)
Together, all dates except February 29 of a leap year
(?! 0000) [0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8]) | ( 0[13-9]|1[0-2])-(29|30) | (0[13578]|1[02])-31)
Next consider the implementation of leap years
1: Four Years a leap
([0-9]{2} (0[48]|[ 2468][048]| [13579] [26])
2: Century does not leap, 400 years again leap
(0[48]| [2468] [048]| [13579] [26]) 00
3: Together is the February 29 of all leap years
([0-9]{2} (0[48]|[ 2468][048]| [13579] [26]) | (0[48]| [2468] [048]| [13579] [26]) 00)-02-29)
Four rules have been implemented and have no effect on each other, together is the regular of all dates that meet the DateTime range
^((?! 0000) [0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8]) | ( 0[13-9]|1[0-2])-(29|30) | (0[13578]|1[02])-31) | ([0-9]{2} (0[48]|[ 2468][048]| [13579] [26]) | (0[48]| [2468] [048]| [13579] [26]) 00)-02-29) $
Given that the regular expression is only used as validation, the capturing group is meaningless, consumes only resources, affects matching efficiency, and can be optimized using non-capturing groups.
^(?:(?! 0000) [0-9]{4}-(?:(?: 0 [1-9]|1[0-2])-(?: 0 [1-9]|1[0-9]|2[0-8]) | (?: 0 [13-9]|1[0-2])-(?: 29|30) | (?: 0 [13578]|1[02])-31) | (?: [0-9]{2} (?: 0 [48]| [2468] [048]| [13579] [26]) | (?: 0 [48]| [2468] [048]| [13579] [26]) 00)-02-29) $
Date regular match PHP super tough