.NET DateTime,与 OADate 相互转换时的分辨率不同吗?
我正在将 DateTime 转换为 OADate。我原本希望在将 OADate 转换回来时获得完全相同的 DateTime,但现在它只有毫秒分辨率,因此有所不同。
var a = DateTime.UtcNow;
double oadate = a.ToOADate();
var b = DateTime.FromOADate(oadate);
int compare = DateTime.Compare(a, b);
//Compare is not 0; the date times are not the same
来自 a 的刻度:634202170964319073
来自 b 的刻度:634202170964310000
OADate 双精度:40437.290467951389
这是什么原因? DateTime 的分辨率显然足够好。
I'm converting a DateTime to OADate. I was expecting to get the exact same DateTime when converting the OADate back, but now it has only millisecond resolution, and is therefore different.
var a = DateTime.UtcNow;
double oadate = a.ToOADate();
var b = DateTime.FromOADate(oadate);
int compare = DateTime.Compare(a, b);
//Compare is not 0; the date times are not the same
Ticks from a: 634202170964319073
Ticks from b: 634202170964310000
The OADate double: 40437.290467951389
What is the reason for this? The resolution of DateTime is clearly good enough.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这是一个很好的问题。 (我刚刚发现它。)
除非您使用的日期非常接近 1900 年,否则
DateTime
将比 OA 日期更高精度。但由于某些晦涩的原因,DateTime
结构的作者只是喜欢在DateTime
和其他内容之间转换时截断到最接近的整毫秒。不用说,这样做会在没有充分理由的情况下失去很多精度。这是一个解决方法:
现在,让我们考虑(根据您的问题)给出的
DateTime
:任何
DateTime
的精度都是 0.1 µs。在我们考虑的日期和时间附近,OA 日期的精度为:
我们得出结论,在此区域有一个
DateTime
比 OA 日期精确(略多)六倍。让我们使用上面的扩展方法将
ourDT
转换为double
现在,如果您使用以下方法将
ourOADate
转换回DateTime
上面的静态FromOADatePrecise
方法,你得到与原始版本相比,我们看到这种情况下的精度损失为0.1 µs。我们预计精度损失在 ±0.4 µs 以内,因为该间隔长度为 0.8 µs,与前面提到的 0.6286 µs 相当。
如果我们采用另一种方式,从表示 OA 日期不太接近 1900 年的
double
开始,并且首先使用FromOADatePrecise
,并且然后ToOADatePrecise
,然后我们回到double
,并且因为中间DateTime
的精度优于对于 OA 日期,我们期望在这种情况下有一个完美的往返。另一方面,如果您以相同的顺序使用 BCL 方法FromOADate
和ToOADate
,则极不可能获得良好的往返(除非>double
我们开始时有一个非常特殊的形式)。I think this is an excellent question. (I just discovered it.)
Unless you're operating with dates quite close to the year 1900, a
DateTime
will have a higher precision than an OA date. But for some obscure reason, the authors of theDateTime
struct just love to truncate to the nearest whole millisecond when they convert betweenDateTime
and something else. Needless to say, doing this throws away a lot of precision without good reason.Here's a work-around:
Now, let's consider (from your question) the
DateTime
given by:The precision of any
DateTime
is 0.1 µs.Near the date and time we're considering, the precision of an OA date is:
We conclude that in this region a
DateTime
is more precise than an OA date by (just over) a factor six.Let's convert
ourDT
todouble
using my extension method aboveNow, if you convert
ourOADate
back to aDateTime
using the staticFromOADatePrecise
method above, you getComparing with the original, we see that the loss of precision is in this case 0.1 µs. We expect the loss of precision to be within ±0.4 µs since this interval has length 0.8 µs which is comparable to the 0.6286 µs mentioned earlier.
If we go the other way, starting with a
double
representing an OA date not too close to the year 1900, and first useFromOADatePrecise
, and thenToOADatePrecise
, then we get back to adouble
, and because the precision of the intermediateDateTime
is superior to that of an OA date, we expect a perfect round-trip in this case. If, on the other hand, you use the BCL methodsFromOADate
andToOADate
in the same order, it is extremely improbable to get a good round-trip (unless thedouble
we started with has a very special form).ToOADate 调用的静态方法明确地将刻度除以 10000,然后将结果存储在 long 中,从而删除任何亚毫秒信息
有谁知道在哪里可以找到 OADate 格式的规范?
The static method called by ToOADate clearly divides the ticks by 10000 and then stores the result in a long, thus removing any sub millisecond info
Does anyone know where to find the specs of the OADate format?
可能与双精度精度有关,而不是日期时间。
Probably has something to do with precision of the double, not the DateTime.