views:

175

answers:

4

I'm making a program in which I need to get the time in milliseconds. By time, I mean a number that is never equal to itself, and is always 1000 numbers bigger than it was a second ago. I've tried converting DateTime.Now to a TimeSpan and getting the TotalMilliseconds from that... but I've heard it isn't perfectly accurate.

Is there an easier way to do this?

+1  A: 

the DateTime.Ticks property gets the number of ticks that represent the date and time.
10,000 Ticks is a millisecond.

Itay
But the resolution of Ticks is very less than 1/10000s, maybe 1/62s
codymanix
@codymanix - from MSDN: `A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.`
Itay
Sure it is, but the operating system does not have the resolution to be this exact.
codymanix
@codymanix is correct. By analogy, an Angstrom is a unit of length; ten billion Angstroms make one metre. You could write a function that reports your height as a 64 bit integer in Angstroms, but if all you have is a metrestick accurate to the centimetre, then the fact that the function represents sub-nanometre precision is completely irrelevant. The less-significant digits are going to be garbage.
Eric Lippert
@Itay: It's like telling someone your age in milliseconds — by the time you have said it, it is wrong.
RedFilter
@RedFilter: If you actually knew your age to the nearest millisecond, you could conceivably say something like, "When I blink again, my age will be x milliseconds." The deeper problem is not communication but measurement: your birth is unlikely to be known even to the nearest second.
Steven Sudit
+8  A: 

Use the Stopwatch class.

Provides a set of methods and properties that you can use to accurately measure elapsed time.

There is some good info on implementing it here:

Performance Tests: Precise Run Time Measurements with System.Diagnostics.Stopwatch

RedFilter
stopwatch is part of Diagnostics. Should it be used in real code?
Andrey
@Andrey - http://stackoverflow.com/questions/2805362/can-stopwatch-be-used-in-production-code/2805409#2805409
John Rasch
This is normally only accurate to the nearest 15ms or so.
Steven Sudit
how expensive is it though? maybe we should stopwatch a stopwatch :)
jb
@Steven, that depends on the OS and the underlying hardware. If available a high resolution timer is used, which is the case for all current desktop and server based x86 Windows versions I am aware of. Check the Frequency and IsHighResolution properties for more details. At the OS level, QueryPerformanceCounter and QueryPerformanceFrequency are the low-level APIs that back this functionality.
Chris Taylor
@Chris: Good point. On my machine, Stopwatch reports a resolution of 2467773 ticks per second. However, if I get ElapsedTicks for a running stopwatch twice in a row, it often returns the same value both times. This is still not good enough to create a unique timestamp. Also, the high-resolution clock can be distorted by power-saving options on some CPU's.
Steven Sudit
As an update, I tried the same sort of test, using Stopwatch.GetTimestamp() but was unable to get a pair of values closer than 4 ticks apart.
Steven Sudit
+1  A: 

You can try the QueryPerformanceCounter native method. See http://www.pinvoke.net/default.aspx/kernel32/QueryPerformanceCounter.html for more information. This is what the Stopwatch class uses.

See http://stackoverflow.com/questions/1416139/how-to-get-timestamp-of-tick-precision-in-net-c for more information.

Stopwatch.GetTimestamp() gives access to this method:

public static long GetTimestamp() {
     if(IsHighResolution) {
         long timestamp = 0;
         SafeNativeMethods.QueryPerformanceCounter(out timestamp);
         return timestamp;
     }
     else {
         return DateTime.UtcNow.Ticks;
     }
 }
Pieter
AFAIK StopWatch uses QueryPerformanceCounter internally if available
codymanix
Yep, the internal implementation of `Stopwatch.GetTimestamp()` actually provides access to that method.
Pieter
+1  A: 
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
Evan Mulawski
For the reasons explained in other answers, what you suggest is not helpful.
Steven Sudit