C#DateTime.Now精度
我只是在做一些unit testing的时候遇到了一些与DateTime.UtcNow出乎意料的行为。 看起来,当你连续快速地调用DateTime.Now/UtcNow时,似乎给你的时间间隔长于同一个值,而不是捕获更精确的毫秒增量。
我知道有一个秒表类,可能更适合做精确的时间测量,但我很好奇,如果有人可以在DateTime中解释这种行为? 是否有DateTime.Nowlogging的官方精确度(例如,精确到50毫秒以内?)? 为什么DateTime.Now会比大多数CPU时钟所能处理的更精确? 也许它只是为最低公分母CPUdevise的?
public static void Main(string[] args) { var stopwatch = new Stopwatch(); stopwatch.Start(); for (int i=0; i<1000; i++) { var now = DateTime.Now; Console.WriteLine(string.Format( "Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond)); } stopwatch.Stop(); Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}", stopwatch.ElapsedMilliseconds); Console.ReadLine(); }
为什么DateTime.Now会比大多数CPU时钟所能处理的更精确?
一个好的时钟应该既精确又准确 ; 那些是不同的。 正如这个老玩笑所说,一个停止的时钟每天准确地两次准确,一分钟一分钟的速度在任何时候都不准确。 但是一分钟慢的时钟总是精确到最接近的分钟,而一个停止的时钟根本没有任何有用的精度。
为什么DateTime应该精确到微秒,而不可能精确到微秒呢? 大多数人没有任何准确到微秒的官方时间信号的来源。 所以精确到小数点后六位数字,最后五位是垃圾 。
请记住,DateTime的目的是表示一个date和时间 。 高精度时间根本不是DateTime的目的; 正如你注意到的,这就是秒表的目的。 DateTime的目的是表示一个date和时间,用于向用户显示当前时间,计算直到下个星期二的天数等等。
总之,“现在几点了?” 和“需要多长时间?” 是完全不同的问题; 不要使用一个旨在回答一个问题来回答另一个问题的工具。
谢谢你的提问 这将是一个很好的博客文章! 🙂
DateTime的精确度与它所运行的系统有一定的关系。 精度与上下文切换的速度有关,往往大约在15或16毫秒左右。 (在我的系统中,实际上我的testing时间大约是14毫秒,但是我看到一些笔记本电脑的精度接近35-40毫秒。)
Peter Bromberg在C#中写了一篇关于高精度代码时序的文章 ,讨论了这一点。
我想要一个精确的Datetime.Now :),所以我做了这个:
public class PreciseDatetime { // using DateTime.Now resulted in many many log events with the same timestamp. // use static variables in case there are many instances of this class in use in the same program // (that way they will all be in sync) private static readonly Stopwatch myStopwatch = new Stopwatch(); private static System.DateTime myStopwatchStartTime; static PreciseDatetime() { Reset(); try { // In case the system clock gets updated SystemEvents.TimeChanged += SystemEvents_TimeChanged; } catch (Exception) { } } static void SystemEvents_TimeChanged(object sender, EventArgs e) { Reset(); } // SystemEvents.TimeChanged can be slow to fire (3 secs), so allow forcing of reset static public void Reset() { myStopwatchStartTime = System.DateTime.Now; myStopwatch.Restart(); } public System.DateTime Now { get { return myStopwatchStartTime.Add(myStopwatch.Elapsed); } } }
对于它的价值,在实际检查.NET源代码的时候,Eric Lippert提供了对这个SO问题的评论,说DateTime只能精确到大约30毫秒。 用他的话来说,毫无准确的说法就是“不需要”。
从MSDN你会发现DateTime.Now
在所有NT操作系统上的近似分辨率为10毫秒。
实际精度取决于硬件。 使用QueryPerformanceCounter
可以获得更好的精度。
从MSDN文档 :
此属性的分辨率取决于系统计时器。
他们还声称在Windows NT 3.5和更高版本上的近似分辨率是10毫秒:)