【问题标题】:Store timestamps in nanoseconds c++以纳秒为单位存储时间戳c ++
【发布时间】:2017-04-17 12:32:30
【问题描述】:

我的目标是将时间戳存储在纳秒范围内。假设我有两台需要通信的机器,确切地说是在什么时候完成任务。

我们只是为了这个问题,假设它们是同步时钟。
机器 A 在完成后存储其本地时间。机器 B 传送到 A,此时它完成了。然后机器 A 计算差值。

我的问题是,时间差实际上可以达到 60 秒,但也可以低至 0.25 毫秒。所以我需要以一种我可以同时处理的方式存储时间,并计算时间差。

由于以纳秒为单位的纪元以来的时间是如此之大,我认为我无法将其存储在我知道的任何变量中。

您将如何应对这种情况?我目前的情况是,我可能(以某种方式)可以将自 ns 中的纪元以来的时间缩小到代表 1 分钟的位,尽管我不知道该怎么做。

希望你能帮忙。

最好的问候

【问题讨论】:

    标签: c++ c++11 time chrono


    【解决方案1】:

    只需使用 64 位整数,有符号 (int64_t) 或无符号 (uint64_t),一切都会好起来的。

    64 位空间真的很大。不仅存储时差就足够了,甚至存储绝对时间值,通常是从 1970 年 1 月 1 日午夜开始计算的时间。

    例如,现在自 1970-01-01 以来的秒数大致为:

    1492432621.123456789
    

    以纳秒为单位,这是:

    1492432621123456789
    

    为了比较,最大的有符号 64 位整数值为:

    9223372036854775807
    

    这大致对应于 2262-04-12,这个日期你几乎肯定不会再活着了。

    但是,如果您仍然担心您的软件可能运行了两个多世纪,在此期间不会得到改进,最终会崩溃,那么您应该使用 unsigned 64 位整数,这将给它更多的世纪,或者你应该使用 128 位整数,在宇宙消亡之前几乎可以肯定是安全的。请注意,所有现代 64 位架构(__int128unsigned __int128)都使用 128 位整数 are supported,因此您可以安全地使用它们,当然,除非您需要支持旧的 32 位系统。或 16 位系统。 8 位,有人吗?

    【讨论】:

    • 在一个纳秒级精度的无符号 64 位整数中可以容纳 584 年多一点。所以,是的,我认为 OP 会很好。
    • 我期待这个软件在 245 年后死于 Y2K262 问题(是的,我们仍然会使用 K,即使它实际上并没有使字符串变短)。 :-)
    • 我的猜测是我的软件不会持续到宇宙的尽头。我要买它!谢谢!
    • 2262-04-13 维护者会骂他,毫秒和小数部分分开存储不是更好吗?
    • 您没有考虑可能需要表示较长持续时间或表示过去或未来时间点的应用程序;不需要 OP 在 2262 中处于活动状态(或程序正在运行),这是有可能的。
    【解决方案2】:

    我建议使用std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>。您可以使用类型别名使这个更漂亮。例如:

    template <class Duration>
        using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
    using sys_nanoseconds = sys_time<std::chrono::nanoseconds>;
    
    sys_nanoseconds now = std::chrono::system_clock::now();
    

    这使您获得与当前接受的答案 (int64_t) 相同的范围,但增加了类型安全性。 int64_t 可能表示时间点或持续时间。 sys_nanoseconds 只能表示time_point,如果像持续时间一样使用会导致编译时错误。

    例如,将两个sys_nanoseconds 加在一起是编译时错误。但是你可以减去两个sys_nanoseconds,得到的类型是std::chrono::nanoseconds

    您的范围(上溢/下溢之前)将是:

    1677-09-21 00:12:43.145224192 to 2262-04-11 23:47:16.854775807
    

    以纳秒精度获得更大范围的价值值得怀疑,但可以在支持 128 位类型的平台上这样做:

    using nano128 = std::chrono::duration<__int128_t, std::nano>;
    using sys_nano = sys_time<nano128>;
    

    现在你的范围远远大于 +/- 宇宙的年龄。

    请注意,在某些平台上,std::chrono::system_clock::now() 不会以纳秒的精度报告。所以存储纳秒时间戳可能是多余的。但是,将上面的代码更改为您想要的任何单位都是微不足道的。

    在 macOS 上,system_clock::now() 报告 microseconds,其范围是 nanoseconds 的 1000 倍。在 Windows 上,system_clock::now()microseconds 的 1/10 为单位报告:

    using win_sys_duration = std::chrono::duration<std::int64_t,
                                                   std::ratio<1, 10'000'000>>;
    using win_sys_time_point = sys_time<win_sys_duration>;
    

    在 gcc 上,system_clock::now() 报告 nanoseconds

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 2021-03-19
      • 2016-09-05
      相关资源
      最近更新 更多