【问题标题】:how to find the number nanoseconds elapsed since 01/JAN/1970 00:00:00 (UTC)?如何找到自 01/JAN/1970 00:00:00 (UTC) 以来经过的纳秒数?
【发布时间】:2019-05-02 21:26:07
【问题描述】:

我试图了解如何找到自 01/JAN/1970 00:00:00 以来经过的纳秒数。

我在互联网上找不到任何示例(或解释如何在不参考代码的情况下进行计算) 我在 Windows 上使用 C++11。

【问题讨论】:

  • 这将导致一个相当大的数字。为什么你真的需要这样做?
  • @πάνταῥεῖ 我对巨大数字的大小没有任何问题。我只是需要它来开发我正在开发的东西
  • 那么首先你必须提供一个合适的数据类型来保存这个数字。 “我只是需要它来开发我正在开发的东西”好吧,你可能会走错路。
  • @πάνταῥεῖ 你能解释一下 - 你是什么意思?我不明白。如果有任何示例代码
  • @πάνταῥεῖ 自 1970 年以来保持纳秒的有符号 64 位整数在 2262 年之前不会翻转。这不是一种奇异的数据类型。

标签: c++ c++11 utc


【解决方案1】:

您可以使用 time_since_epoch() 方法将 time_point 转换为 duration,这将给出自 1970 年 1 月 1 日以来的时间单位数。

然后,您只需将持续时间转换为纳秒。我可以用相对简单的代码做到这一点:

#include<iostream>
#include<chrono>

int main() {
    //Use system_clock, not steady_clock, or you will not get correct values!
    auto now = std::chrono::system_clock::now().time_since_epoch();
    auto now_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(now);
    //Also valid, but doesn't convey programmer intent:
    //std::chrono::nanoseconds now_ns = now;
    std::cout << now_ns.count() << "ns" << std::endl;
}

在我正在测试的机器上,我得到以下输出:

1556833575688789496ns

注意两个潜在问题:

  • system_clock 没有特别高的精度。因此,您可能无法获得比几毫秒更准确的结果。
  • 如果您使用 C++20 进行编译,system_clock 仅保证将其纪元设置为 1 月 1 日。在之前的版本中,它通常是这样实现的,但是一些符合标准的 C++ 编译器可能不会使用这个 epoch,您需要进行验证。

【讨论】:

    【解决方案2】:

    这是我在之前的 cmets 中提到的特定于 Windows 的简单数学方法:

    #include <windows.h>
    #include <iostream>
    
    int main() {
      FILETIME now;
      FILETIME epoch_ft;
      SYSTEMTIME epoch_st = { 1970, 1, 4, 1, 0, 0, 0, 0 }; 
      GetSystemTimeAsFileTime(&now);
      SystemTimeToFileTime(&epoch_st, &epoch_ft);
    
      ULARGE_INTEGER nsecs, epoch_nsecs;
      nsecs.LowPart = now.dwLowDateTime;
      nsecs.HighPart = now.dwHighDateTime;
      epoch_nsecs.LowPart = epoch_ft.dwLowDateTime;
      epoch_nsecs.HighPart = epoch_ft.dwHighDateTime;
      nsecs.QuadPart -= epoch_nsecs.QuadPart;
    
      std::cout << "100-nsec periods since epoch: " << nsecs.QuadPart << '\n';
      return 0;
    }
    

    上面得到当前系统时间作为文件时间,以及纪元的文件时间,并将两者相减得到从纪元开始的100纳秒间隔数。

    Windows FILETIME自 1601 年 1 月 1 日以来的 100 纳秒间隔数。它没有实际的纳秒分辨率,我认为GetSystemTimeAsFileTime() 使用的分辨率与GetSystemTime() 一样是毫秒,但它可能与您将获得的方法一样准确。如果使用 Windows 8、Server 2012 或更高版本,还可以使用 GetSystemTimePreciseAsFileTime() 来获得支持的最高精度。

    【讨论】:

      【解决方案3】:

      您可以使用std::chrono::system_clock - 请参阅https://en.cppreference.com/w/cpp/chrono/system_clock。 在 C++20 之前,实际上并没有说明这个时钟是在 1970 年还是其他时间开始的(又名“纪元”),但 C++20 将保证那实际上是纪元,您应该验证您的 Windows 编译器是否已经符合这个要求(我猜是这样,但没有 Windows 来确认)。

      要获取纳秒数,您可以使用std::chrono::duration_cast - https://en.cppreference.com/w/cpp/chrono/duration/duration_cast - 将时钟大小写为std::chrono::nanoseconds,然后使用.time_since_epoch().count() 检索实际的纳秒数。但是,不能保证它的分辨率是多少......您可能无法用它测量单个纳秒 - 分辨率可能只是微秒、毫秒或任何值,即使指定为纳秒也是如此。你需要检查一下。

      【讨论】:

      • 分辨率为纳秒。精度可能会更低。
      • 我不确定您对“分辨率”和“精度”这两个词的区分是否正确。请注意,“高分辨率”意味着能够解析更小的间隔,C++ 使用这个术语,例如,在其“high_resolution_clock”中。 std::chrono::nanoseconds 中的纳秒不是“分辨率”,而是单位(或 C++ 称之为“周期”)。在时钟中,“精度”通常完全是另外一回事——你离完美的原子钟有多远。
      猜你喜欢
      • 2012-03-14
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 2019-12-01
      • 2012-02-19
      • 1970-01-01
      • 2012-12-29
      • 2015-04-12
      相关资源
      最近更新 更多