Home > Net >  How to get exactly the same result of timeval with C 11 chrono
How to get exactly the same result of timeval with C 11 chrono

Time:11-21

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?

CodePudding user response:

You do not have to stick to the duration types that the library provides. You can define your own that has the representation that you need:

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

Then you can follow up with the following calculation. It assumes that the epoch of the high_resolution_clock begins at midnight.

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();

Note: Add namespace qualifications as required yourself.

  • Related