vba – IsDate函数返回意外的结果

IsDate(“13.50”)如何返回True但IsDate(“12.25.2010”)返回False?
最近我被这个小小的“功能”绊倒了,想提高对VB和VBA中IsDate功能的一些问题的认识。

简单案例

如您所料,IsDate在传递Date数据类型时返回True,对于除Strings之外的所有其他数据类型,IsDate返回False。对于字符串,IsDate根据字符串的内容返回True或False:

IsDate(CDate("1/1/1980"))  --> True
IsDate(#12/31/2000#)       --> True
IsDate(12/24)              --> False  '12/24 evaluates to a Double: 0.5'
IsDate("Foo")              --> False
IsDate("12/24")            --> True

IsDateTime?

IsDate应该更精确地命名为IsDateTime,因为它为格式为时间的字符串返回True:

IsDate("10:55 AM")   --> True
IsDate("23:30")      --> True  'CDate("23:30")   --> 11:30:00 PM'
IsDate("1:30:59")    --> True  'CDate("1:30:59") --> 1:30:59 AM'
IsDate("13:55 AM")   --> True  'CDate("13:55 AM")--> 1:55:00 PM'
IsDate("13:55 PM")   --> True  'CDate("13:55 PM")--> 1:55:00 PM'

从上面最后两个例子可以看出,IsDate不是时代的完美验证器。

Got cha!

IsDate不仅接受时间,它接受了许多格式的时间。其中一个使用句点(。)作为分隔符。这会导致一些混乱,因为该时间段可以用作时间分隔符,但不能用作日期分隔符:

IsDate("13.50")     --> True  'CDate("13.50")    --> 1:50:00 PM'
IsDate("12.25")     --> True  'CDate("12.25")    --> 12:25:00 PM'
IsDate("12.25.10")  --> True  'CDate("12.25.10") --> 12:25:10 PM'
IsDate("12.25.2010")--> False '2010 > 59 (number of seconds in a minute - 1)'
IsDate("24.12")     --> False '24 > 23 (number of hours in a day - 1)'
IsDate("0.12")      --> True  'CDate("0.12")     --> 12:12:00 AM

如果您正在解析字符串并根据其明显类型对其进行操作,那么这可能是一个问题。例如:

Function Bar(Var As Variant)
    If IsDate(Var) Then
        Bar = "This is a date"
    ElseIf IsNumeric(Var) Then
        Bar = "This is numeric"
    Else
        Bar = "This is something else"
    End If
End Function

?Bar("12.75")   --> This is numeric
?Bar("12.50")   --> This is a date

解决方法

如果您正在测试其底层数据类型的变体,则应使用TypeName(Var)=“Date”而不是IsDate(Var):

TypeName(#12/25/2010#)  --> Date
TypeName("12/25/2010")  --> String

Function Bar(Var As Variant)
    Select Case TypeName(Var)
    Case "Date"
        Bar = "This is a date type"
    Case "Long", "Double", "Single", "Integer", "Currency", "Decimal", "Byte"
        Bar = "This is a numeric type"
    Case "String"
        Bar = "This is a string type"
    Case "Boolean"
        Bar = "This is a boolean type"
    Case Else
        Bar = "This is some other type"
    End Select
End Function

?Bar("12.25")   --> This is a string type
?Bar(#12/25#)   --> This is a date type
?Bar(12.25)     --> This is a numeric type

但是,如果您正在处理可能是日期或数字的字符串(例如,解析文本文件),则应在检查以查看是否为日期之前检查它是否是一个数字:

Function Bar(Var As Variant)
    If IsNumeric(Var) Then
        Bar = "This is numeric"
    ElseIf IsDate(Var) Then
        Bar = "This is a date"
    Else
        Bar = "This is something else"
    End If
End Function

?Bar("12.75")   --> This is numeric
?Bar("12.50")   --> This is numeric
?Bar("12:50")   --> This is a date

即使你关心的是是否是一个日期,你应该确定它不是一个数字:

Function Bar(Var As Variant)
    If IsDate(Var) And Not IsNumeric(Var) Then
        Bar = "This is a date"
    Else
        Bar = "This is something else"
    End If
End Function

?Bar("12:50")   --> This is a date
?Bar("12.50")   --> This is something else

褪色特性

正如@Deanna在下面的评论中指出的,CDate()的行为也是不可靠的。它的结果取决于是传递一个字符串还是一个数字:

?CDate(0.5)     -->  12:00:00 PM
?CDate("0.5")   -->  12:05:00 AM

如果一个数字作为字符串传递,尾随和前导零是很重要的:

?CDate(".5")    -->  12:00:00 PM 
?CDate("0.5")   -->  12:05:00 AM 
?CDate("0.50")  -->  12:50:00 AM 
?CDate("0.500") -->  12:00:00 PM 

行为也随着字符串的小数部分接近60分钟标记而变化:

?CDate("0.59")  -->  12:59:00 AM 
?CDate("0.60")  -->   2:24:00 PM 

最底线的是,如果您需要将字符串转换为日期/时间,则需要注意您期望的格式,然后在依赖CDate()之前对其进行适当的格式转换。

翻译自:https://stackoverflow.com/questions/4338025/isdate-function-returns-unexpected-results

转载注明原文:vba – IsDate函数返回意外的结果