DateTime以微秒为单位

时间:2017-07-03 06:56:22

标签: c# datetime time double precision

是否将具有微秒的日期时间值转换为具有精确精度的双精度?

例如。我的日期为 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()

任何人都可以解决这个问题吗?

提前致谢:)

3 个答案:

答案 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,但在很多情况下您仍然会丢失信息。
  • 如果除以10.0(因此避免使用整数算术),那么根据您尝试表示的值,您可以避免丢失任何信息。

如果您能够为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);