奇怪的DateAdd行为

时间:2015-03-20 21:35:19

标签: vba

任何人都可以解释以下结果:

?DateAdd("s", 54, 0) = #12:00:54 AM#
True

?DateAdd("s", 55, 0) = #12:00:55 AM#
False

?DateAdd("s", 56, 0) = #12:00:56 AM#
True

更新: Ross Presser的回答提供了以下内容:差异与二进制分数不能总是表示小数分数的事实有关。但是,当两个表达式评估为相同的数据类型时,为什么浮点偏移量不同?

?TypeName(DateAdd("s", 55, 0))
Date

?TypeName(#12:00:55 AM#)
Date

?VarType(DateAdd("s", 55, 0)) = VarType(#12:00:55 AM#)
True

当我遇到这种浮点工件in past时,通常是因为结果实际上是两种不同的类型,至少在评估期间的某个时刻。这似乎不是这种情况。我还是很困惑。

更新2 :Ross的更新答案提供了对此问题的进一步了解。我在追踪这个方面取得了进展。每个答案似乎都提出了新的问题。似乎DateAdd和日期文字都使用双精度,但由于某种原因,DateAdd舍入到18位小数(或者可能截断为19而不是舍入):

?CDbl(#12:00:55 AM#) - CDbl(55/86400)
 0 

?CDbl(DateAdd("s", 55, 0)) - CDbl(55/86400)
-1.0842021724855E-19 

?0.000636574074074074 - 0.0006365740740740741
-1.0842021724855E-19 

为什么会出现这种情况?

1 个答案:

答案 0 :(得分:2)

VBA中的

Date表示为整数天加上表示时间的浮点分数。由于时间是一个浮点数(或者可能是一个双精度数),因此无法精确地表达每一秒。 55秒是55/86400,或一天的0.00063657407。这可能在浮点数中无法准确表示。

要获得更多信息,请尝试从文字值中减去Dateadd值,然后转换为float。

编辑:以下是我所谈论的见解:

? cdbl(dateadd("s",55,0)) - cdbl(#12:00:55 AM#)
-1.0842021724855E-19 

将时间字面值转换为Date结构的解析算法显然正在执行与dateadd函数不同的操作,从而导致第19个小数位的错误。我的猜测是,其中一个或另一个使用Single应该使用Double。我猜你可以称之为一个错误并报告给微软。

编辑2:谷歌搜索出现this link人们正在谈论VBA日期类型下的浮点现实。他们给出了一个不同的例子,其中错误在第17位而不是第19位:

? DateAdd("h",2,#8:00#) - #10:00#
-5.55111512312578E-17 

还有this gentleman人写了一些VBA代码来更准确地完成DateAdd的工作。