如何使用 C++11 chrono 获得完全相同的 timeval 结果

How to get exactly the same result of timeval with C++11 chrono

在我的C++项目中,有一个非常古老的函数,它使用了Linux的系统函数来计算时间。

这是一段代码:

struct timeval tv;
gettimeofday(&tv, NULL);
uint32_t seqId = (tv.tv_sec % 86400)*10000 + tv.tv_usec / 100;

* 10000/ 100都没有错,因为这段代码是要生成一个seqId。

现在,我正在尝试使用 C++11 的 std::chrono 来替换它。这是我的代码:

std::chrono::high_resolution_clock::duration duration_since_midnight() {
    auto now = std::chrono::high_resolution_clock::now();
    std::time_t tnow = std::chrono::high_resolution_clock::to_time_t(now);
    tm *date = std::localtime(&tnow);
    date->tm_hour = 0;
    date->tm_min = 0;
    date->tm_sec = 0;
    auto midnight = std::chrono::system_clock::from_time_t(std::mktime(date));
    return now - midnight;
}
auto res = duration_since_midnight();
auto sec = std::chrono::duration_cast<std::chrono::seconds>(res);
auto mil = std::chrono::duration_cast<std::chrono::milliseconds>(res - sec);
std::cout << sec.count() * 10000 + mil.count() << std::endl;

然而,结果总是有点不对。例如,旧版本可能会给我 360681491,但我的版本会给我 360680149。你看他们不完全一样。

我不知道为什么。或者 std::chrono?

无法做到这一点

您不必拘泥于库提供的持续时间类型。您可以定义自己的具有所需表示的内容:

using tenthmillis = duration<long, ratio<1,10000>>;

那你就可以跟进下面的计算了。

auto now = high_resolution_clock::now().time_since_epoch();
auto oneDay = duration_cast<tenthmillis>(days{1});
auto sinceMidnight = duration_cast<tenthmillis>(now) % oneDay.count();

cout << sinceMidnight.count();

注意:根据需要自行添加命名空间限定条件。

[更新:选择在其实现中使用 gettimeofday 的时钟而不是 high_resolution_clock,以获得与您的 gettimeofday 实现相当的结果。]