以微秒为单位的日期时间

DateTime in Microseconds

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

例如。我的日期是 3 July 2017 10:00:00 00 Ticks 636346728000000050。当我得到 42919.4166666667 时,它转换为双倍。同样,我已将 50 Ticks 添加到当前日期,即。 3 July 2017 10:00:00 00 Ticks 636346728000000100 转换为 double,也得到相同的 double 值,但 ticks 值已添加到日期中。

我是用这个方法转成double的date.ToOADate()

谁能解决这个问题?

提前致谢:)

50 个刻度无法在 OLE 自动化日期中表示。此代码:

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 个刻度才能使添加产生影响。

这里有两个独立的逻辑操作:

  • 从滴答声转换为微秒。这基本上是一个除以 10 的问题(每个刻度有 100 纳秒或 0.1 微秒),因此这可能会丢失已经在整数运算中的信息 - 但添加 50 个刻度正好添加 5 微秒,所以应该没问题。

  • 从整数转换为二进制浮点数。您的值有 17 个有效十进制数字,这是 64 位二进制浮点类型可以表示的较高端。您不应依赖超过 15 位有效的小数位。

最重要的是,您正在使用 ToOADate,它似乎具有毫秒精度,查看 reference source

所以:

  • 您可以将 Ticks 除以 10 得到微秒,只会损失少量精度
  • 您可以用不同的方式从 long 转换为 double,这会比 ToOADate 丢失更少的信息,但在许多情况下您仍然会丢失信息。
  • 如果您除以 10.0(因此避免以整数运算开头),那么根据您要表示的值,您可以避免丢失 任何 信息。

如果您能够为您的 double 值选择不同的纪元,您可以轻松地以适当的精度在值中表达微秒 - 但您需要知道您需要表达的值的范围为了检查这一点,以及使用结果 double 值控制其余代码。

转换函数ToOADate不支持这么小的差异。 50 个刻度为 50*100ns = 5 μs。

如果您检查其他函数,如 SystemTimeToVariantTime 或 VariantTimeToSystemTime,您会发现它们的限制甚至更多,精度为 1 秒。

https://www.codeproject.com/Articles/17576/SystemTime-to-VariantTime-with-Milliseconds 提供允许毫秒精度的代码。

OLE 日期的当前分辨率约为 629ns,天数(整数部分)的两个双打之间的差异约为 44057(如今天),因此低于 7 Ticks 的所有内容都不会产生影响。

计算改进的 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);