从 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_cast
将tp
的精度截断为seconds
的精度。一个重要的注意事项是 time_point_cast
截断为零。所以这段代码假设 now()
是 在 时钟的纪元和 returns 之后 non-negative time_point
。如果不是这种情况,那么您应该改用 C++17 的 floor
。 floor
总是向负无穷大截断。我选择 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
是可选的,因为可以隐式进行整数转换。然而他们的使用被认为是好的风格。
这可能是
我得到了我的时间
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_cast
将tp
的精度截断为seconds
的精度。一个重要的注意事项是time_point_cast
截断为零。所以这段代码假设now()
是 在 时钟的纪元和 returns 之后 non-negativetime_point
。如果不是这种情况,那么您应该改用 C++17 的floor
。floor
总是向负无穷大截断。我选择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
是可选的,因为可以隐式进行整数转换。然而他们的使用被认为是好的风格。