【问题标题】:How to get exactly the same result of timeval with C++11 chrono如何使用 C++11 chrono 获得完全相同的 timeval 结果
【发布时间】:2021-11-19 10:04:12
【问题描述】:

在我的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 不能这样做?

【问题讨论】:

    标签: c++11 chrono gettimeofday


    【解决方案1】:

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

    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 实现相当的结果。]

    【讨论】:

    • 不可编译。 now 是一个时间点,不能立即转换为duration,对吧?所以我使用了(std::chrono::time_point_cast&lt;tenthmillis&gt;(now).time_since_epoch() % oneDay).count();
    • 如果我是对的,您能否稍后更新您的答案?
    • 感谢您的提示。我可以想出一个更简单的程序。
    • 只是一个挑剔:high_resolution_clock 不一定有一个从一天边界开始的纪元。使用 gcc 可以,但没有其他地方。 system_clock 是完成这项工作的正确工具。
    • @HowardHinnant 该解决方案无论如何都是依赖于系统的。要求是“产生与 gettimeofday 给出的相同结果”,因此 OP 必须检查哪些时钟使用 gettimeofday 或在幕后使用的等效项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 2018-10-24
    • 2021-07-17
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多