How can I get an std::chrono::duration
since a fixed date? I need this to convert a std::chrono::time_point
to an unix timestamp.
Insert code into XXX
auto unix_epoch_start = XXX;
auto time = std::chrono::system_clock::now();
auto delta = time - unix_epoc_start;
auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(delta).count();
I know time_point
has a method time_since_epoch()
but it's not guaranteed that this is the same as the unix epoch (00:00:00 UTC on 1 January 1970).
Long story short, here is the function I use to get Unix timestamp (seconds count since Jan 1, 1970 UTC):
The advantage of this function is that the default parameter value just gives you current time. However if you wanted to convert some specific time to unix timestamp than you can do so as well.
You could use
mktime()
to convert the desired date encoded in atm
structure into a local-timetime_t
value.If you need a UTC time, then use
gmttime()
to convert thattime_t
value into a UTCtm
structure, and figure out from the output you get whichtm
structure yields the desired UTCtime_t
when given in input tomktime()
.A bit elaborate, but hopefully it will work or at least provide a hint.
A unix time stamp is defined as the number of seconds since January 1, 1970 UTC, except not counting all the seconds. This is somewhat ridiculous and one has to wonder what the point of it is, so I agree that this is a silly question.
Anyway, lets look at some platform documentation for
time_t
andtime()
.Linux:
Windows:
Mac OS X:
Similar documentation can be found for other systems, such as AIX, HP-UX, Solaris, etc.
So although not specified in C++ there is an easy and widely portable way to get a Unix timestamp:
And if you want a number of milliseconds since 1 Jan 1970 UTC (similarly not counting all of them) then you can do this:
Just remember that these values aren't real times, so you can't in general use unix timestamps in arithmetic. For example subtracting unix timestamps does not give you an accurate count of seconds between the times. Or if you did something like:
you would not get a time point actually corresponding to 1970-01-01 00:00:00+0000.
As Andy Prowl suggests you could do something silly like:
l
should now represent the (wrong) number of seconds since 1 Jan 1970 UTC. As long as there are no leap seconds between the system epoch and 1 Jan 1970 (system time zone), or within an equal amount of time in the other direction from the system epoch, then any counted leap seconds should cancel out andl
will be wrong in just the way that unix timestamps are wrong.Another option is to use a decent date library such as Howard Hinnant's
chrono::date
. (Howard Hinnant was one of the guys that worked on the C++11<chrono>
library.)If you want to handle leap seconds Howard Hinnant also provides a library that includes facilities for handling them as well as for parsing time zone databases as the source for leap second data.