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

时间:2015-08-20 06:45:58

标签: c++ c++11 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()值来自我们代码库中的以下代码,然后我们将其与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上编译。

2 个答案:

答案 0 :(得分:2)

两者使用相同的时钟。如果您的时间戳需要在应用程序运行期间保持意义,则必须使用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>的类型安全系统的空间/时间开销为零。

答案 1 :(得分:1)

您应该为两者使用相同的时间函数。

我建议更改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()));