尽管传递了有效的日期,但VB.NET TryParse返回False

时间:2014-12-04 09:59:49

标签: .net vb.net excel parsing date

我在VB.NET中创建了一个检查有效日期的函数。功能如下:

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

我将值传递给我认为是有效日期的函数。我的测试值是49278,应该对应于2034年11月30日的日期。

然而,我的功能告诉我这不是一个有效的日期。我不明白为什么。

enter image description here

这里发生了什么?

2 个答案:

答案 0 :(得分:1)

那是Double,无法通过Date解析为DateTime.Parse,请使用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

答案 1 :(得分:1)

该值是Excel等使用的“OLE自动化日期”

DateTime.Parse需要一个类似12th Nov 20343/5/14的日期的字符串表示形式,默认情况下使用其运行的线程上下文的区域性信息进行解析。

在您的情况下,我认为您应该先检查该值是否为Double,然后使用DateTime.FromOADate如果是:

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

注意:方括号不需要围绕Object声明。

也许为了改进这个你应该有一个重载方法,一个接受一个双字符串和一个字符串,然后你没有使用双值调用它时装箱和取消装箱值类型的开销

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

更好 - 创建上述扩展方法,然后你可以做这样的事情49278R.IsDate