【问题标题】:.Net Core equivalent to $(date +%s%N).Net Core 相当于 $(date +%s%N)
【发布时间】:2021-10-15 08:26:29
【问题描述】:

当我运行这个 Linux shell 命令$(date +%s%N) 我得到:1628718908367130365

我希望能够在我的 .Net Core 3.1 应用程序中获得此值。

这是我尝试过的,它给了我什么:

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

但这些都不相同。 Ticks 选项的精度似乎最接近,但并不相同。

是否有可能使用 .Net Core 获取此日期值?

【问题讨论】:

    标签: c# linux asp.net-core .net-core .net-core-3.1


    【解决方案1】:

    您的 linux 命令为您提供纳秒级精度。一个滴答声是 100 纳秒。 (见:https://docs.microsoft.com/en-us/dotnet/api/system.datetime.ticks?view=net-5.0#remarks)。

    如果您真的需要纳秒级精度,我认为标准库无法实现(请参阅:Is there a high resolution (microsecond, nanosecond) DateTime object available for the CLR?)。

    您真的需要纳秒级的精度,还是只需要生成一个具有纳秒级值的结构?如果是后者,您可以乘以 100,就像在 Microsoft 示例中一样:

    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
    

    此外,刻度使用 2000 年 1 月 1 日作为起始时间,而 Unix 时间使用 1970 年 1 月 1 日作为起始时间。你必须考虑到这一点。举例说明:

    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}");
            
        }
    }
    

    输出:

    提供的 unix 时间戳:1628718908367130365

    毫秒精度的unix时间:1628718908367

    具有纳米(假)精度的 unix 时间:1628718908367000000

    自微软时代以来的滴答声:637643157083670000

    自 unix 纪元以来的滴答声:16287189083670000

    类 unix 格式的 100 倍:1628718908367000000

    见: https://dotnetfiddle.net/fEdprI

    【讨论】:

    • 我不需要纳秒精度,Ticks 就足够了。但数字不匹配。 $(date +%s%N) = 1628718908367130365 和elapsedTicks * 100 = 650394508216294100。它们是从不同的时间点开始的吗? (一个是 19 个字符,第二个是 18 个字符)
    • Ticks 以 2000 年 1 月 1 日为起点。 Unix 时间使用 1970 年 1 月 1 日作为开始时间,所以这就是您看到差异的原因。我将使用显示这一点的示例更新我的答案。
    • 完美!非常感谢! (我为我的时区添加了testDateTime = testDateTime.AddHours(6);,现在它完美匹配!)
    【解决方案2】:

    阅读this blog 和乔纳森的回答后。我可以为您提供更好的解决方案。

    不过我想到了一个可行的解决方案,execute linux command in .net core,也许对你有用。

    【讨论】:

      猜你喜欢
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 2010-10-18
      • 2020-03-08
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      相关资源
      最近更新 更多