Search code examples
c#linuxasp.net-core.net-core.net-core-3.1

.Net Core equivalent to $(date +%s%N)


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?


Solution

  • 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