如何将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 其中 returns 以毫秒为单位的时间戳。
现在,当我打印出 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 秒的旧数据,所以我觉得我的代码有问题?因为如果我将该数据持有者时间戳转换为实际时间(使用纪元转换器),然后将其与日志时间进行比较,如上所示,它几乎相同。
所以我决定使用 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()));
实际上,我建议更多地朝解决方案 A 的方向前进,并将剩余的 uint64_t
时间转换为 time_points: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();
}
至少在我读到它时,这是一次休眠 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)
。
就标题问题而言,我会说:直接说不。将 time_points 存储为实际 time_points 比坚持将它们填充为整数,然后在需要再次使用它们时将它们变回 time_points 要好得多。一点也不明显,这是为了换取痛苦而完成的任何有用的事情。
我试图通过查看数据的时间戳来查看我的数据是否是 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 其中 returns 以毫秒为单位的时间戳。
现在,当我打印出 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 秒的旧数据,所以我觉得我的代码有问题?因为如果我将该数据持有者时间戳转换为实际时间(使用纪元转换器),然后将其与日志时间进行比较,如上所示,它几乎相同。
所以我决定使用 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()));
实际上,我建议更多地朝解决方案 A 的方向前进,并将剩余的 uint64_t
时间转换为 time_points: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();
}
至少在我读到它时,这是一次休眠 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)
。
就标题问题而言,我会说:直接说不。将 time_points 存储为实际 time_points 比坚持将它们填充为整数,然后在需要再次使用它们时将它们变回 time_points 要好得多。一点也不明显,这是为了换取痛苦而完成的任何有用的事情。