C#DateTime.Now precision

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#DateTime.Now precision相关的知识,希望对你有一定的参考价值。

我在进行一些单元测试时遇到了DateTime.UtcNow的某些意外行为。看起来,当您快速连续调用DateTime.Now/UtcNow时,似乎可以在比预期更长的时间间隔内返回相同的值,而不是捕获更精确的毫秒增量。

我知道有一个秒表类,它更适合于进行精确的时间测量,但是我很好奇是否有人可以在DateTime中解释这种行为?是否记录了DateTime.Now的官方精度(例如,精确到50毫秒以内)?为什么将DateTime.Now的精度降低到大多数CPU时钟无法处理的水平?也许它只是为最低公分母设计的?

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在可能无法精确到微秒的情况下,应该说是[[precise到微秒?大多数人没有任何精确到微秒的官方时间信号源。因此,给precision小数点后六位数字,而最后五位是garbage,则为lying

记住,DateTime的目的是

代表日期和时间

。高精度计时完全不是DateTime的目的;如您所述,这就是StopWatch的目的。 DateTime的目的是为了表示日期和时间,例如向用户显示当前时间,计算到下一个星期二的天数,等等。总之,“现在几点?和“那花了多长时间?”是完全不同的问题;不要使用旨在回答一个问题来回答另一个问题的工具。

感谢您的问题;这将是一篇不错的博客文章! :-)

另一答案
DateTime的精度在某种程度上取决于运行它的系统。精度与上下文切换的速度有关,该速度通常约为15或16毫秒。 (在我的系统上,实际上距离我的测试大约14毫秒,但我已经看到一些笔记本电脑的精度接近35-40毫秒。)

Peter Bromberg用C#编写了an article on high precision code timing,对此进行了讨论。

另一答案
我想要一个精确的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);

另一答案
MSDN中,您会发现在所有NT操作系统上,DateTime.Now

近似分辨率为10毫秒。

实际精度取决于硬件。使用QueryPerformanceCounter可以获得更好的精度。
另一答案
对于它的价值,由于没有实际检查.NET源,Eric Lippert提供了QueryPerformanceCounter称DateTime仅精确到大约30 ms。用他的话说,不精确到纳秒级是因为它“不需要如此”。
另一答案
a comment on this SO question

此属性的分辨率取决于系统计时器。

他们还声称Windows NT 3.5和更高版本的近似分辨率为10毫秒:)

另一答案
此属性的分辨率取决于系统计时器,取决于基础操作系统。它倾向于

0.5和15毫秒。

因此,在较短的时间间隔(例如在循环中)重复调用Now属性可能返回相同的值。

From MSDN documentation

以上是关于C#DateTime.Now precision的主要内容,如果未能解决你的问题,请参考以下文章

在C#中将当前的DateTime秒和毫秒设置为0

System.DateTime.Now 和 System.DateTime.Today 之间的区别

DateTime.UtcNow.ToString() 和DateTime.Now.ToString()输出的字符为啥不一样呢?

python时间(毫秒)计算

django 1.4 timezone.now() 与 datetime.datetime.now()

c# datetime to sql,包括秒