将Excel VBA中的date写入工作表会给出错误的值

当我将VBA的date写入Excel工作表时,有时工作表上的值比我预期的要less一天(提前一天)。 以下是我在Excel 2003,2007和2010多台计算机上testing的示例。从即时窗口:

?Format(41652.9999999963, "yyyy-mm-dd hh:mm:ss") > 2014-01-14 00:00:00 [A1].value = CDate(41652.9999999963) ?Format([A1].value, "yyyy-mm-dd hh:mm:ss") > 2014-01-13 00:00:00 [A1].value = CDbl(CDate(41652.9999999963)) ?Format([A1].value, "yyyy-mm-dd hh:mm:ss") > 2014-01-14 00:00:00 

究竟是什么触发了这个?

编辑:

好吧,让我更清楚, 这不是一个四舍五入的问题。 如果我上下一秒钟,我会得到正确的时间。 只是如果我接近这个确切的数字,那么这个date会持续一整天:

 [A1].value = CDate(41652.99999) ?Format([A1].value, "yyyy-mm-dd hh:mm:ss") > 2014-01-13 23:59:59 [A1].value = CDate(41652.999999999996) ?Format([A1].value, "yyyy-mm-dd hh:mm:ss") > 2014-01-13 00:00:00 [A1].value = CDate(41652.999999999997) ?Format([A1].value, "yyyy-mm-dd hh:mm:ss") > 2014-01-14 00:00:00 [A1].value = CDate(41653.00001) ?Format([A1].value, "yyyy-mm-dd hh:mm:ss") > 2014-01-14 00:00:01 

正如CDate的“帮助”所述,“CDate识别date文字和时间文字以及一些落在可接受date范围内的数字。当将数字转换为date时, 整数部分被转换为date任何小数部分的数字是从午夜开始转换为一天的时间 。“ 它从不说时间四舍五入到第二天增加date! 我相信这解决了这个谜团。

事实上,你可以使用自己来获得所需的结果。 testing表明9位数是舍入的最高数字,10位提供了不希望的效果…

ex [a1]=cdate(round(41652.9999999999,8)) – > 14/01/14 00:00

[a1]=cdate(round(41652.9999999999,10)) – > 13/01/14 00:00

在评论后添加代码:

 Sub dower() Dim v1 As Double, vdt As Date, vv As Variant, vdbl As Double Range("a1:a6").ClearContents v1 = 41652.9999999996 vdt = CDate(v1) vv = CDate(v1) vdbl = CDate(v1) [a1] = v1 [a2] = vdt [a3] = vv [a4] = vdbl vdt = CDbl(v1) [a5] = vdt End Sub 

单元值和cdate都有足够的精度来logging这个值:41652.9999999963。

 ?CDate(41652.9999999963) = 41652.9999999963 True [A1].Value=cdbl(CDate(41652.9999999963)) ?[A1].Value= 41652.9999999963 True 

所以我认为这应该是一个Excel缺陷,当用户将cdate分配给单元格值。

虽然我们不知道它的细节实现,但我猜可能是这样的:

 [A1].Value=StringToDate(DateToString(CDate(41652.9999999963))) 

当我们这样做

 [A1].Value=CDate(41652.9999999963)) 

而“DateToString”函数并没有做正确的事情:它将41652.9999999963分为41652和.9999999963两个部分,它使用41652来计算date部分(“2014-1-13”),并使用.9999999963来计算其余部分(“1天0:0:0”),最后合并为“2014-1-13 0:0:0”,但“1天”丢失。