IsDate("13.50")
如何返回True
但IsDate("12.25.2010")
返回False
吗?
最佳答案
最近,我被这个小“功能”绊倒了,想提高对VB和VBA中IsDate
函数的某些问题的认识。
简单案例
如您所料,传递日期数据类型时,IsDate
返回True
,对于除字符串以外的所有其他数据类型,False
返回IsDate
。对于字符串,True
根据字符串的内容返回False
或IsDate
:
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?
IsDateTime
应该更精确地命名为True
,因为它为格式化为时间的字符串返回IsDate
: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
并不是完美的时间验证器。陷阱!
.
不仅接受时间,而且接受多种格式的时间。其中之一使用句点(TypeName(Var) = "Date"
)作为分隔符。这会引起一些困惑,因为句点可以用作时间分隔符,而不能用作日期分隔符: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
解决方法
如果要测试变量的基础数据类型,则应使用
IsDate(Var)
而不是CDate()
: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
CDate的特点
正如@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
底线是,如果您需要将字符串转换为日期/时间,则需要知道期望它们采用的格式,然后在依靠ojit_code对其进行转换之前适当地重新格式化它们。