Reputation: 195
Does anyone have a regurlar expression available which only accepts dates in the format dd/mm/yy but also has strict checking to make sure that the date is valid, including leap year support?
I am coding in vb.net and am struggling to work this one out.
Upvotes: 3
Views: 12838
Reputation: 21684
There is no need to verify the format because the "parse" methods will do this for you. the parse will compare all date format strings in DateTimeFormatInfo
against the string you pass to the method. The parse-exact method will only compare the specified string against the data format strings you pass to the method.
Imports System.Globalization
Module Sample
Public Function IsValidDateString1(ByVal s As String) As Boolean
Return Date.TryParseExact(s, "dd/MM/yy", CultureInfo.InvariantCulture, DateTimeStyles.None, Nothing)
End Function
Public Function IsValidDateString2(ByVal s As String) As Boolean
Static _dateFormats() As String = New String() {"dd/MM/yy", "d/M/yy", "d/M/yyyy"}
Return Date.TryParseExact(s, _dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, Nothing)
End Function
Public Sub Main()
Debug.WriteLine("single")
Debug.WriteLine(IsValidDateString1("31/12/2001")) 'wrong format
Debug.WriteLine(IsValidDateString1("31/12/01"))
Debug.WriteLine(IsValidDateString1("29/2/08")) '<-be careful
Debug.WriteLine(IsValidDateString1("29/ 2/08")) '<-be careful
Debug.WriteLine(IsValidDateString1("29/02/08"))
Debug.WriteLine(IsValidDateString1("29/02/09")) 'invalide date
Debug.WriteLine("multiple")
Debug.WriteLine(IsValidDateString2("31/12/2001"))
Debug.WriteLine(IsValidDateString2("31/12/01"))
Debug.WriteLine(IsValidDateString2("29/2/08"))
Debug.WriteLine(IsValidDateString2("29/ 2/08")) '<-be careful
Debug.WriteLine(IsValidDateString2("29/02/08"))
Debug.WriteLine(IsValidDateString2("29/02/09")) 'invalid date
End Sub
End Module
Upvotes: 0
Reputation: 97591
You're trying to use the regex hammer to solve an eminently non-nail shaped problem.
Would it not be better to extract the numbers using regular expressions, but validate it programatically?
Upvotes: 0
Reputation: 59451
Apart from the fact that such a regex would be a long dirty unmaintainable thing if it existed, you can't even tell for sure if an year in YY
format is a leap year or not. 00
is leap if and only if it is a multiple of 400. 2000 was leap, 1900 wasn't.
The following regex makes sure that date is between 01 and 31, month is between 01 and 12 and year is between 1900 and 2099. Delete the (?:19|20)
part to make it dd/mm/yy
format: then year can be anything from 00 to 99. Do the real validation using standard date-time libraries - use the regex for just client side validations (to save a trip to server - assuming you're doing date-time validation at server), or as a screening test before feeding to the real validator.
^(0[1-9]|[12]\d|3[01])/(0[1-9]|1[0-2])/((?:19|20)\d{2})$
Upvotes: 3
Reputation: 5885
I don't think the leap year support is doable in a regex without using some ugly regex.
You will have to check the date validity after validating input with the regex.
As hinted by Keeper, you could use the DateTime.ParseExact method to validate your date :
Public Function IsValidDate(ByVal dateString As String) As Boolean
Try
DateTime.ParseExact(dateString, "dd/MM/yy", System.Globalization.CultureInfo.InvariantCulture)
Return True
Catch ex As FormatException
Return False
End Try
End Function
Upvotes: 4
Reputation: 5903
I think it is extreamly hard to check whether year leap or not with reqular expression. Please take a look at this article about your problem. Here is a citate from here:
Again, how complex you want to make your regular expression depends on the data you are using it on, and how big a problem it is if an unwanted match slips through. If you are validating the user's input of a date in a script, it is probably easier to do certain checks outside of the regex. For example, excluding February 29th when the year is not a leap year is far easier to do in a scripting language. It is far easier to check if a year is divisible by 4 (and not divisible by 100 unless divisible by 400) using simple arithmetic than using regular expressions.
Upvotes: 2
Reputation: 3566
No need to use a regex because there's already a date parsing function: DateTime.ParseExact
Upvotes: 2
Reputation: 117250
It will be hard, or ugly and a maintenance nightmare, or even impossible.
Just do a check in code after Regex validation.
Upvotes: 2
Reputation: 47790
You'd probably be better off just doing the format-validation in regex and handling the date-validation separately.
Upvotes: 1