172

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Entity
  • 7,972
  • 21
  • 79
  • 122
  • 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. – Steven Sudit Oct 25 '10 at 16:29
  • 21
    "A number that is never equal to itself". That sounds... complicated. ;) – Mizipzor Aug 17 '12 at 10:00
  • 2
    NaN would fit that requirement actually. Despite being "not a number", it is a number type, and it is not equal to itself. – Yay295 Feb 04 '18 at 19:29

10 Answers10

429
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();
Evan Mulawski
  • 54,662
  • 15
  • 117
  • 144
  • 78
    The title is "get time in milliseconds". This answer is helpful. – Aerospace Jan 21 '14 at 10:10
  • 40
    Yup, for those of us searching for an answer to the question as posed, this was very helpful, thank you. – user430788 Feb 09 '14 at 16:51
  • 1
    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. – Jeppe Stig Nielsen Mar 03 '14 at 14:43
  • 1
    This is much more useful than the selected answer for search results and even for what I gather from the original question. – bwoogie Dec 21 '16 at 20:05
  • Note that the "epoc" (beginning of time) for `DateTime.Ticks` is the year 1, rather than the year 1970 for `System.currentTimeMillis()` ;) – Svend Hansen Jan 20 '17 at 14:26
  • 1
    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. – FisNaN Mar 28 '18 at 21:12
  • I was looking for the C#.NET equivalent of the millis() function commonly used within Arduino sketches (C). Perfect, replacement – NadimAJ Dec 29 '20 at 09:51
  • `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" – Efreeto Apr 01 '21 at 23:33
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

D'Arcy Rittich
  • 167,292
  • 40
  • 290
  • 283
  • 8
    stopwatch is part of Diagnostics. Should it be used in real code? – Andrey Oct 25 '10 at 16:08
  • 5
    @Andrey - http://stackoverflow.com/questions/2805362/can-stopwatch-be-used-in-production-code/2805409#2805409 – John Rasch Oct 25 '10 at 16:10
  • This is normally only accurate to the nearest 15ms or so. – Steven Sudit Oct 25 '10 at 16:29
  • 12
    how expensive is it though? maybe we should stopwatch a stopwatch :) – jb. Oct 25 '10 at 16:38
  • 3
    @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 Oct 25 '10 at 18:07
  • @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 Oct 25 '10 at 19:30
  • 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 Oct 25 '10 at 19:32
  • This should not be the answer. The question is how to get the current time in milliseconds. Not record the passing of time. – KWallace Dec 10 '20 at 20:00
  • @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. – D'Arcy Rittich Dec 14 '20 at 16:31
18

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).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Itay Karo
  • 17,924
  • 4
  • 40
  • 58
  • 5
    But the resolution of Ticks is very less than 1/10000s, maybe 1/62s – codymanix Oct 25 '10 at 16:11
  • 2
    @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 Karo Oct 25 '10 at 16:13
  • 7
    Sure it is, but the operating system does not have the resolution to be this exact. – codymanix Oct 25 '10 at 16:18
  • 6
    @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 Oct 25 '10 at 17:58
  • @Itay: It's like telling someone your age in milliseconds — by the time you have said it, it is wrong. – D'Arcy Rittich Oct 25 '10 at 19:55
  • 4
    @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 Oct 25 '10 at 20:14
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.

schmijos
  • 8,114
  • 3
  • 50
  • 58
  • 5
    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. – ToolmakerSteve Sep 23 '15 at 09:26
  • This is useful when need to pass milliseconds to java from C# – Nick Oct 30 '20 at 10:41
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;
     }
 }
Community
  • 1
  • 1
Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111
6

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

Sarvan
  • 706
  • 8
  • 16
  • 1
    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. – Jim O'Neil Aug 18 '12 at 02:26
  • 3
    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 :) – Sarvan Aug 19 '12 at 10:51
2

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
John Tobler
  • 404
  • 2
  • 14
  • Good to know, but not relevant to the question being asked, which is about timing (measurement of time passage), not about accurately communicating time. – ToolmakerSteve Sep 23 '15 at 09:29
2

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

Stopwatch stopwatch  = new Stopwatch();
stopwatch.Start();
stopwatch.Stop();
Debug.WriteLine(stopwatch.ElapsedMilliseconds);
Vijendran Selvarajah
  • 1,330
  • 1
  • 11
  • 31
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.

runec
  • 1,687
  • 12
  • 22
0

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

Efreeto
  • 2,132
  • 1
  • 24
  • 25