如何将std::chrono::time_point转换为uint64_t
How to convert std::chrono::time_point to uint64_t?
我试图通过查看数据的时间戳来查看我的数据是否为120秒(或2分钟)旧,因此我有以下代码,因为我在c++中使用chrono
包:
uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
// check for 2 minutes old data
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));
uint64_t value = now;
while (now < data_holder->getTimestamp() + 80 * 1000
&& now < value + 80 * 1000) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}
在上面的代码中,data_holder->getTimestamp()
是uint64_t,它以毫秒为单位返回时间戳。
现在当我打印出now
变量值时,我看到的是10011360
当我打印出data_holder->getTimestamp()
值时,我看到的是1437520382241
2015-07-21 16:13:02,530 WARN 0x7f35312d1700 data_check - now value: 10011360 , data holder timestamp: 1437520382241
从上面的数据持有人时间戳,它不看起来是120秒的旧数据,所以我觉得在我的代码是错误的?因为如果我将数据持有人时间戳转换为实际时间(使用epoch转换器),然后将其与上面所示的日志时间进行比较,结果几乎相同。
所以我决定使用system_clock
而不是steady_clock
,并提出了以下代码,我开始使用auto
而不是uint64_t
。
解决方案一:
auto now = system_clock::now();
auto dh_ts = system_clock::time_point{milliseconds{data_holder->getTimestamp()}};
bool is_old = (minutes{2} < (now - dh_ts));
早些时候,我使用now
变量值作为uint64_t
而不是auto
。现在在上面的代码之后,我在我的原始代码中有这样的东西,因为now
不是uint64_t
,所以我在编译代码时得到编译错误。
uint64_t value = now;
while (now < data_holder->getTimestamp() + 80 * 1000
&& now < value + 80 * 1000) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}
解决这个问题的正确方法是什么?我不能改变data_holder->getTimestamp()
数据类型,它必须是uint64_t
,因为其他代码也在使用它。
错误如下:
error: cannot convert std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >â to âuint64_t {aka long unsigned int}â in initialization
更新:
我可以这样使用,而不是使用Solution A
,如果一切看起来很好下面?
解决方案B:
uint64_t now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));
至少在我读到它的时候,这是每次睡100毫秒,然后检查它是否已经睡了2分钟。然后重复,直到达到2分钟点。
在我看来,计算所需的时间,然后一直睡到那个时候更有意义:
struct foo {
time_point<system_clock> time_stamp;
time_point<system_clock> get_timestamp() { return time_stamp; }
foo() : time_stamp(system_clock::now()) {}
};
// ...
foo f;
std::this_thread::sleep_until(f.get_timestamp() + 2m);
确实使用了(c++ 14中新增的)用户定义的字面量来构造一个2分钟的持续时间。如果你真的需要支持旧的(c++ 11)编译器,你需要使用minutes(2)
来代替。
至于标题问题,我想说:直接说不。将您的时间点存储为实际的时间点要比坚持将它们填充成整数,然后在需要再次使用它们时将它们转换回时间点要好得多。这一点也不明显,因为这样做是为了换取痛苦。
实际上,我建议更多地朝着解决方案A的方向发展,并将剩余的uint64_t
次转换为时间点:chrono
单位系统非常有用。我将首先定义一个辅助函数,将对象上的uint64_t
时间戳转换为time_points:
using u64_millis = duration<uint64_t, milli>;
static time_point<system_clock, u64_millis> u64_to_time(uint64_t timestamp) {
return time_point<system_clock, u64_millis>{u64_millis{timestamp}};
}
如果您的纪元与system_clock
的纪元不同,这将是修复它的地方。使用milliseconds
代替u64_millis
也可以,但是milliseconds
的表示类型没有明确定义,这样做可以确保类型正确匹配。
现在,您发布的代码变成类似于:
auto now = system_clock::now();
bool is_old = now - u64_to_time(data_holder->getTimestamp()) > minutes{2};
auto value = now;
while (now - u64_to_time(data_holder->getTimestamp()) < seconds{80}
&& now - value < seconds{80}) {
this_thread::sleep_for(milliseconds{100});
now = system_clock::now();
}
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 将 Vector<vector<Point> > X 转换为 IplImage* 或 cv::Mat*
- OpenCV:向量<向量<Point>>向量的转换<Mat>,引用调用的问题
- 从cv::Mat中的cv::Point的矢量转换轮廓
- win32(windows.h)中是否有一个方便函数可以将lParam转换为POINT
- 将System.Windows.Rect强制转换为System.Windows.Point
- 如何将两个双数据类型元素转换为一个Point数据类型
- 在OpenCV中将Point数据类型转换为int
- OpenCv: 如何将矢量转换为<Point>垫子 (CV_8U)