vendredi 19 novembre 2021

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

In my C++ project, there is a very old function, which used the system function of Linux to do some calculation about time.

Here is a picec of code:

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

* 10000 and / 100 are not wrong, because this piece of code is about to generate a seqId.

Now, I'm trying to use std::chrono of C++11 to replace it. Here is my code:

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;

However, the result is always kind of wrong. For example, the old version may give me 360681491 but my version would give me 360680149. You see they are not exactly the same.

I don't know why. Or it's not possible to do so with std::chrono?

Aucun commentaire:

Enregistrer un commentaire