Get time in milliseconds using C#
Asked Answered
H

10

176

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?

Harleyharli answered 25/10, 2010 at 16:3 Comment(3)
Are you expecting any two calls to always lead increasing values? In general, calls closer than the minimum interval that the timer resolution allows will yield the same value. You would need to add your own tiebreaker in the form of a fake-precision serializer.Eicher
"A number that is never equal to itself". That sounds... complicated. ;)Partida
NaN would fit that requirement actually. Despite being "not a number", it is a number type, and it is not equal to itself.Borodino
S
83

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

Sublieutenant answered 25/10, 2010 at 16:5 Comment(9)
stopwatch is part of Diagnostics. Should it be used in real code?Lilli
@Lilli - #2805862Psyche
This is normally only accurate to the nearest 15ms or so.Eicher
how expensive is it though? maybe we should stopwatch a stopwatch :)Nation
@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.Apprehensible
@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.Eicher
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.Eicher
This should not be the answer. The question is how to get the current time in milliseconds. Not record the passing of time.Aldrin
@KirbyL.Wallace You may be right, there is a lack of clarity in the question. My answer may work or it may not. It is NOT a good solution if the number needs to be different across different runs, which is not clear. I selected the Stopwatch class as it has more precision than the DateTIme class, and the user indicated that was a concern.Actual
H
437
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

This is actually how the various Unix conversion methods are implemented in the DateTimeOffset class (.NET Framework 4.6+, .NET Standard 1.3+):

long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();
Humorist answered 25/10, 2010 at 16:7 Comment(8)
The title is "get time in milliseconds". This answer is helpful.Mcgill
Yup, for those of us searching for an answer to the question as posed, this was very helpful, thank you.Avantgarde
If you want decimals (even if DateTime.Now is not "updated" very often), of course use decimal milliseconds = DateTime.Now.Ticks / (decimal)TimeSpan.TicksPerMillisecond; instead.Hindustan
This is much more useful than the selected answer for search results and even for what I gather from the original question.Salvidor
Note that the "epoc" (beginning of time) for DateTime.Ticks is the year 1, rather than the year 1970 for System.currentTimeMillis() ;)Spearwort
This answer saved my life. Got similar code but doesn't work. Couldn't figure out why. Then I saw the long datatype in front of milliseconds. Using int certainly gonna overflow.Beutler
I was looking for the C#.NET equivalent of the millis() function commonly used within Arduino sketches (C). Perfect, replacementAluminum
DateTimeOffset.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt") to get the millisecond in the format of "07/16/2008 08:32:45.126 AM"Continuate
S
83

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

Sublieutenant answered 25/10, 2010 at 16:5 Comment(9)
stopwatch is part of Diagnostics. Should it be used in real code?Lilli
@Lilli - #2805862Psyche
This is normally only accurate to the nearest 15ms or so.Eicher
how expensive is it though? maybe we should stopwatch a stopwatch :)Nation
@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.Apprehensible
@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.Eicher
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.Eicher
This should not be the answer. The question is how to get the current time in milliseconds. Not record the passing of time.Aldrin
@KirbyL.Wallace You may be right, there is a lack of clarity in the question. My answer may work or it may not. It is NOT a good solution if the number needs to be different across different runs, which is not clear. I selected the Stopwatch class as it has more precision than the DateTIme class, and the user indicated that was a concern.Actual
T
19

The DateTime.Ticks property gets the number of ticks that represent the date and time.

10,000 Ticks is a millisecond (10,000,000 ticks per second).

Tropic answered 25/10, 2010 at 16:5 Comment(6)
But the resolution of Ticks is very less than 1/10000s, maybe 1/62sDravidian
@Dravidian - from MSDN: A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.Tropic
Sure it is, but the operating system does not have the resolution to be this exact.Dravidian
@Dravidian 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.Autochthonous
@Itay: It's like telling someone your age in milliseconds — by the time you have said it, it is wrong.Actual
@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.Eicher
O
13

I use the following class. I found it on the Internet once, postulated to be the best NOW().

/// <summary>Class to get current timestamp with enough precision</summary>
static class CurrentMillis
{
    private static readonly DateTime Jan1St1970 = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    /// <summary>Get extra long current timestamp</summary>
    public static long Millis { get { return (long)((DateTime.UtcNow - Jan1St1970).TotalMilliseconds); } }
}

Source unknown.

Odetteodeum answered 24/2, 2013 at 12:59 Comment(2)
FWIW, the entire point of this commonly used snippet, is to make a timestamp that is compatible with the Unix timestamp standard. For that, it is vital. If one just wants to do timing, it is unnecessarily expensive.Dav
This is useful when need to pass milliseconds to java from C#Huihuie
A
8

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 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;
     }
 }
Anaplastic answered 25/10, 2010 at 16:6 Comment(2)
AFAIK StopWatch uses QueryPerformanceCounter internally if availableDravidian
Yep, the internal implementation of Stopwatch.GetTimestamp() actually provides access to that method.Anaplastic
U
7

I used DateTime.Now.TimeOfDay.TotalMilliseconds (for current day), hope it helps you out as well.

Uella answered 17/8, 2012 at 9:57 Comment(2)
that won't return increasing values (as the original poster required) since TimeOfDay is reset to zero everyday at midnight. Plus it would have the same potential issues that the poster mentioned when just using DateTime.Now an getting the total milliseconds from that.Lalonde
Jim O'Neil I agree with u, that is why I mentioned "(for current day)" in my post... Btw, my solution worked for my problem, as my problem is not date-specific, I simply needed to get the Milliseconds part to be used as a counter, so I posted it here. I am new here, so if I posted it in a wrong place am sorry :)Uella
G
2

Use System.DateTime.Now.ToUniversalTime(). That puts your reading in a known reference-based millisecond format that totally eliminates day change, etc.

Glenoid answered 17/9, 2012 at 17:7 Comment(1)
Good to know, but not relevant to the question being asked, which is about timing (measurement of time passage), not about accurately communicating time.Dav
P
2

Using Stopwatch class we can achieve it from System.Diagnostics.

Stopwatch stopwatch  = new Stopwatch();
stopwatch.Start();
stopwatch.Stop();
Debug.WriteLine(stopwatch.ElapsedMilliseconds);
Peoria answered 25/11, 2020 at 6:0 Comment(0)
C
1

System.DateTimeOffset.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt") to get the millisecond in the format of '04/01/2021 04:32:14.788 PM'

https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-display-milliseconds-in-date-and-time-values

Continuate answered 1/4, 2021 at 23:34 Comment(0)
C
1

As I understand your requirements Environment.TickCount fits the bill. It returns number of milliseconds since startup, so it always increases and can be used for computing elapsed time in milliseconds. If you want absolute time also, you can get current time and current Environment.TickCount, and compute new absolute time based on that and new Environment.TickCount.

Chuckhole answered 5/9, 2021 at 13:52 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.