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
?
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.
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.
[Update: Instead of high_resolution_clock
, choose a clock that uses gettimeofday
in its implementation to get results that are comparable to your gettimeofday
implementation.]