为什么时间跨度的总毫秒在整数部分和小数部分有相同的数字

本文关键字:小数部 数字 整数部 时间跨度 为什么 | 更新日期: 2023-09-27 18:01:39

在计算两个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。现在精度

然而,这并不能完全解释这种行为

为什么时间跨度的总毫秒在整数部分和小数部分有相同的数字

对此有一个技术上的解释,否则我无法证明它解释了你的观察。

对于初学者来说,你正在寻找一个噪声数字,操作系统时钟几乎不够精确,无法提供亚毫秒的精度。所以一定不要依赖它们的价值去做任何重要的事情。如果你想测量一个高分辨率的间隔,那么你必须使用秒表代替。

操作系统时钟受到时间服务器更新的影响。大多数机器设置为定期接触time.windows.com以重新校准时钟。这可以消除时钟漂移,机器硬件通常不够好,无法在一个月内保持时间精确到一秒以上。低公差晶体是昂贵的,从来没有完全没有漂移由于温度和老化的影响。每隔一段时间就会插入闰秒,以使时钟与地球缓慢的自转保持同步。最后一个让很多Linux机器崩溃了,谷歌一下"Linux闰秒bug"看看有什么好玩的。

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

相反,它每次增加一个位,每增加一个时钟刻度。实际上,让时钟走得慢一点或快一点,这样它就会逐渐弥补差异,再次变得准确。也许您可以看到它的走向,额外增加的微秒与间隔的长度成正比。因此,看到噪声数字重复的间隔是合理的。

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