有时我看到
timespec
和
timeval
被用作时间间隔,有时我看到它们被用作时间点。您需要知道所持有的值的类型。在
<chrono>
中,这两个概念是不同的类型。
一个duration是一段时间:您会用秒表来测量它。例子包括 2 分钟、3 秒、4 小时和 16 年。
time point是一个特定的时间:2015年7月14日下午2点EDT,或者距离我启动计算机已经6小时。time point有一个与之相关联的暗示纪元。一个纪元只是一些共同商定的起点,您可以从中测量时间。
如果您的
timespec
持续一段时间:
timespec ts = {3, 123}; // 3 seconds + 123 nanoseconds
auto d = std::chrono::seconds{ts.seconds}
+ std::chrono::nanoseconds{ts.nanoseconds};
如果您的timespec
包含一个时间点,那么您必须了解时代。很可能时代是1970-01-01 00:00:00 UTC,不考虑闰秒(这是Unix时间)。如果是这样,您可以将它放入std::chrono::system_clock::time_point
中。该类型不保证具有此时代,但每个实现都有:
using namespace std::chrono;
system_clock::time_point tp{duration_cast<system_clock::duration>(d)};
其中d
的计算方式如上所述。
如果您有一个timeval
,则在我使用nanoseconds
的地方使用microseconds
。
您不能可移植地使用high_resolution_clock
或steady_clock
时间点,因为不同的实现对这些类型有不同的纪元。
此外,如果您正在使用timeval
,实际上duration_cast
变得不必要,因为持续时间d
将隐式转换为所有system_clock::duration
的实现:
using namespace std::chrono
system_clock::time_point tp{d}
如果您不确定是否需要使用duration_cast
,可以尝试不使用它。如果编译通过,则无需使用它。如果出现编译时错误,则需要使用它。在转换持续时间时,需要使用它,当不存在精确的转换时。
std::chrono::system_clock
拥有方便的方法from_time_t
和to_time_t
。如果我们谈论time_points
,这些方法应该确保更可移植的转换。 - user666412from_time_t
和to_time_t
放入了C++11中。不幸的是,time_t
通常既是整数又表示秒数,而timespec
和timeval
表示比秒更细的单位。因此,通过to/from_time_t
意味着你必须将精度截断到秒,然后以某种方式恢复该精度。说实话,to/from_time_t
的好处在于它鼓励实现者使用UnixTime“标准”来处理system_clock
。 :-) - Howard Hinnantto/from_time_t
是一种便携式调整纪元的方法,因为这可能是实现特定的,并且秒的分数可以像您使用持续时间一样添加。 - user666412to/from_time_t
是目前唯一标准认可的方法。我正在努力将system_clock
的纪元标准化为 UnixTime。我已经得到了所有实现者的个人保证,他们会这样做。但这当然不是官方的,只有在实现者改变或标准锁定之前才有效。目前,我的提案包括许多其他内容,使其风险非常高:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0355r1.html#Wording - Howard Hinnantsystem_clock
的时代,以匹配Unix时间:http://eel.is/c++draft/time.clock.system#overview-1 - Howard Hinnant