C# DateTime.Now 精度
我刚刚在进行一些单元测试时遇到了 DateTime.UtcNow 的一些意外行为。看来,当您快速连续调用 DateTime.Now/UtcNow 时,它似乎会在比预期更长的时间间隔内返回相同的值,而不是捕获更精确的毫秒增量。
我知道有一个 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();
}
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.
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?
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
一个好的时钟应该既精确又准确;这些是不同的。正如一个老笑话所说,停止的时钟每天准确两次,而慢一分钟的时钟在任何时候都不会准确。但是慢一分钟的时钟总是精确到最接近的分钟,而停止的时钟根本没有任何有用的精度。
为什么 DateTime 不可能精确到微秒,而要精确到微秒?大多数人没有任何精确到微秒的官方时间信号来源。因此,在精度小数点后给出六位数字,其中最后五位是垃圾将是说谎。
请记住,DateTime 的用途是表示日期和时间。高精度计时根本不是 DateTime 的目的;正如您所注意到的,这就是秒表的目的。 DateTime 的用途是表示日期和时间,用于向用户显示当前时间、计算距下周二的天数等。
简而言之,“现在几点了?”以及“这花了多长时间?”是完全不同的问题;不要使用旨在回答一个问题的工具来回答另一个问题。
谢谢你的提问;这将成为一篇很好的博客文章! :-)
A good clock should be both precise and 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 precise to, say a microsecond when it cannot possibly be accurate to 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 garbage would be lying.
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.
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! :-)
DateTime 的精度在一定程度上取决于其运行的系统。精度与上下文切换的速度有关,通常约为 15 或 16 毫秒。 (在我的系统上,我的测试实际上大约为 14 毫秒,但我见过一些笔记本电脑的准确度接近 35-40 毫秒。)
Peter Bromberg 写道 一篇关于 C# 中高精度代码计时的文章对此进行了讨论。
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.)
Peter Bromberg wrote an article on high precision code timing in C#, which discusses this.
我想要一个精确的 Datetime.Now :),所以我做了这个:
I would like a precise Datetime.Now :), so I cooked this up:
就其价值而言,由于没有实际检查 .NET 源代码,Eric Lippert 提供了 对此问题的评论说 DateTime 仅精确到大约 30 毫秒。用他的话说,不达到纳秒精度的原因是“不需要”。
For what it's worth, short of actually checking the .NET source, Eric Lippert provided a comment on this SO question saying 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."
从 MSDN 您会发现
DateTime .Now
在所有 NT 操作系统上的分辨率大约为 10 毫秒。实际精度取决于硬件。使用
QueryPerformanceCounter
可以获得更好的精度。From MSDN you'll find that
DateTime.Now
has an approximate resolution of 10 milliseconds on all NT operating systems.The actual precision is hardware dependent. Better precision can be obtained using
QueryPerformanceCounter
.来自 MSDN 文档:
他们还声称 Windows NT 3.5 及更高版本上的近似分辨率为 10 毫秒 :)
From MSDN documentation:
They also claim that the approximate resolution on Windows NT 3.5 and later is 10 ms :)
因此,在短时间内(例如在循环中)重复调用 Now 属性可能会返回相同的值。
MSDN 链接
As a result, repeated calls to the Now property in a short time interval, such as in a loop, may return the same value.
MSDN Link