.NET 核心中的日期时间精度 [英] DateTime precision in .NET core

查看:21
本文介绍了.NET 核心中的日期时间精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关注 Eric Lippert 的 帖子 几年前 DateTime 的精度,我在 .netcore 和 .NET Framework 4.5.2 上运行了他的测试,在装有 Windows 10 的同一台机器上.

Following Eric Lippert's post years back on precision of DateTime, I ran his test on .netcore and .NET Framework 4.5.2, on the same machine with Windows 10.

        var n = 1000;
        int i = 0;
        long[] diffs = new long[n];
        while (i++ < n-1)
        {
            if (ticks != DateTime.Now.Ticks)
            {
                var newTicks = DateTime.UtcNow.Ticks;
                var diff = newTicks - ticks;
                diffs[i] = diff;
                ticks = newTicks;
            }
        }
        foreach (var d in diffs)
        {
            if (d == 0)
                Console.WriteLine("same");
            else
                Console.WriteLine(d);

        }

.NET 框架 4.5.2 的结果如预期:输出中有一些随机的相同",这意味着 DateTime 对某些子级别不精确.

The result on .NET framework 4.5.2 was as expected: some random "same" in output which means DateTime is not precise to some sub-levels.

然而,在 .NET Core 上的结果完全不同:输出中没有相同".不是两个 Ticks 具有相同的值.

However, the result on .NET core was totally different: no "same" in output. Not two Ticks had the same value.

有什么解释?

推荐答案

解释是,dot net 向底层操作系统询问当前时间.操作系统询问底层硬件.在古代,主板上的硬件时钟 (RTC) 过去常常每 15 毫秒更新一次.这个数字来自美国的 60Hz 交流线路频率,电网保持足够准确.记住那些是缓慢"的日子计算机和设计师试图尽其所能地发挥性能.因此,操作系统不会在每次有人询问时间并传递值的缓存副本时咨询 RTC - 很少更新.

The explanation would be, that dot net asks the underlying operating system for the current time. The operating system asks the underlying hardware. In ancient times the hardware clock (RTC) on the motherboard used to update itself once in about 15 milli seconds. That number was derived from the 60Hz AC line frequency in US which the power grid maintained sufficient accurately. Remember those were the days of "slow" computers and designers tried to squeeze in every bit of performance they could. So the OS did not consult RTC everytime someone asked for time and passed a cached copy of the value - which is updated very infrequently.

后来,主板不断发展,RTC 变得更加精确.但是操作系统和它上面的所有东西并不觉得需要它.请记住,硬件的发展速度远远快于软件,甚至直到今天,消费级软件都浪费了很大一部分原始硬件能力.因此,当 dot net framework 向操作系统询问时间时,即使硬件有能力,它也会取回不精确的数据.准确度确实从 15 毫秒发展到 1 毫秒以下,但仅此而已.

Somewhere down the line, the motherboard evolved and the RTCs became more precise. But the OS and all the things on top of it did not feel the need for it. Remember h/w evolved far faster than software and even till day, consumer grade software waste a large fraction of raw h/w capability. So when dot net framework asked OS for time, it got back the imprecise data even when the h/w was capable. The accuracy did evolve from 15ms to below 1ms, but that was it.

来到 windows 8 (server 2012),终于意识到 (1) 应用程序可以在更精确的时间下做得更好 (2) 计算机速度很快,因此每次咨询 RTC 不再是问题 (3) 大量程序员和程序习惯于并且实际上依赖于不精确的时间行为.所以他们(win 8)继续引入一种新的稍微慢一点的机制来获取最精确的时间数据,但保持原始实现不变.

Come windows 8 (server 2012), it was finally realized that (1) applications could do better with more precise time (2) computers are fast so consulting RTC everytime is no longer a problem (3) a large population of programmers and programs are used to and actually rely on the imprecise time behavior. So they (win 8) went on to introduce a new marginally slower mechanism to obtain the most precise time data, but left the original implementation unchanged.

Dot net 一直使用旧的和不精确的 OS 函数 GetSystemTimeAsFileTime,当一个新表亲 GetSystemTimePreciseAsFileTime 出现在 win 8 中时,dot net 选择了向后兼容的方式,什么都没做.

Dot net had always used the older and imprecise OS function GetSystemTimeAsFileTime and when a new cousin GetSystemTimePreciseAsFileTime appeared in win 8, dot net chose to go the backward compatible way and did nothing.

Dot net core 是对许多核心功能的全新重写,现在利用了高精度数据源.

Dot net core is a fresh rewrite of many core features and now leverages the high precision data source.

如果当前时间是 13:14:15:123456 ,仍然不能保证真实的时间,正如物理学家和天文学家所看到的那样.您的计算机不是原子钟.当然不是一个同步良好的时钟.它唯一的意思是,如果两个事件发生在不同的时间戳,那么一个事件肯定会先于另一个事件发生.在较旧的计算机中,事件(例如日志、文件、数据库 txns 等)的生成率较低,因此为连续事件分配相同时间戳的可能性很小.这个新的时间系统迎合了现代高频率活动,因此您可以将连续事件标记为不同.仍然对于两个非常接近的事件,总会有相同时间戳的机会.这最终是不可避免的.如果您需要纳秒级测量(为什么),您需要不同的工具,例如 Stopwatch 而不是 System.DateTime.

If the current time is 13:14:15:123456 , there is still no guarantee that the real true time, as seen by the physicists and astronomers is that. Your computer is not an atomic clock. And certainly not a well synchronized clock. The only thing it means is that if two events happened at different timestamps then one event happened certainly before the another. In older computers, rate of generation of events (ex logs, files, database txns etc) was lower and so there was low chance that sequential events would be assigned same timestamps. This new time system caters to modern high rate activities so that you can mark sequential events as different. Still for two very close events, there will always be a chance of same timestamp. That is eventually unavoidable. If you need nanosecond level measurement (why) you need different tools like Stopwatch and not System.DateTime.

这篇关于.NET 核心中的日期时间精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆