C# DateTime.Теперь точность



Я просто столкнулся с некоторым неожиданным поведением с DateTime.UtcNow при выполнении некоторых модульных тестов. Оказалось, что, когда вы называете даты.Теперь/UtcNow в быстрой последовательности, похоже, возвращает вам одно и то же значение в течение более длительного, чем ожидалось, интервала времени, а не захватывает более точные миллисекундные приращения.



Я знаю, что есть класс секундомера, который лучше всего подходит для выполнения точных измерений времени, но мне было любопытно, может ли кто-нибудь объяснить это поведение в Дата и время? Есть ли официальная точность, задокументированная для DateTime.Теперь (например, с точностью до 50 мс?)? Почему бы DateTime.Теперь можно сделать менее точным, чем то, что может обрабатывать большинство процессорных часов? Может быть, он просто предназначен для самого низкого общего знаменателя процессора?



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();
}
668   6  

6 ответов:

почему бы DateTime.Теперь можно сделать менее точным, чем то, что может обрабатывать большинство процессорных часов?

хорошие часы должны быть как точный и точный; это разные вещи. Как гласит старая шутка, остановленные часы точно точны дважды в день, часы с минутной задержкой никогда не бывают точными в любое время. Но часы с минутным замедлением всегда точны до ближайшей минуты, тогда как остановленные часы не имеют полезной точности при все.

почему дата и время должны быть точный чтобы, скажем, микросекунда, когда он не может быть точный в микросекунду? Большинство людей не имеют никакого источника для официальных сигналов времени, которые точны до микросекунды. Таким образом, давая шесть цифр после десятичного знака точность, последние пять из которых являются мусор будет врет.

помните, что цель DateTime состоит в том, чтобы представляют собой дату и время. Высокоточные тайминги вовсе не являются целью DateTime; как вы заметили, это цель секундомера. Цель DateTime-представить дату и время для таких целей, как отображение текущего времени пользователю, вычисление количества дней до следующего вторника и т. д.

короче говоря, " который час?- и сколько времени это заняло?"это совершенно разные вопросы; не используйте инструмент, предназначенный для ответа на один вопрос, чтобы ответить другой.

Спасибо за вопрос; это будет хорошая статья в блоге! : -)

точность DateTime несколько специфична для системы, в которой она запускается. Точность связана со скоростью переключения контекста, которая, как правило, составляет около 15 или 16 мс. (в моей системе это на самом деле около 14 мс из моего тестирования, но я видел некоторые ноутбуки, где она ближе к точности 35-40 МС.)

Питер Бромберг написал статья о высокой точности кода синхронизации в C#, который обсуждает это.

Я хотел бы точную дату и время.Теперь :), поэтому я приготовил это:

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, Эрик Липперт предоставил комментарий на это так вопрос говоря, что DateTime является точным только приблизительно до 30 мс. рассуждение о том, чтобы не быть точным наносекундой, по его словам, заключается в том, что это "не должно быть."

С MSDN вы найдете, что DateTime.Now есть примерное разрешение 10 миллисекунд на всех операционных системах NT.

фактическая точность зависит от аппаратного обеспечения. Лучшая точность может быть получена с помощью QueryPerformanceCounter.

из документации MSDN:

разрешение этого имущества зависит от системного таймера.

Они также утверждают, что приблизительное разрешение на Windows NT 3.5 и более поздних версий составляет 10 мс:)

Comments

    Ничего не найдено.