我的目标是将时间戳存储在纳秒范围内。让我们说我有两台机器需要在任务完成的时间进行通信。
我们只是为了问题,说它们是同步时钟 机器A在完成后存储当地时间。机器B发送到A,此时它完成。机器A然后计算差异。
我的问题是,时差实际上可以达到60秒,但也可以达到.25ms。所以我需要以这样的方式存储时间,我可以处理两者,并计算时差。
由于纳秒时代以来的时间是如此之大,我不认为我可以将其存储在我所知道的任何变量中。
你会如何解决这种情况?我当前的情况是,我可能(某种程度上)可以缩短从ns的纪元到1分钟的时间,但我不知道该怎么做。
希望你能提供帮助。
祝你好运
答案 0 :(得分:5)
只需使用64位整数,有符号(int64_t
)或无符号(uint64_t
),你就可以了。
64位空间非常庞大。它不仅足以存储时差,甚至可以存储绝对时间值,通常以1970-01-01午夜以来的时间来衡量。
例如,目前1970-01-01以来的秒数大致为:
1492432621.123456789
在纳秒内,这是:
1492432621123456789
为了进行比较,最大的有符号64位整数值是:
9223372036854775807
这大致相当于2262-04-12,这个日期你几乎肯定不会再活着。
但是,如果您仍然担心软件运行超过两个世纪的可能性,在此期间不会得到改善,并且最终会崩溃,那么您应该使用 unsigned 64位整数,它将给它更多的世纪,或者你应该使用128位整数,这几乎肯定是安全的,直到宇宙死亡。请注意所有现代64位架构(__int128
或unsigned __int128
)的128位整数are supported,因此您可以安全地使用它们,当然,除非您需要支持传统32比特系统。或16位系统。 8位,有人吗?
答案 1 :(得分:3)
我建议使用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
。