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

Using chrono c++ library to calculate difference of timestamp

本文关键字:时间戳 计算 chrono c++ 使用      更新时间:2023-10-16

从这里开始

我试图通过查看数据的时间戳来查看我的数据是否为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

现在,如果我使用epoch转换器转换数据持有人时间戳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()值来自我们代码库中的下面代码,然后我们将其与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,所以纪元时间会不同,这就是为什么我看到这个问题?

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

同样的代码在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等转换因子。
违反上述准则将把编译时错误变成运行时错误。编译时错误是您的朋友。<chrono>在编译时捕获许多错误。一旦您逃避了<chrono>的类型安全(例如,通过使用count()),您就是在用汇编语言编写相当于计时的程序。<chrono>的类型安全系统的空间/时间开销为零。

你绝对应该使用相同的时间函数。

我建议改变getTimestamp()值的创建方式(例如通过使用chrono::system_clock)或比较时间戳的方式。

干净的方法是这样修改:

struct timeval val;
gettimeofday(&val, NULL);
uint64_t now = uint64_t(val.tv_sec) * 1000 + val.tv_usec / 1000;
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));

或者反过来

1。修改getTimestamp()值的创建方式

long long time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();

2。调整比较函数

long long now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));