Search code examples
c#datetimetimestampunix-timestamp

Get Milliseconds from Ticks in DateTime c#


I have a simple DateTime object, equal to the date: 11/1/2020 8:11:14 AM.

I want to convert it to milliseconds so I do: myTimestamp?.Ticks / TimeSpan.TicksPerMillisecond.

I get 63739786274788, which seems correct from the pure calculation perspective.

However, when I input it into one of the online converters to validate, I get the date Wed Nov 01 3989 01:11:14, which is of course way off.

Questions:

  1. What is this number 63739786274788 if not time in ms?
  2. How do I get "normal" timestamp in ms?

Solution

  • In .NET, DateTime ticks are based on an epoch of 0001-01-01T00:00:00.0000000. The .Kind property is used to decide whether that is UTC, local time, or "unspecified".

    Most online converters, such as the one you linked to, are expecting a Unix Timestamp, where the value is based on an epoch of 1970-01-01T00:00:00.000Z. It is always UTC based. (The precision varies, both seconds and milliseconds are commonly used.)

    If you want to get a milliseconds-based Unix Timestamp From .NET, instead of dividing you should use the built-in functions DateTimeOffset.FromUnixTimeMilliseconds and DateTimeOffset.ToUnixTimeMilliseconds. (There are also seconds-based versions of these functions.)

    Assuming your input values are UTC-based:

    DateTime dt = new DateTime(2020, 11, 1, 8, 11, 14, DateTimeKind.Utc);
    DateTimeOffset dto = new DateTimeOffset(dt);
    long timestamp = dto.ToUnixTimeMilliseconds();
    
    // output:  1604218274000
    

    DateTimeKind.Local will also work with this, assuming your values are indeed based on the computer's local time zone. DateTimeKind.Unspecified is a bit trickier, as you'll need to convert to a DateTimeOffset with a specific time zone using TimeZoneInfo first.

    You could also construct the DateTimeOffset value directly, rather than go through DateTime at all.