C# 为什么timespan Total毫秒的整数和小数部分具有相同的数字?

C# 为什么timespan Total毫秒的整数和小数部分具有相同的数字?,c#,datetime,timespan,C#,Datetime,Timespan,当计算两个DateTime对象之间的毫秒差时,我似乎总是得到一个返回的数字,其中数字的小数部分与数字的整数部分相同。例如:1235.1235 为什么会发生这种情况?我做错什么了吗?这是语言的怪癖还是DateTime粒度的限制 这可以使用以下代码进行演示: DateTime then = DateTime.Now; Thread.Sleep(1234); DateTime now = DateTime.Now; TimeSpan ta

当计算两个
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`的精确度无法达到此级别:请参阅


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

对此有技术上的解释,我无法证明它能解释你的观察结果。它当然不会在我的机器上重新编程

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

操作系统时钟受时间服务器更新的影响。大多数机器设置为定期联系time.windows.com重新校准时钟。这消除了时钟漂移,机器硬件通常不足以在一个月内将时间精确到一秒以上。低公差晶体价格昂贵,而且由于温度和老化效应,永远不会完全无漂移。每隔一段时间就会插入一次闰秒,以使时钟与地球缓慢的自转保持同步。上一次是在很多Linux机器上崩溃的,谷歌的“Linux闰秒bug”是为了一些有趣的阅读

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

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


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

这可能只是抽签的运气。另外:看一下秒表类。总有多少次?
DateTime。现在
最多有毫秒精度。实际上通常只有16毫秒。我怀疑小数部分是windows(而不是.net)在内部表示日期的人工制品。@Rawling还有他上级的一般保护错误。@ColonelPanic-我做了1000次测试,所以如果您在新安装的windows上进行测试,
GetSystemTimeAdjustment()
应该返回零,而您不会看到这种行为?这可能是最糟糕的时间,当然时钟已经过大了。不要插入网络电缆。有趣:-)我已经检查了时间调整,它已启用-增量返回为156001滴答声,似乎没有变化。为了验证,我必须在非零时刻捕捉它,看看结果是否不同。(我还没有设法让SetSystemTimeAdjustment禁用调整-因此我将稍后再试。)