日期时间准确与精密

33 篇文章 1 订阅

日期时间准确与精密

该文由英语经过翻译而来,定时任务中由于时间一秒之差导致平台系统引发百万级的错误数据查询中,翻译此文
原文链接: https://docs.microsoft.com/en-us/archive/blogs/ericlippert/precision-and-accuracy-of-datetime

​ DateTime struct 将日期表示为一个64位数字,用于度量自特定开始日期以来的“刻度”数。一千万滴答声等于一秒钟。

​ 这是相当高的精确度。您可以使用 DateTime 将日期和时间表示为亚微秒级的精度,这通常比您需要的精度更高。当然,并不总是这样; 在现代硬件上,你可能一次就可以执行几百条指令,因此,如果你想要的计时精度达到谈论单个指令所需的水平,那么这个计时就太粗糙了。

​ 具有如此高的精度所带来的问题当然是,我们很容易假设给定的值与它的精度一样准确。但是这根本就是不正当的!我可以用一个双精度浮点数字1.799992352094米来表示我的身高; 虽然精确到千分之一米,但它只能精确到百分之一米左右,因为我没有一个能真正测量我身高千分之一米,甚至千分之一米的装置。这里有更多的精确性而不是准确性。

​ 日期和时间也是如此。您的 DateTime 可能精确到亚微秒级别,但它是否具有准确性?我经常将**电脑与 time. gov 同步**。但如果我不这样做,他们的时钟每年通常会偏离几秒。假设我的钟每年慢一秒。一年有3150万秒,一秒钟有1000万个滴答声,因此它每3.15秒就失去一个滴答声。即使我的时钟奇迹般地准确,在某个时刻,在十秒钟之内,它已经很精确了。一天之内,大部分的精确度都会变成垃圾(精度损失而变成的无效数据)。

如果你做一个小实验,你会发现当被问到“现在是什么时间?”时,操作系统实际上给你的准确度比精确度低几千倍

long ticks = DateTime.Now.Ticks;
while (true) {
    if (ticks != DateTime.Now.Ticks) {
        ticks = DateTime.Now.Ticks;
        Console.WriteLine(ticks);
    } else {
        Console.WriteLine("same");
    }
}

​ 在我的机器上,这个值显示“相同”8到9次,然后 Ticks 属性突然跳跃大约160000,也就是16毫秒,一秒的64分之一。(不同类型的 Windows 可能会给出不同的结果,这取决于它们的线程计时算法和其他实现细节。)

​ 正如您所看到的,时钟似乎精确到亚微秒级别,但实际上它只精确到16毫秒。(当然,它是否精确到那个水平取决于时钟与官方报时信号的同步程度。)

​ 这是 DateTime 中的一个缺陷吗。现在?也不尽然。“挂钟”计时器的目的是为典型的现实世界使用生成日期和时间,比如“神秘博士什么时候开始?”或者”我们什么时候改成夏令时?”或者“给我看看我上周四午饭后编辑的文件。”这些操作不需要亚微秒级的精度。

​ (顺便提一句,在 VBScript 中,语言中内置的“挂钟”计时器方法实际上舍去了从操作系统到最接近的秒的时间,而不是最接近的64分之一秒。)

​ 简而言之,问题是“现在几点了?”真的应该只回答一个水平的精确度,反映了准确性的水平固有的系统。大多数计算机时钟甚至没有精确地与官方时间的一毫秒同步,因此超过这一精确度水平的精确度是一个谎言。在我看来,相当不幸的是,DateTime 结构的表面精度和它的表面精度一样高,因为它使得该结构上的操作看起来也应该精确到那个级别。但几乎可以肯定的是,他们并不是那么准确。

​ 现在,问题是“从开始到结束花了多少时间?”和”现在几点了”完全是两码事如果你想问的问题是一些操作需要多长时间,并且你想要一个高精度、高准确度的答案,那么使用秒表类。它确实有纳秒准确与精密,接近它的精确度。

​ 记住,你不需要知道时间就可以知道已经过去了多少时间。这可能是完全不同的两件事。

评论中提到

​ 秒表类的问题在于,尽管它极其精确,但它并不能保证精确。它用来计数的源可能在不同的 CPU 上不同,当你在不同的 CPU 上停止时钟而不是在它上面启动时,会导致不正确的结果。此外,它可以在省电模式下以不同的频率计数,这对于微基准测试代码来说是完美的,但是作为以太网数据包到达的时间指示器是无用的。

​ 我还要补充一点,我非常喜欢 DateTime 具有如此高的内置精度(即使它暗示了 DateTime)。现在比它更精确) ,因此我可以对表示生日、系统时间和以太网数据包到达时间的数据使用相同的数据结构和函数。这比其他系统更可取,因为它们需要不同的表示形式,因此针对每种情况需要不同的库。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值