如何将高分辨率时间戳转换为双精度浮点数?

3

我正在尝试使用以下代码:

std::chrono::high_resolution_clock::now();

我需要获取一个时间戳,但我需要它作为double类型,而它并不是支持的数据类型,auto可以工作,但我无法操作它。


为什么你需要它作为双精度浮点数?你的时间单位是什么? - Thomas Matthews
1
通常,使用像毫秒这样的整数单位可能比使用双精度数字更准确。 - Thomas Matthews
2个回答

3
您的“时间戳”就是<chrono>库中所称的time_pointtime_point是时钟和持续时间的集合。而持续时间则是表示和周期的集合。
您已经指定了其中两个:
  • clock == high_resolution_clock
  • representation == double
  • period == ?
您的周期可以为nano(ratio<1, 1000000000>)、milli(ratio<1, 1000>)、seconds(ratio<1>)、minutes(ratio<60>)或任何与秒的有理关系。
例如,假设您想使用double作为表示形式,以秒为周期的时间戳,写法如下:
using clock = std::chrono::high_resolution_clock;
using dsec = std::chrono::duration<double>;
using tps = std::chrono::time_point<clock, dsec>;
tps tp = clock::now();
high_resolution_clock::time_point 通过双精度数值和比率<1>的时间段表示,隐式转换为您的 time_point。它将保存自 high_resolution_clock 的纪元以来的小数秒数。
通常,因为您的目标类型具有浮点表示,所有的 time_point 源类型都会被隐式转换为该类型。要进行反向转换,需要使用 std::chrono::time_point_cast<some-duration>(source-time_point)
如果您希望持有基于双精度纳秒的时间,则代码应如下所示:
using clock = std::chrono::high_resolution_clock;
using dns = std::chrono::duration<double, std::nano>;
using tpns = std::chrono::time_point<clock, dns>;
tpns tp = clock::now();

作为指南,我建议使用system_clocksteady_clock,而不是high_resolution_clock。如果您的time_point需要与公历有一定关系,或需要在进程之间保持意义,请使用system_clock。如果您的time_point仅用于同一进程中的短时间间隔,请使用steady_clockhigh_resolution_clock实际上始终是system_clocksteady_clock的别名。因此,最好使用后两者之一,并且清楚所选的时钟类型。
using clock = std::chrono::system_clock;
using dsec = std::chrono::duration<double>;
using tps = std::chrono::time_point<clock, dsec>;
tps tp = clock::now();

1
非常好的答案,对C++时钟类有很好的见解!我能否将这行代码附加到您答案中的第一个示例中,以获取实际的双精度UTC时间戳:double ts = tp.time_to_epoch().count(); - lowtech
我宁愿你不这样做。理由是:.count()(以及.time_to_epoch())通常被新手程序员过度使用。初学者会调用now(),并立即跳出chrono库的类型安全性。我已经进行了长达十年的运动,以阻止这种情况的发生。我宁愿回答一个关于如何获取double的直接问题,这样我就可以了解为什么需要它。很有可能一旦知道了“为什么”,.count()就不是正确的答案。 - Howard Hinnant

1

std::chrono::high_resolution_clock::now()返回一个std::time_point<std::chrono::high_resolution_clock>。在这里,您可以选择使用std::chrono::duration以纳秒、微秒、毫秒等方式表示此时间点,并最终将其转换为double

std::chrono::time_point<std::chrono::high_resolution_clock> tp = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> dur = tp;
double micros = dur.count();

在这里,您可以将std::micro替换为您想要的任何分辨率。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接