9

在计算两个DateTime对象之间的毫秒差时,我似乎总是得到一个返回的数字,其中数字的小数部分与数字的整数部分相同。例如:1235.1235

为什么会这样?难道我做错了什么?这是语言的怪癖还是DateTime粒度的限制或其他什么?

这可以使用以下代码进行演示:

        DateTime then = DateTime.Now;
        Thread.Sleep(1234);
        DateTime now = DateTime.Now;
        TimeSpan taken = now - then;
        string result = taken.TotalMilliseconds.ToString(CultureInfo.InvariantCulture);
        //result = "1235.1235"

正如 CodesInChaos 评论的那样:

DateTime` 不准确到此精度级别:请参阅C# DateTime.Now 精度

但是 - 这并不能完全解释这种行为。

4

1 回答 1

4

对此有技术解释,我无法以其他方式证明它解释了您的观察。它当然不会在我的机器上重现。

对于初学者来说,您正在寻找噪声数字,操作系统时钟几乎不够准确,无法为您提供亚毫秒级的精度。所以一定要确保你从不依赖他们的价值来做任何重要的事情。如果要以高分辨率测量间隔,则必须改用秒表。

操作系统时钟受时间服务器更新的影响。大多数机器都设置为定期联系time.windows.com以重新校准时钟。这消除了时钟漂移,机器硬件通常不足以在一个月内保持时间精确到一秒以上。低容差晶体价格昂贵,并且由于温度和老化效应而永远不会完全没有漂移。并且不时插入闰秒,以保持时钟与行星缓慢旋转的同步。最后一个崩溃了很多Linux机器,谷歌“Linux闰秒bug”找找乐子阅读。

这里重要的是当您的机器获得需要它调整时钟的新更新时会发生什么。Windows 不会突然跳时钟值,这会导致关注时钟并期望它以可预测的数量持续增加的程序出现重大问题。

相反,它会随着每个时钟滴答增量一次增加一点。实际上,使时钟运行得更慢或更快,因此它将逐渐弥补差异并再次变得准确。也许您可以看到它的去向,额外增加的微秒与间隔的长度成正比。所以看到噪声数字中重复的间隔是合理的。

证明这一理论的唯一真正方法是调用 GetSystemTimeAdjustment()。当系统时间调整正在进行时,它将返回非零值。然后 pinvoke SetSystemTimeAdjustment() 以禁用它并观察这是否会影响您看到的值。或者只是等待足够长的时间,直到时钟赶上,这样它就不会再调整了。

于 2013-02-28T19:10:47.277 回答