Nuts
Nuts

Reputation: 2813

VB.NET TryParse returns False although a valid date passed

I created a function in VB.NET that checks for valid dates. The function is below:

Public Shared Function IsDate(obj As [Object]) As Boolean
        Dim strDate As String = obj.ToString()
        Dim dt As DateTime = DateTime.MinValue

        If DateTime.TryParse(strDate, dt) AndAlso dt <> DateTime.MinValue AndAlso dt <> DateTime.MaxValue Then
            Return True
        Else
            Return False
        End If
    End Function

I pass a value to that function that I think is a valid date. My test value is 49278 that should correspond to a date of 30th Nov 2034.

My function however tells this is NOT a valid date. I cannot get why.

enter image description here

What is happening here?

Upvotes: 0

Views: 1400

Answers (2)

Matt Wilko
Matt Wilko

Reputation: 27342

That value is an "OLE Automation Date" as used by Excel etc.

DateTime.Parse requires a string representation of a date like 12th Nov 2034 or 3/5/14 and is parsed by default using the culture information of the thread context it is running under.

In your case I think you should just check if the value is an Double first and then use DateTime.FromOADate if it is:

Public Shared Function IsDate(obj As Object) As Boolean
    Dim dt As DateTime
    Dim d As Double
    Dim strDate As String = obj.ToString()

    If Double.TryParse(strDate, d) Then
        dt = DateTime.FromOADate(d)
        'parsed OA date
    ElseIf DateTime.TryParse(strDate, dt) Then
        'parsed string representation of date
    Else
        dt = DateTime.MinValue
    End If
    Return (Not dt = DateTime.MinValue AndAlso Not dt = DateTime.MaxValue)
End Function

Note: There is no need for the square brackets round the Object declaration.

Maybe to improve this your should have an overloaded method with one accepting a double and one a string, then you don't have the overhead of boxing and unboxing value types when calling it using a double value

Public Shared Function IsDate(d As Double) As Boolean
    Dim dt As DateTime = DateTime.MinValue
    Try
        dt = DateTime.FromOADate(d)
        Return (Not dt = DateTime.MinValue AndAlso Not dt = DateTime.MaxValue)
    Catch ex As Exception
        Return False
    End Try
End Function

Public Shared Function IsDate(s As String) As Boolean
    Dim dt As DateTime
    If DateTime.TryParse(s, dt) Then
        Return True
    Else
        Return False
    End If
End Function

Even better - create an extension method of the above, then you can do something like this 49278R.IsDate

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460208

That's a Double, it can't be parsed to Date via DateTime.Parse, use DateTime.FromOADate.

Public Shared Function IsDate(obj As Object) As Boolean
    If obj Is Nothing Then Return False

    Dim dt As DateTime
    If TypeOf obj Is DateTime Then
        dt = DirectCast(obj, DateTime)
    Else
        Dim strDate As String = obj.ToString()
        If Not DateTime.TryParse(strDate, dt) Then
            Dim oaVal As Double
            If Double.TryParse(strDate, oaVal) Then
                Try
                    dt = DateTime.FromOADate(oaVal)
                Catch ex As ArgumentException
                    Return False
                End Try
            End If
        End If
    End If
    Return dt <> DateTime.MinValue AndAlso dt <> DateTime.MaxValue
End Function

Upvotes: 1

Related Questions