C# DateTime.Now 精度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2143140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:52:54  来源:igfitidea点击:

C# DateTime.Now precision

c#.netdatetimeprecisiontime-precision

提问by Andy White

I just ran into some unexpected behavior with DateTime.UtcNow while doing some unit tests. It appears that when you call DateTime.Now/UtcNow in rapid succession, it seems to give you back the same value for a longer-than-expected interval of time, rather than capturing more precise millisecond increments.

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

I know there is a Stopwatch class that would be better suited for doing precise time measurements, but I was curious if someone could explain this behavior in DateTime? Is there an official precision documented for DateTime.Now (for example, precise to within 50 ms?)? Why would DateTime.Now be made less precise than what most CPU clocks could handle? Maybe it's just designed for the lowest common denominator CPU?

我知道有一个 Stopwatch 类更适合进行精确的时间测量,但我很好奇是否有人可以在 DateTime 中解释这种行为?DateTime.Now 是否有官方精度记录(例如,精确到 50 毫秒以内?)?为什么 DateTime.Now 不如大多数 CPU 时钟可以处理的精确?也许它只是为最低公分母 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();
}

采纳答案by Eric Lippert

Why would DateTime.Now be made less precise than what most CPU clocks could handle?

为什么 DateTime.Now 不如大多数 CPU 时钟可以处理的精确?

A good clock should be both preciseand accurate; those are different. As the old joke goes, a stopped clock is exactly accurate twice a day, a clock a minute slow is never accurate at any time. But the clock a minute slow is always precise to the nearest minute, whereas a stopped clock has no useful precision at all.

一个好的时钟应该既精确准确;那些是不同的。正如老笑话所说,停止的时钟每天准确两次,慢一分钟的时钟在任何时候都永远不准确。但是慢一分钟的时钟总是精确到最近的一分钟,而停止的时钟根本没有有用的精度。

Why should the DateTime be preciseto, say a microsecond when it cannot possibly be accurateto the microsecond? Most people do not have any source for official time signals that are accurate to the microsecond. Therefore giving six digits after the decimal place of precision, the last five of which are garbagewould be lying.

当 DateTime 不可能精确到微秒时,为什么要精确到微秒?大多数人没有任何精确到微秒的官方时间信号的来源。因此在精度的小数位后给出六位数字,其中最后五位是垃圾将是在说谎

Remember, the purpose of DateTime is to represent a date and time. High-precision timings is not at all the purpose of DateTime; as you note, that's the purpose of StopWatch. The purpose of DateTime is to represent a date and time for purposes like displaying the current time to the user, computing the number of days until next Tuesday, and so on.

请记住, DateTime 的目的是表示日期和时间。高精度计时根本不是 DateTime 的目的;正如您所注意到的,这就是 StopWatch 的目的。DateTime 的目的是表示日期和时间,用于向用户显示当前时间、计算到下周二的天数等。

In short, "what time is it?" and "how long did that take?" are completely different questions; don't use a tool designed to answer one question to answer the other.

简而言之,“现在几点了?” 以及“那花了多长时间?” 是完全不同的问题;不要使用旨在回答一个问题的工具来回答另一个问题。

Thanks for the question; this will make a good blog article! :-)

谢谢你的提问;这将是一篇很好的博客文章!:-)

回答by Tomas Vana

From MSDN documentation:

从 MSDN 文档

The resolution of this property depends on the system timer.

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

They also claim that the approximate resolution on Windows NT 3.5 and later is 10 ms :)

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

回答by Scott Anderson

For what it's worth, short of actually checking the .NET source, Eric Lippert provided a comment on this SO questionsaying that DateTime is only accurate to approx 30 ms. The reasoning for not being nanosecond accurate, in his words, is that it "doesn't need to be."

对于它的价值,除了实际检查 .NET 源代码之外,Eric Lippert 对这个 SO 问题发表了评论,称 DateTime 仅准确到大约 30 毫秒。用他的话来说,没有达到纳秒准确度的原因是它“不需要如此”。

回答by Reed Copsey

DateTime's precision is somewhat specific to the system it's being run on. The precision is related to the speed of a context switch, which tends to be around 15 or 16 ms. (On my system, it is actually about 14 ms from my testing, but I've seen some laptops where it's closer to 35-40 ms accuracy.)

DateTime 的精度在某种程度上特定于它正在运行的系统。精度与上下文切换的速度有关,通常在 15 或 16 毫秒左右。(在我的系统上,我的测试实际上大约需要 14 毫秒,但我已经看到一些笔记本电脑的准确度接近 35-40 毫秒。)

Peter Bromberg wrote an article on high precision code timingin C#, which discusses this.

Peter Bromberg在 C# 中写了一篇关于高精度代码计时的文章,讨论了这一点。

回答by Kevin Montrose

From MSDNyou'll find that DateTime.Nowhas an approximateresolution of 10 milliseconds on all NT operating systems.

MSDN你会发现DateTime.Now有一个大约10毫秒的所有NT操作系统的分辨率。

The actual precision is hardware dependent. Better precision can be obtained using QueryPerformanceCounter.

实际精度取决于硬件。使用 可以获得更好的精度QueryPerformanceCounter

回答by Jimmy

I would like a precise Datetime.Now :), so I cooked this up:

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

回答by Iman

The resolution of this property depends on the system timer, which depends on the underlying operating system. It tends to be between 0.5 and 15 milliseconds.

此属性的分辨率取决于系统计时器,后者取决于底层操作系统。它往往在 0.5 到 15 毫秒之间。

As a result, repeated calls to the Now property in a short time interval, such as in a loop, may return the same value.

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

MSDN Link

MSDN链接