是否将具有微秒的日期时间值转换为具有精确精度的双精度?
例如。我的日期为 2017年7月3日10:00:00 00 Ticks 636346728000000050 。当我得到 42919.4166666667 时,它变成了双倍。同样地,我已将50个Ticks添加到当前日期即。 2017年7月3日10:00:00 00 Ticks 636346728000000100 转换为double,也获得相同的双倍值但是ticks值已添加到日期。
我通过此方法转换为double date.ToOADate()
任何人都可以解决这个问题吗?
提前致谢:)
答案 0 :(得分:3)
在OLE自动化日期中无法表示50个刻度。这段代码:
DateTime d1 = DateTime.Parse("3 July 2017 10:00:00");
DateTime d2 = d1.AddTicks(100);
double o2 = d2.ToOADate();
Console.WriteLine(o2);
DateTime d3 = d1.AddTicks(1000);
double o3 = d3.ToOADate();
Console.WriteLine(o3);
DateTime d4 = d1.AddTicks(10000);
double o4 = d4.ToOADate();
Console.WriteLine(o4);
生成输出:
42919,4166666667
42919,4166666667
42919,4166666782
因此,您需要至少10000个刻度才能使添加产生影响。
答案 1 :(得分:2)
这里有两个独立的逻辑操作:
从刻度转换为微秒。这基本上是除以10(每个滴答中有100纳秒或0.1微秒)的问题,因此可能会丢失已经在整数算术中的信息 - 但添加50个滴答正好加上5微秒,所以这应该没问题。
从整数转换为二进制浮点数。您的值有17个有效十进制数字,它位于64位二进制浮点类型可以表示的较高端。您不应该依赖超过15位有效十进制数字。
最重要的是,您正在使用ToOADate
,它看起来具有毫秒级的精度,正在查看reference source。
所以:
Ticks
除以10得到微秒,只会失去少量精确度long
转换为double
,这样会丢失的信息少于ToOADate
,但在很多情况下您仍然会丢失信息。如果您能够为double
值选择不同的纪元,则可以很容易地以适当的精度表示值的微秒 - 但是您需要知道需要表达的值的范围才能检查一下,并使用生成的double
值来控制其余代码。
答案 2 :(得分:0)
转换函数ToOADate不支持这么小的差异。 50个刻度是50 * 100ns = 5μs。
如果您检查其他功能,例如SystemTimeToVariantTime或VariantTimeToSystemTime,您会发现它们的限制甚至更高,达到1秒精度。
https://www.codeproject.com/Articles/17576/SystemTime-to-VariantTime-with-Milliseconds提供了允许毫秒级精度的代码。
当前OLE日期的分辨率约为629ns,带有日期计数(整数部分)的两个双精度值之间的差约为44057(如今天),因此,低于7个刻度的所有内容都不会产生影响。
一种用于计算改进的OLE日期的方法是将ODate转换回DateTime,然后根据Tick差异更正Ole日期:
DateTime now = DateTime.Now;
double olenow = now.ToOADate();
DateTime oanow = DateTime.FromOADate(olenow);
double betterolenow = olenow + ((double)(now.Ticks - oanow.Ticks) ) / (24L * 3600 * 1000 * 10000);