【问题标题】:.NET DateTime to time_t in seconds.NET DateTime 到 time_t 以秒为单位
【发布时间】:2011-11-05 20:05:26
【问题描述】:

有C代码:

time1=((double)dt1-25569.0)*86400.0;

它以秒为单位从 TDateTime (VCL) 转换为 time_t 格式,所以最后我需要从 .NET DateTime 获取 time_t 格式

关于时间_t:

几乎普遍认为它是一个整数值,表示 自 UTC 时间 1970 年 1 月 1 日 00:00 时起经过的秒数。这 是由于历史原因,因为它对应一个unix 时间戳,但在所有 C 库中广泛实现 平台。

为了在 .NET 中获得秒数,我正在这样做 (F#):

let seconds(dt : DateTime) =
    (dt.Ticks/10000000L)

或在 C# 上(使用更流行的 C# 标签):

Int64 seonds(DateTime dt)
{ return (dt.Ticks/ ((Int64)10000000)); } 
// hope it works, but please correct if I mistaken

据我了解,时间是 0001 年 1 月 1 日 12:00:00 UTC。

所以要使用 time_t 格式,我需要以秒为单位添加 1970 年。

所以最终函数必须是(F#):

let seconds(dt : DateTime) =
    (dt.Ticks/10000000L) + 31536000*1970

C#:

Int64 seonds(DateTime dt)
{ return (dt.Ticks/ ((Int64)10000000)) + 31536000*1970; } 

我真的害怕我在这里犯了错误。 请检查此解决方案!(检查是否正确)

谢谢

【问题讨论】:

  • 我不会只添加 1970 年作为秒,因为闰年​​是上下文的一部分...

标签: c# .net c++ datetime f#


【解决方案1】:

【讨论】:

  • 奇怪的是,这不会产生与 C 标准库时间函数相同的值!
  • @jheriko 也许两者之一都考虑了夏令时...在计算中明确使用 UTC 可能值得一试...
  • 在我使用过的地方,差异非常大。最后,我使用 p/invoke 和 msvcrt 来获得正确的值。作为猜测,问题在于 time_t 忽略了 UTC 没有的闰秒。 (所以即使从概念上讲,这段代码也是错误的)
  • @jheriko UTC 确实是关键,幸运的是,您可以使用托管代码获得与 p/invoke 相同的结果 - 请参阅 my answer
【解决方案2】:

这似乎有点整洁?如果您经常使用它,您可以将时代设为静态日期时间。

DateTime date = DateTime.Now;
DateTime epoch = new DateTime(1970, 1, 1);
TimeSpan span = (date - epoch);
double unixTime = span.TotalSeconds;

【讨论】:

  • 我喜欢静态时代的想法
【解决方案3】:

我建议使用以下代码。似乎更能传达代码的意思

private static readonly DateTime REFERENCE = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

Int64 seconds(DateTime dt)
{
  return (dt - REFERENCE).TotalSeconds;
}

【讨论】:

    【解决方案4】:

    在 C# 中:

    Int64 Secs(DateTime dt)
    {
        var delta = dt - new DateTime(1970, 1, 1);
        return Convert.ToInt64(delta.TotalSeconds);
    }
    

    【讨论】:

      【解决方案5】:

      在阅读了@jheriko 对the accepted answer 的评论后,我编写了一个快速控制台应用程序来测试 msvcrt.dll 中的 time() 是否对使用托管日期/时间函数的计算产生不同的结果,幸运的是它们没有,前提是使用 UTC。一般来说,只要有可能,日期和时间都应以 UTC 作为通用基准进行计算和存储,然后在必要时转换回相关时区进行显示。

      作为参考,并说明得出 1970 年 1 月 1 日到现在之间秒数的不同方法,我的测试代码是:

      class Program
      {
          [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
          public unsafe static extern int time(int* timer);
      
          static unsafe void Main(string[] args)
          {
              DateTime now = DateTime.Now;
              DateTime utc_now = DateTime.UtcNow;
      
              int time_t_msvcrt = time(null);
              int time_t_managed = (int)Math.Floor((now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
              int time_t_managed_2 = (int)Math.Floor((utc_now - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
      
              Console.WriteLine(time_t_msvcrt == time_t_managed);
              Console.WriteLine(time_t_msvcrt == time_t_managed_2);
      
              DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
              DateTime time_t_now = epoch.Add(TimeSpan.FromSeconds(time_t_msvcrt));
      
              long now_secs = now.Ticks / 10000000L;
              long utc_now_secs = utc_now.Ticks / 10000000L;
              long time_t_now_secs = time_t_now.Ticks / 10000000L;
      
              Console.WriteLine(time_t_now_secs == now_secs);
              Console.WriteLine(time_t_now_secs == utc_now_secs);
              Console.ReadLine();
          }
      }
      

      这会产生输出

      True
      True
      True
      True
      

      正如预期的那样。

      【讨论】:

        猜你喜欢
        • 2015-08-31
        • 2013-10-28
        • 2019-08-08
        • 1970-01-01
        • 1970-01-01
        • 2011-08-22
        • 1970-01-01
        • 2019-02-24
        • 1970-01-01
        相关资源
        最近更新 更多