2

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?
Akif
  • 7,098
  • 7
  • 27
  • 53
Uylenburgh
  • 1,277
  • 4
  • 20
  • 46
  • There are three starting times 1) 1/1/01 2) 1/1/1900 3) 1/1/1970 Which one do you have? – jdweng Dec 07 '20 at 17:48
  • 1
    You mention `DateTime`, `TimeStamp`, converting to milliseconds but refusing to use `DateTime.TotalMilliseconds` and some random assumptions about the internals of `DateTime`. Can you order your thoughts and just ask what you need to ask? – Blindy Dec 07 '20 at 17:50
  • 1
    @Blindy - `TotalMilliseconds` is not a property of `DateTime`. You may be thinking of `TimeSpan`, which is different. – Matt Johnson-Pint Dec 07 '20 at 17:59

2 Answers2

8

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.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
3

Okay, so you start off dividing Ticks by System.TimeSpan.TicksPerMillisecond (10,000)

As you can see, the number you generated is much larger than the current milliseconds:

63739786274788

1607363529803

The short answer is that Ticks are based off of 12:00:00 midnight January 1, 0001 and a your online calculator is based off of unix time, January 1, 1970. So that would explain why you're about 2,000 years off. If you subtracted the Ticks from a new DateTime(1970,1,1), then that would give you about the right number to satisfy the online calculator.

For more info, I would suggest reading through MS's docs on DateTime

Gauthier
  • 1,251
  • 10
  • 25
Dan Csharpster
  • 2,662
  • 1
  • 26
  • 50