以微秒为单位的日期时间
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);
是否以精确精度将具有微秒的日期时间值转换为双精度值?
例如。我的日期是 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);