0

When I run this Linux shell command $(date +%s%N) I get: 1628718908367130365

I would like to be able to get this value in my .Net Core 3.1 application.

This is what I have tried and what it gave me:

  • DateTime.Now.Ticks: 637642942785036026
  • DateTimeOffset.Now.ToUnixTimeMilliseconds(): 1628719160465

But none of these are the same. The Ticks option seems to be the closest in precision, but it is not the same.

Is it possible, using .Net Core, to get this date value?

Vaccano
  • 78,325
  • 149
  • 468
  • 850

2 Answers2

1

Your linux command is giving you nanosecond precision. A tick is 100 nanoseconds. (see: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.ticks?view=net-5.0#remarks).

If you truly need the nanosecond precision, I don't think it's possible with standard libraries (see: Is there a high resolution (microsecond, nanosecond) DateTime object available for the CLR?).

Do you truly need the nanoseconds of precision, or just to generate a structure that has a value for the nanoseconds? If the latter, you could multiply by 100, like in the Microsoft example:

DateTime centuryBegin = new DateTime(2001, 1, 1);
DateTime currentDate = DateTime.Now;

long elapsedTicks = currentDate.Ticks - centuryBegin.Ticks;
TimeSpan elapsedSpan = new TimeSpan(elapsedTicks);

Console.WriteLine("Elapsed from the beginning of the century to {0:f}:",
                   currentDate);
Console.WriteLine("   {0:N0} nanoseconds", elapsedTicks * 100);
Console.WriteLine("   {0:N0} ticks", elapsedTicks);
Console.WriteLine("   {0:N2} seconds", elapsedSpan.TotalSeconds);
Console.WriteLine("   {0:N2} minutes", elapsedSpan.TotalMinutes);
Console.WriteLine("   {0:N0} days, {1} hours, {2} minutes, {3} seconds",
                  elapsedSpan.Days, elapsedSpan.Hours,
                  elapsedSpan.Minutes, elapsedSpan.Seconds);

// This example displays an output similar to the following:
//
// Elapsed from the beginning of the century to Thursday, 14 November 2019 18:21:
//    595,448,498,171,000,000 nanoseconds
//    5,954,484,981,710,000 ticks
//    595,448,498.17 seconds
//    9,924,141.64 minutes
//    6,891 days, 18 hours, 21 minutes, 38 seconds

Additionally, ticks use Jan 1, 2000 as their starting point while Unix time uses Jan 1, 1970 as its starting time. You would have to account for this. A sample to illustrate:

using System;
                    
public class Program
{

    public static void Main()
    {
        // provided Unix string = "1628718908367130365";
        // the above, converted via https://www.unixtimestamp.com/index.php, returns the following:
        // Wed Aug 11 2021 21:55:08 GMT+0000 (to the seconds), plus:
        // milliseconds: 367
        // microseconds: 130
        // nanoseconds: 365
        Console.WriteLine($"provided unix timestamp:              1628718908367130365");
    
        var testDateTime = new DateTime(2021, 08, 11, 21, 55, 08, 367); // millisecond precision
        var testDto = new DateTimeOffset(testDateTime);
        
        var asUnixTime = testDto.ToUnixTimeMilliseconds();
        Console.WriteLine($"unix time with milli precision:       {asUnixTime}");
        Console.WriteLine($"unix time with nano (fake) precision: {asUnixTime * 1000 * 1000}");
        
        var asTicks = testDateTime.Ticks;
        Console.WriteLine($"ticks since microsoft epoch:          {asTicks}");
        
        var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        TimeSpan span = testDateTime - unixEpoch;
        Console.WriteLine($"ticks since unix epoch:               {span.Ticks}");
        Console.WriteLine($"times 100 for unix-like format:       {span.Ticks * 100}");
        
    }
}

Output:

provided unix timestamp: 1628718908367130365

unix time with milli precision: 1628718908367

unix time with nano (fake) precision: 1628718908367000000

ticks since microsoft epoch: 637643157083670000

ticks since unix epoch: 16287189083670000

times 100 for unix-like format: 1628718908367000000

See: https://dotnetfiddle.net/fEdprI

Jonathan
  • 4,916
  • 2
  • 20
  • 37
  • I don't need nanosecond precision, Ticks is enough. But the numbers don't match up. The `$(date +%s%N)` = 1628718908367130365 and `elapsedTicks * 100` = 650394508216294100. Do they start from different time points? (One is 19 chars and the second is 18 chars) – Vaccano Aug 11 '21 at 23:09
  • Ticks use Jan 1, 2000 as their starting point. Unix time uses Jan 1, 1970 as its starting time, so that's why you're seeing the difference. I'll update my answer with a sample that shows this. – Jonathan Aug 12 '21 at 15:49
  • Perfect! Thank you very much! (I added `testDateTime = testDateTime.AddHours(6);` for my timezone and now it is matching up perfectly!) – Vaccano Aug 12 '21 at 17:43
0

After read this blog and Jonathan's answer. I can get more better solution for you.

But I think of a feasible solution, execute linux command in .net core, maybe it will be useful to you.

Jason Pan
  • 15,263
  • 1
  • 14
  • 29