c++ - 使用 chrono c++ 库计算时间戳的差异

标签 c++ c++11 c++-chrono

跟进自 here

我试图通过查看数据的时间戳来查看我的数据是否存在 120 秒,因此我在使用 std::chrono 包的库项目中有以下小代码:

uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));

// some logging to print out above values
LOG4CXX_WARN(logger, "data logging, now: " << now << ", data holder timestamp: " << data_holder->getTimestamp() << ", is_old: " << is_old << ", difference: " << (now -         data_holder->getTimestamp()));

在上面的代码中,data_holder->getTimestamp()uint64_t,它返回以毫秒为单位的时间戳。

现在当我打印出 now 变量值时,我看到了这个 433425679 并且当我打印出 data_holder->getTimestamp() 值时这是 1437943796841,现在和数据持有者时间戳的区别是 18446742636199180454,如下面的日志所示:

2015-07-26 13:49:56,850 WARN 0x7fd050bc9700 simple_process - data logging, now: 433425679 , data holder timestamp: 1437943796841 , is_old: 1 , difference: 18446742636199180454

现在,如果我使用纪元转换器转换数据持有者时间戳 1437943796841,我会看到:

Your time zone: 7/26/2015, 1:49:56 PM

这与日志 2015-07-26 13:49:56,850 WARN 中显示的时间戳完全相同,这意味着我的数据看起来不是 120 秒的旧数据。如果是,那么为什么我看到 is_old 值为 1

看起来 data_holder->getTimestamp() 值来 self 们代码库中的以下代码,然后我们将它与 120 秒旧数据检查进行比较。

// is this the problem?
struct timeval val;
gettimeofday(&val, NULL);
uint64_t time_ms = uint64_t(val.tv_sec) * 1000 + val.tv_usec / 1000;

现在在仔细阅读了 C++ 中的各种时钟实现之后,看起来我们应该使用相同的时钟来进行比较。

我上面计算 data_holder->getTimestamp() 值的代码是否有问题?因为我没有在那里使用 steady_clock,所以纪元时间会有所不同,这就是我看到这个问题的原因?

现在我的问题是 - 我应该使用什么代码来解决这个问题?对于 data_holder->getTimestamp() 代码,我是否也应该使用 steady_clock?如果是,那么正确的方法是什么?

同样的代码在 Ubuntu 12 中也能正常工作,但在 Ubuntu 14 中却不能正常工作。我正在运行所有静态链接库。对于 Ubuntu 12,代码是在运行 4.7.3 编译器的 Ubuntu 12 上编译的;对于 Ubuntu 14,代码是在运行 4.8.2 编译器的 Ubuntu 14 上编译的。

最佳答案

两者使用相同的时钟。如果您的时间戳需要在应用程序运行期间保持意义,则必须使用 system_clock , 不是 steady_clock .如果您的时间戳仅在单次运行中有意义,您可以使用 steady_clock .

steady_clock就像一个“秒表”。你可以用它来计时,但你不能用它来获取当前时间。

DataHolder::DataHolder()
    : timestamp_{system_clock::now()}
    {}

system_clock::time_point
DataHolder::getTimestamp()
{
    return timestamp_;
}

bool is_old = minutes{2} < system_clock::now() - data_holder->getTimestamp();

在 C++14 中,您可以将其缩短为:

bool is_old = 2min < system_clock::now() - data_holder->getTimestamp();

  • 请使用 <chrono> .
  • 不要使用 count()time_since_epoch() (调试目的除外)。
  • 不要使用转换因子,例如 1000120 .

违反上述准则会将编译时错误转化为运行时错误。编译时错误是你的 friend 。 <chrono>在编译时捕获许多错误。一旦你逃离了 <chrono> 的类型安全(例如,通过使用 count() ),您正在使用相当于计时的汇编语言进行编程。以及 <chrono> 的空间/时间开销的类型安全系统为零。

关于c++ - 使用 chrono c++ 库计算时间戳的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32111273/

相关文章:

C++11 可变参数模板和逗号分隔表达式等价

c++ - 用 std::chrono 显示日月年?

c++ - `rep` 时钟中的有符号和无符号 `std::chrono`

c++ - 为什么是标准代码?

c++ - 修改哈希函数

c++ - ELF 包含 NEON 或 VFP3 指令?

c++ - C++中函数返回的值是右值吗?无法使用复制/move 构造函数初始化实例

C++循环遍历目录中的文件

C++:没有用于调用 std::deque<SnakePart>::emplace_front 的匹配函数

c++ - localtime_s 失败,而 gmtime_s 在 1-1-1970 之前的日期成功