从 std::chrono:: 转换为 32 位秒和纳秒?

Converting from std::chrono:: to 32 bit seconds and nanoseconds?

这可能是

的倒数

我得到了我的时间

const std::Chrono::CRealTimeClock::time_point RealTimeClockTime = std::Chrono::CRealTimeClock::now();

我必须将其转换为 struct timespec

其实我不会,如果有替代品的话;我要做的是获取自纪元以来的秒数和自上一秒以来的纳秒数。

我选择了struct timespec因为

struct timespec
{
    time_t tv_sec;  // Seconds - >= 0
    long   tv_nsec; // Nanoseconds - [0, 999999999]
};

问题是我需要将秒数和非秒数硬塞进 uint32_t

我知道存在精度损失的危险,但认为我们不太关心纳秒,而 year 208 problem 让我担心。

但是,我现在必须敲出一些代码,如果需要的话我们可以稍后更新。该代码必须满足另一个制造商的规范,可能需要数周或数月才能解决此问题并使用 uint64_t.

那么,我现在如何从 std::Chrono::CRealTimeClock::now() 中获取秒和纳秒的 32 位值?

我要忽略 std::Chrono::CRealTimeClock::now(),假装你写了 std::chrono::system_clock::now()。希望这会为您提供处理实际拥有的任何时钟的工具。

假设:

#include <cstdint>

struct my_timespec
{
    std::uint32_t tv_sec;  // Seconds - >= 0
    std::uint32_t tv_nsec; // Nanoseconds - [0, 999999999]
};

现在你可以写:

#include <chrono>

my_timespec
now()
{
    using namespace std;
    using namespace std::chrono;

    auto tp = system_clock::now();
    auto tp_sec = time_point_cast<seconds>(tp);
    nanoseconds ns = tp - tp_sec;
    return {static_cast<uint32_t>(tp_sec.time_since_epoch().count()),
            static_cast<uint32_t>(ns.count())};
}

解释:

  • 我使用 function-local using 指令来减少代码冗长并提高可读性。如果您愿意,可以使用 using 声明来代替将单个名称引入范围,或者您可以明确限定所有内容。

  • 第一项工作是从您使用的任何时钟中获取 now()

  • 接下来使用std::chrono::time_point_casttp的精度截断为seconds的精度。一个重要的注意事项是 time_point_cast 截断为零。所以这段代码假设 now() 时钟的纪元和 returns 之后 non-negative time_point。如果不是这种情况,那么您应该改用 C++17 的 floorfloor 总是向负无穷大截断。我选择 time_point_cast 而不是 floor 只是因为问题上的 [c++14] 标签。

  • 表达式tp - tp_sec是一个std::chrono::duration,表示自上一整秒以来的持续时间。此持续时间被隐式转换为单位 nanoseconds。这种隐式转换通常很好,因为 system_clock::duration 的所有实现都具有 nanoseconds 或更粗略的单位(因此可以隐式转换为)nanoseconds。如果您的时钟跟踪单位为 picoseconds(例如),那么您需要在此处使用 duration_cast<nanoseconds>(tp - tp_sec) 以将 picoseconds 截断为 nanoseconds 精度。

  • 现在 {tp_sec, ns} 中有 {seconds, nanoseconds} 信息。只是它们仍然是 std::chrono 类型,而不是所需的 uint32_t 类型。您可以使用成员函数 .time_since_epoch().count() 提取内部整数值,然后将这些结果整数类型 static_cast 转换为 uint32_t。最后的 static_cast 是可选的,因为可以隐式进行整数转换。然而他们的使用被认为是好的风格。