需要了解为什么我会有时间差异。 这是我的VBA代码:
Public OHLCArray(1 To 481, 0 To 28, 0 To 3) As Single
'debug stmt below
Dim DebugTime As Double
OHLCArray(1, 0, 3) = Now()
'next 3 lines are debugging lines
DebugTime = OHLCArray(1, 0, 3)
Print #1, "Now()=" & DebugTime
Print #1, Now & "Debug print line - (just before pushing"
以下是日志文件中的调试输出行:
Now()=42527.4609375
06/06/2016 11:01:00 AMDebug print line - (just before pushing
你知道吗,时间是0.4609375 = 11:03:45 AM;我期待在第二个Print语句中向我显示这个,或者在不超过2秒的时间内关闭。
我的问题:在上面的例子中,为什么我会有不同的时间? now和now()之间有区别吗?这会影响时间的捕获吗,如上图所示?
感谢您的帮助。卡尔。
P.S。以下是上面确定的行之前的2个调试输出行:
06/06/2016 10:59:34 AM - Skipped ws_calculate routine - CurrentTimeID already processed - CurrentTimeID = 45
06/06/2016 10:59:54 AM - Skipped ws_calculate routine - CurrentTimeID already processed - CurrentTimeID = 45
P.S.S。以下是相关主题的链接 - 不确定它是否适用于我的问题:Postgres now() vs 'now' in function
P.S.S。谢谢Vegard。在检查具有类似输出数据的其他日志文件时,可以确定由于两个错误而导致我的混淆:a)在将新的单个数据移动到它之前我没有将DebugTime重置为零(较小的小数位来自哪里)从单个重叠到双重?),和b)您的观察,单个数据类型转换为双数据类型是没有用的,因为最初移动到我的数组时发生截断全日期数据定义为单一。我想我会将我的数组维持为单一,但是,为了避免它的大小加倍,当99.8%的数组工作得很好时定义为单数。我可以在我的工作表的标题中接受最多约2分钟的时间(当数组被转移到它时)。我了解到在大多数应用程序中将日期/时间数据移动到Single数据类型是不够的。数据类型应为Double或DateTime。
P.S.S。最后:
今天(周三,上午11点左右)运行调试语句的逻辑向我展示了以下内容:
OHLCArray(1,0,3)=现在()
单个OHLCArray元素捕获date.time为42529.46。 Now()然而是42529.45905067(相当于上午11:01:02),这出现在我的print.debug和打印日志文件(正确)中。当现在被铸造时,它会四舍五入到.46
DebugTime = OHLCArray(1,0,3)
当数组元素被转换为DebugTime时,会拾取其他数字(错误地)。 DebugTime = 42529.46093750。这意味着上午11:03:45。这里也很有趣。当我稍后将该数组元素(42529.46)移动到我的Excel工作表(反映完整数组的工作表)时 - 格式化为仅显示该数字的单元格,我在工作表中上午11:03:45。因此,这意味着工作表中的单元格正在以与DebugTime = OHLCArray(1,0,3)语句完全相同的方式接收数字。因为记住,数组元素是42529.46。 0.46转换为11:02:24 am。
感谢VeGard的额外努力。我希望这一后续工作有助于您更深入地了解EXCEL和VBA表现出来的一些不太明显的方法。正如我总是告诉我的非计算机文化的朋友:“计算机永远不会错!”
答案 0 :(得分:4)
在日期上下文中使用Single
给出正确答案的任何实例都是极端巧合。
为了进一步说明为什么,基于Gary的回答,我已经改变了你的代码,以便数组声明为Double
- 当我们想要比较实际正确的Double
与Single
- 施放到 - Double
这是不正确的。
Sub testTime()
Dim OHLCArray(1 To 481, 0 To 28, 0 To 3) As Double
'debug stmt below
Dim DblTime As Double, SngTime As Single
OHLCArray(1, 0, 3) = Now()
'next 3 lines are debugging lines
DblTime = OHLCArray(1, 0, 3)
SngTime = OHLCArray(1, 0, 3)
Debug.Print "Doubletime: " & DblTime
Debug.Print "Singletime: " & SngTime
Debug.Print " Date Double Single Double(single2)"
Debug.Print "Singletime = " & CDate(SngTime) & " - " & CDbl(SngTime) & " - " & CSng(SngTime) & " - " & CDbl(SngTime2)
Debug.Print "Doubletime = " & CDate(DblTime) & " - " & CDbl(DblTime) & " - " & CSng(DblTime)
Debug.Print "Now() = " & Now() & " - " & CDbl(Now()) & " - " & CSng(Now())
Debug.Print "Now = " & Now & " - " & CDbl(Now) & " - " & CSng(Now)
End Sub
现在,让我们回顾一下输出。我已经运行了好几次,这清楚地说明了这个问题。观察在“Double”列的第一行中发生了什么(或者更确切地说,不发生了什么),这是我们将单个转换为double的地方,并将其与正确的{{1}进行比较在下一行:
Double
请注意,对于使用Doubletime: 42528,3991666667
Singletime: 42528,4
Date Double Single
Singletime = 07.06.2016 09:33:45 - 42528,3984375 - 42528,4
Doubletime = 07.06.2016 09:34:48 - 42528,3991666667 - 42528,4
Now() = 07.06.2016 09:34:48 - 42528,3991666667 - 42528,4
Now = 07.06.2016 09:34:48 - 42528,3991666667 - 42528,4
Doubletime: 42528,3995138889
Singletime: 42528,4
Date Double Single
Singletime = 07.06.2016 09:33:45 - 42528,3984375 - 42528,4
Doubletime = 07.06.2016 09:35:18 - 42528,3995138889 - 42528,4
Now() = 07.06.2016 09:35:18 - 42528,3995138889 - 42528,4
Now = 07.06.2016 09:35:18 - 42528,3995138889 - 42528,4
Doubletime: 42528,3996180556
Singletime: 42528,4
Date Double Single
Singletime = 07.06.2016 09:33:45 - 42528,3984375 - 42528,4
Doubletime = 07.06.2016 09:35:27 - 42528,3996180556 - 42528,4
Now() = 07.06.2016 09:35:27 - 42528,3996180556 - 42528,4
Now = 07.06.2016 09:35:27 - 42528,3996180556 - 42528,4
Doubletime: 42528,3998726852
Singletime: 42528,4
Date Double Single
Singletime = 07.06.2016 09:33:45 - 42528,3984375 - 42528,4
Doubletime = 07.06.2016 09:35:49 - 42528,3998726852 - 42528,4
Now() = 07.06.2016 09:35:49 - 42528,3998726852 - 42528,4
Now = 07.06.2016 09:35:49 - 42528,3998726852 - 42528,4
Doubletime: 42528,4045486111
Singletime: 42528,41
Date Double Single
Singletime = 07.06.2016 09:45:00 - 42528,40625 - 42528,41
Doubletime = 07.06.2016 09:42:33 - 42528,4045486111 - 42528,41
Now() = 07.06.2016 09:42:33 - 42528,4045486111 - 42528,41
Now = 07.06.2016 09:42:33 - 42528,4045486111 - 42528,41
的所有日期转换,时间戳实际上是长时间静态的,因为数据类型不能支持足够的数字。
将它投射到Single
产生更多数字这一事实并不一定能使它正确 - 它会变得稍微准确一些,但仍然不正确。
所以问题似乎与Double
或Now
无关!如我的示例所示,只要使用正确的数据类型,它们都会产生正确的结果。
您的第一个问题,即错误的时间戳,是由于数组是Now()
而不是Single
。
您的第二个问题完全是其他问题,可能在您的代码中。要么你正在超载Double
,要么可能更有可能,Now
在运行时正在做一些时髦的事情。尝试使用Print
为Print
语句添加前缀,然后将结果与日志文件进行比较,或者更好的是,根据documentation,更改此内容:
Debug.Print "Now: " & Now
到此:
Print #1, Now & "Debug print line - (just before pushing"
使用标准短日期格式将日期数据写入文件 由您的系统识别。当日期或时间组件时 缺少或为零,只有提供的部分被写入文件。
至于将Print #1, CDate(Now) & "Debug print line - (just before pushing"
转换为Single
时出现的神秘的额外数字,这不是编译器所做的近似,正如我之前错误猜到的那样。这是数字如何表示的已知副作用,显然是计算机科学中的common topic。
此处:https://msdn.microsoft.com/en-us/library/system.double.aspx?cs-save-lang=1&cs-lang=vb#Conversions
类型转换。 Double结构提供了显式接口 支持IConvertible接口的实现 任何两种标准.NET Framework数据类型之间的转换。 语言编译器也支持隐式转换值 Double值的所有其他标准数字类型。转换a Double的任何标准数字类型的值都是加宽 转换并且不需要铸造操作员的用户或 转换方法。
但是,Int64和Single值的转换可以 涉及精度的损失。
精度问题最常影响转换为Double值的单值。
在这里:https://msdn.microsoft.com/en-us/library/system.single.aspx
例如,2/10,精确地用.2表示为小数 分数,由.0011111001001100表示为二进制分数, 模式“1100”重复到无穷大。在这种情况下, 浮点值提供了不精确的表示 它代表的数字。执行额外的数学 对原始浮点值的操作通常会增加其值 缺乏精确性。例如,如果您比较结果 将.3乘以10并将.3增加到.3九次,你会看到 加法产生不太精确的结果,因为它涉及八个 比乘法更多的操作。请注意,这种差异是 只有在使用“R”显示两个Single值时才会显现 标准数字格式字符串,如有必要,显示全部9 Single类型支持的精度数字。
答案 1 :(得分:1)
使用Single
而不是Double
会产生截断的排序:
Sub NotNow()
Dim s As Single, d As Double
s = Now
d = Now
Dim dt As Date, dt2 As Date
dt = CDate(s)
dt2 = CDate(d)
MsgBox s & vbCrLf & d & vbCrLf & dt & vbCrLf & dt2
End Sub
答案 2 :(得分:1)
Now和Now()之间没有区别。您的示例中的差异是因为OHLCarray被声明为单个。当我宣布evrything为双倍的时候是相同的:
现在()= 42528.3594907407
42528.3594907407调试打印行 - (在推送之前
(顺便说一句,如果你想要准确的时间使用windows api调用高分辨率计时器)
Sub lg()
Dim OHLCArray(1 To 481, 0 To 28, 0 To 3) As Double
'debug stmt below
Dim DebugTime As Double
OHLCArray(1, 0, 3) = Now()
'next 3 lines are debugging lines
DebugTime = OHLCArray(1, 0, 3)
Debug.Print "Now()=" & DebugTime
Debug.Print CDbl(Now) & "Debug print line - (just before pushing"
End Sub