Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to implement a high resolution DateTime.UtcNow in C#?

Tags:

c#

time

stopwatch

I am trying to implement a time service that will report time with greater accuracy than 1ms. I thought an easy solution would be to take an initial measurement and use StopWatch to add a delta to it. The problem is that this method seems to diverge extremely fast from wall time. For example, the following code attempts to measure the divergence between Wall Time and my High Resolution Clock:

public static void Main(string[] args)
{
    System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
    DateTime baseDateTime = DateTime.UtcNow;
    s.Start();
    long counter = 0;
    while(true)
    {
        DateTime utcnow = DateTime.UtcNow;
        DateTime hpcutcnow = baseDateTime + s.Elapsed;
        Console.WriteLine(String.Format("{0}) DT:{1} HP:{2} DIFF:{3}", 
            ++counter, utcnow, hpcutcnow, utcnow - hpcutcnow));
        Thread.Sleep(1000);
    }
}

I am diverging at a rate of about 2ms/minute on fairly recent sever hardware.

Is there another time facility in windows that I am not aware of that will be more accurate? If not, is there a better approach to creating a high resolution clock or a 3rd party library I should be using?

like image 302
Chuu Avatar asked Nov 01 '13 21:11

Chuu


People also ask

Is DateTime UtcNow accurate?

DateTime. UtcNow is accurate to 15.625 milliseconds and stable over very long periods thanks to the time service updates.

How precise is DateTime now?

From MSDN you'll find that DateTime. Now has an approximate resolution of 10 milliseconds on all NT operating systems.

What is the difference between DateTime now and DateTime UtcNow?

The property Now of the DateTime class returns the current date and time of the machine running the code, expressed in the computer's local time. The property UtcNow of the DateTime class returns the current date and time of the machine running the code, expressed in UTC format.

How accurate is DateTime C#?

First, lets take a look at precision: The DateTime type is basically just a 64 bit integer that counts “ticks”. One tick is 100 nanoseconds (or 0.0001 milliseconds) long (MSDN). So DateTime 's precision can be up to 0.0001 milliseconds.


2 Answers

Getting an accurate clock is difficult. Stopwatch has a very high resolution, but it is not accurate, deriving its frequency from a signal in the chipset. Which operates at typical electronic part tolerances. Cut-throat competition in the hardware business preempted the expensive crystal oscillators with a guaranteed and stable frequency.

DateTime.UtcNow isn't all that accurate either, but it gets help. Windows periodically contacts a time service, the default one is time.windows.com to obtain an update of a high quality clock. And uses it to recalibrate the machine's clock, inserting small adjustments to get the clock to catch up or slow down.

You need lots of bigger tricks to get it accurate down to a millisecond. You can only get a guarantee like that for code that runs in kernel mode, running at interrupt priority so it cannot get pre-empted by other code and with its code and data pages page-locked so it can't get hit with page faults. Commercial solutions use a GPS radio to read the clock signal of the GPS satellites, backed up by an oscillator that runs in an oven to provide temperature stability. Reading such a clock is the hard problem, you don't have much use for a sub-millisecond clock source when your program that uses it can get pre-empted by the operating system just as it obtained the time and not start running again until ~45 msec later. Or worse.

DateTime.UtcNow is accurate to 15.625 milliseconds and stable over very long periods thanks to the time service updates. Going lower than that just doesn't make much sense, you can't get the execution guarantee you need in user mode to take advantage of it.

like image 129
Hans Passant Avatar answered Sep 30 '22 16:09

Hans Passant


Apparently in Windows 8/Server 2012 a new API was added specifically for getting high resolution timestamps, the GetSystemTimePreciseAsFileTime API. I haven't had a chance to play around with this, but it looks promising.

like image 44
Chuu Avatar answered Sep 30 '22 17:09

Chuu