0

I'm trying to write a regular expression that validates a date. The regex needs to match the following formats

  • MM-DD-YYYY
  • MM/DD/YYYY
  • DD-MM-YYYY
  • DD/MM/YYYY
  • YYYY-MM-DD
  • YYYY/MM/DD
  • YYYY-DD-MM
  • YYYY/DD/MM

and should not match formats like DD-MM/YYYY.

I have tried this Regex

'^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$'

but I am only able to extract the dates with mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy format.

I also tried using this (?:\d{2}){1,2}[-|/|.]\d{2}-|/|.{1,2} where I am getting the dates but I am also getting the values like 5542-21-54, 99/01/2019 which does not represent the date.

Thanks, everyone for the help.

Billal Begueradj
  • 20,717
  • 43
  • 112
  • 130
  • Your pattern still [does not match](https://regex101.com/r/sAv0ox/1) a lot of dates. – Wiktor Stribiżew Jun 20 '19 at 16:27
  • Which regex engine/language are you using? – ctwheels Jun 20 '19 at 17:02
  • Maybe you can use [this](https://stackoverflow.com/a/46414732/3600709). I wrote it a while ago, but it does leap years too. You can put together your own datetime formats (you can remove time formats if not needed) by editing the `d_format`, `t_format`, and `dt_format` defined groups. – ctwheels Jun 20 '19 at 17:06
  • https://stackoverflow.com/a/5978549/372239 – Toto Jun 21 '19 at 08:26

1 Answers1

0

If you would like to match days yo need to do this regex:

((1|2)[0-9]|3[0-1]|0?[1-9])

For the month you need:

(0?[1-9]|1[0-2])

For the year you need (only 1900 and 2000, for the 3000 you need maybe to update your script when we will arrive in 2999):

((19|20)?[0-9]{2})

After you have different delimiter and date orders, so:

((1|2)[0-9]|3[0-1]|0?[1-9])\/(0?[1-9]|1[0-2])\/((19|20)?[0-9]{2}) # for DD/MM/YYYY
((1|2)[0-9]|3[0-1]|0?[1-9])\-(0?[1-9]|1[0-2])\-((19|20)?[0-9]{2}) # for DD-MM-YYYY
((19|20)?[0-9]{2})\/((1|2)[0-9]|3[0-1]|0?[1-9])\/(0?[1-9]|1[0-2]) # for YYYY/DD/MM
((19|20)?[0-9]{2})\-((1|2)[0-9]|3[0-1]|0?[1-9])\-(0?[1-9]|1[0-2]) # for YYYY-DD-MM
...

Finally, you need to combine them and have a single match with (expression1|expression2|...):

\W(((1|2)[0-9]|3[0-1]|0?[1-9])\/(0?[1-9]|1[0-2])\/((19|20)?[0-9]{2})|((1|2)[0-9]|3[0-1]|0?[1-9])\-(0?[1-9]|1[0-2])\-((19|20)?[0-9]{2})|((19|20)?[0-9]{2})\/((1|2)[0-9]|3[0-1]|0?[1-9])\/(0?[1-9]|1[0-2])|((19|20)?[0-9]{2})\-((1|2)[0-9]|3[0-1]|0?[1-9])\-(0?[1-9]|1[0-2]))\W

I need the \W at the begining and the end of regex. this one check if you have anything (\s, \;, \,, etc.).

DEMO

You need to complete the missing combinations.

Enjoy ;)

B.Gees
  • 1,125
  • 2
  • 11
  • 28