std::chrono::parse
and std::chrono::from_stream
allows us to parse many different date/time formats.
But I recently got a string like this:
2022-07-10 22:00 GMT+2
- and I'm not sure what format should I use.
I tried:
%F %T GMT%z
- fails
%F %T GMT%Z
- fails
%F %T %Z
- fails
Or maybe I just have to parse time/date and then manually get the zone?
This is a little tricky.
%T
is a short cut for %H:%M:%S
. But you don't have a seconds field, and so using %T
fails when the parse can't find the trailing :
after the minutes. Use %H:%M
instead.
%Z
(parsing an abbreviation) will greedily accept alphanumeric, or one of '_', '/', '-', or '+' characters, and so if used will grab all of GMT+2
. So your use of GMT
over %Z
is correct.
%z
(offset) requires the format [+|-]hh[mm]
. This fails for you because you only have one digit for the hours (no leading zero). However the modified command %Ez
doesn't require a leading zero.
Putting this all together:
istringstream in{"2022-07-10 22:00 GMT+2"};
in.exceptions(ios::failbit);
sys_seconds tp;
in >> parse("%F %H:%M GMT%Ez", tp);
cout << tp << '\n';
Output:
2022-07-10 20:00:00
Note that the offset is applied and so tp
represents a UTC timestamp. If you instead wanted the local time, then just change sys_seconds
to local_seconds
and the output changes to:
2022-07-10 22:00:00
The offset is parsed, but not applied.