98

What is the equivalent of Java's System.currentTimeMillis() in C#?

3
  • Just curious, why do you need the millis since 1970? Commented Nov 14, 2008 at 16:00
  • 7
    DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() Commented May 30, 2018 at 11:06
  • @AlexB some systems store date and time in UnixTimeMIlliseconds format. In order to write a query like "between A and B" you must convert your datetime value to milliseconds then compare Commented Oct 13, 2023 at 15:54

11 Answers 11

101

An alternative:

// Use DateTime.UnixEpoch as of .NET or .NET Core 2.1 upwards; // not available in .NET Framework private static readonly DateTime Jan1st1970 = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public static long CurrentTimeMillis() { return (long) (DateTime.UtcNow - Jan1st1970).TotalMilliseconds; } 
Sign up to request clarification or add additional context in comments.

3 Comments

Same result with "DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()"
There is a DateTime.UnixEpoch now that can replace the read-only value above.
@PeterL: But not in .NET Framework, sadly :(
79

A common idiom in Java is to use the currentTimeMillis() for timing or scheduling purposes, where you're not interested in the actual milliseconds since 1970, but instead calculate some relative value and compare later invocations of currentTimeMillis() to that value.

If that's what you're looking for, the C# equivalent is Environment.TickCount.

3 Comments

But they both give difference numbers.How they compare correctly?? C# give : 2688547 and Java give : 1390707872687
@Elshan You can't compare them. They're different ticks. This technique is for timing and scheduling within an application, not across applications.
System.currentTimeMillis() returns UTC time in ms since 1970, while Environment.TickCount returns ms since the app started. System.currentTimeMillis() is good for checking elapsed time, but if you want two durations to be comparable you must use System.nanoTime().
18
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() 

1 Comment

That DateTimeOffset method was introduced as of .Net 4.6.
16

If you are interested in TIMING, add a reference to System.Diagnostics and use a Stopwatch.

For example:

var sw = Stopwatch.StartNew(); ... var elapsedStage1 = sw.ElapsedMilliseconds; ... var elapsedStage2 = sw.ElapsedMilliseconds; ... sw.Stop(); 

Comments

7

the System.currentTimeMillis() in java returns the current time in milliseconds from 1/1/1970

c# that would be

public static double GetCurrentMilli() { DateTime Jan1970 = new DateTime(1970, 1, 1, 0, 0,0,DateTimeKind.Utc); TimeSpan javaSpan = DateTime.UtcNow - Jan1970; return javaSpan.TotalMilliseconds; } 

edit: made it utc as suggested :)

1 Comment

DateTime.Now uses the local time, not UTC. I don't know exactly what happens when you subtract an unknown kind of DateTime from a local one, but it's best to set both of them to UTC :)
7

We could also get a little fancy and do it as an extension method, so that it hangs off the DateTime class:

public static class DateTimeExtensions { private static DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public static long currentTimeMillis(this DateTime d) { return (long) ((DateTime.UtcNow - Jan1st1970).TotalMilliseconds); } } 

4 Comments

Isn't this a bit wrong? This extension method will hand on to any instance of DateTime, but it doesn't use the instance. Just seems confusing...I don't think you should require a parameter that you don't use
@mortb That's an extension method. That is how it gets defined in C# to "add a method" to a class without modifying the class. The compiler interprets the method and can apply it to an instance of the "this" parameter as if it were an instance method on the class itself. It functions just the same as a method on the static class but the compiler allows writing an easier, alternate syntax.
The problem is that the value of the parameter dis not used. To use this code you could write var date = new DateTime(); var millis = date.currentTimeMillis(); But the date variable would just be redundant and its state never used. When not using the state of the object creating an extension method just obscures the code. The answer provided by @Hath is more straight forward and therefore better (to me). Maybe @Joel Coehoorn intended to use the value d instead of DateTime.UtcNow in the method body? I use extension methods quite a lot, but not for this.
Why would you create an extension, that doesn't use the date? I used this code and it caught me out. The correct version is: return (long)((d.ToUniversalTime() - Jan1st1970).TotalMilliseconds);
4

The framework doesn't include the old seconds (or milliseconds) since 1970. The closest you get is DateTime.Ticks which is the number of 100-nanoseconds since january 1st 0001.

1 Comment

Would (DateTime.Ticks/10000000)-(the number of seconds between 0001 and 1970) give an accurate answer?
4

Here is a simple way to approximate the Unix timestamp. Using UTC is closer to the unix concept, and you need to covert from double to long.

TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)); long millis = (long)ts.TotalMilliseconds; Console.WriteLine("millis={0}", millis); 

prints:

millis=1226674125796 

Comments

4

I just consider the most straight forward way how to achieve what you've been striving for as follows:

DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond 

1 Comment

DateTime.UtcNow is a better option
2

If you want a timestamp to be compared between different processes, different languages (Java, C, C#), under GNU/Linux and Windows (Seven at least):

C#:

private static long nanoTime() { long nano = 10000L * Stopwatch.GetTimestamp(); nano /= TimeSpan.TicksPerMillisecond; nano *= 100L; return nano; } 

Java:

java.lang.System.nanoTime(); 

C GNU/Linux:

static int64_t hpms_nano() { struct timespec t; clock_gettime( CLOCK_MONOTONIC, &t ); int64_t nano = t.tv_sec; nano *= 1000; nano *= 1000; nano *= 1000; nano += t.tv_nsec; return nano; } 

C Windows:

static int64_t hpms_nano() { static LARGE_INTEGER ticksPerSecond; if( ticksPerSecond.QuadPart == 0 ) { QueryPerformanceFrequency( &ticksPerSecond ); } LARGE_INTEGER ticks; QueryPerformanceCounter( &ticks ); uint64_t nano = ( 1000*1000*10UL * ticks.QuadPart ) / ticksPerSecond.QuadPart; nano *= 100UL; return nano; } 

Comments

1

I know question asks for equivalent but since I use those 2 for the same tasks I throw in GetTickCount. I might be nostalgic but System.currentTimeMillis() and GetTickCount() are the only ones I use for getting ticks.

[DllImport("kernel32.dll")] static extern uint GetTickCount(); // call uint ticks = GetTickCount(); 

Comments