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.
