tags:

views:

530

answers:

5
Q: 

date regex

i am trying to validate a date in c# in the format "yyyy/mm/dd". is it even possible (using regex) to validate that there aren't 30 days in february?

A: 

Probably, but the leap year stuff is going to be really hard so you may want to go with something other than a Regex.

tvanfosson
+8  A: 

It is possible to do this with a regex, but it would be incredibly complex. I am quite comfortable writing regular expressions, but I would not use that solution to validate dates.

It's much simpler to use another solution for validating dates. There are date-validation components available for every programming language. I'm not a user of .NET, but with a quick search I find the DateTime class, which seems to do this.

See .NET Framework Developer's Guide, "Parsing Date and Time Strings."

Bill Karwin
I am also very comfortable with regular expressions and love them greatly. However, they are not always the right tool for the job. Bill Karwin's suggestion is much more appropriate for this task than are regular expressions.
Dinah
+1. Writing your own regex for dates would be mind bogglingly annoying. You're much better off using DateTime with the built-in localization options.
SnOrfus
A: 

Yes, it's possible, but it gets rather lengthy. The pattern just for checking months and days has quite some variations, and it all has to be repeated for leap years.

As an example, here's a pattern from Michael Ash's Regex Blog for mm/dd/yyyy format:

^(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
Guffa
Yay Regex Blog! aka The Daily Argh-My-Eyes!
bobince
+7  A: 

As others have said, a regex isn't the best approach unless you're forced to (e.g. for client-side JavaScript reasons).

I suggest you use DateTime.TryParseExact with a pattern of "yyyy/MM/dd".

Jon Skeet
A: 

It is possible to do that. It is even possible to do that for for leap years, but that would be complex.

A simple expression for this date format:

^\d{4}/\d{2}/\d{2}$

A more complex expression that considers the number of days per month (but the feburary still allows 29 days in every year):

^\d{4}/(?:02/(?:0[1-9]|[12]\d)|(?:0[13578]|1[02])/(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)/(?:0[1-9]|[12]\d|30))$

But it would probably easier to do this with a build-in C# function.

Gumbo