Consider a historic date string of format:
Thu Jan 9 12:35:34 2014
I want to parse such a string into some kind of C++ date representation, then calculate the amount of time that has passed since then.
From the resulting duration I need access to the numbers of seconds, minutes, hours and days.
Can this be done with the new C++11 std::chrono
namespace? If not, how should I go about this today?
I'm using g++-4.8.1 though presumably an answer should just target the C++11 spec.
GCC prior to version 5 doesn't implement
std::get_time
. You should also be able to write:This is rather C-ish and not as elegant of a solution as Simple's answer, but I think it might work. This answer is probably wrong but I'll leave it up so someone can post corrections.
New answer for old question. Rationale for the new answer: The question was edited from its original form because tools at the time would not handle exactly what was being asked. And the resulting accepted answer gives a subtly different behavior than what the original question asked for.
I'm not trying to put down the accepted answer. It's a good answer. It's just that the C API is so confusing that it is inevitable that mistakes like this will happen.
The original question was to parse
"Thu, 9 Jan 2014 12:35:34 +0000"
. So clearly the intent was to parse a timestamp representing a UTC time. Butstrptime
(which isn't standard C or C++, but is POSIX) does not parse the trailing UTC offset indicating this is a UTC timestamp (it will format it with%z
, but not parse it).The question was then edited to ask about
"Thu Jan 9 12:35:34 2014"
. But the question was not edited to clarify if this was a UTC timestamp, or a timestamp in the computer's current local timezone. The accepted answer implicitly assumes the timestamp represents the computer's current local timezone because of the use ofstd::mktime
.std::mktime
not only transforms the field typetm
to the serial typetime_t
, it also performs an offset adjustment from the computer's local time zone to UTC.But what if we want to parse a UTC timestamp as the original (unedited) question asked?
That can be done today using this newer, free open-source library.
This library can parse
%z
. Anddate::sys_seconds
is just a typedef for:The question also asks:
That part has remained unanswered. Here's how you do it with this library. For this part I'm also going to use a second header-only library
"chrono_io.h"
:floor<days>
truncates the seconds-precisiontime_point
to a days-precisiontime_point
. If you subtract the days-precisiontime_point
fromtp
, you're left with aduration
that represents the time since midnight (UTC).The factory function
make_time
takes anyduration
(in this case time since midnight) and creates a{hours, minutes, seconds}
field type with getters for each field. If the duration has precision finer than seconds this field type will also have a getter for the subseconds.Finally, using
"chrono_io.h"
, one can just print out all of these durations. This example outputs:The
[86400]s
represents the units of theduration
that has days-precision. So 2014-01-09 is 16079 days after 1970-01-01.