tags:

views:

60

answers:

8

Hi There,

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.

Many Thanks

+4  A: 

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
Thibault Falise
It is certainly doable, but it's not going to be pretty.
Tim Pietzcker
@Tim : Yeah, I updated the answer to be more specific ;-)
Thibault Falise
Thanks this solved my problem :)
WizardsSleeve
+1  A: 

You'd probably be better off just doing the format-validation in regex and handling the date-validation separately.

tzaman
+2  A: 

It will be hard, or ugly and a maintenance nightmare, or even impossible.

Just do a check in code after Regex validation.

leppie
+2  A: 

No need to use a regex because there's already a date parsing function: DateTime.ParseExact

Keeper
+1  A: 

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.

Restuta
A: 

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})$
Amarghosh
A: 

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?

Eric
A: 

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
AMissico