Home > OS >  Datetime parse and format in C
Datetime parse and format in C

Time:05-07

I'm using time_point the first time. I want to parse datetime from string and found a difference when returning back to string from 1 hour.

std::chrono::system_clock::time_point timePoint;
std::stringstream ss("2021-01-01 00:00:09 01");
std::chrono::from_stream(ss, "%F %T%z", timePoint);  
  // timePoint == {_MyDur={_MyRep=16094556090000000 } }
std::string timePointStr = std::format("{:%Y/%m/%d %T}", floor<std::chrono::seconds>(timePoint));
  // timePointStr = "2020/12/31 23:00:09"

I don't know what is wrong: the timepoint and the parsing or the formatting to string? How can I get the same format as the parsed one?

CodePudding user response:

This is the expected behavior.

Explanation:

system_clock::time_point, and more generally, all time_points based on systme_clock, have the semantics of Unix Time. This is a count of time since 1970-01-01 00:00:00 UTC, excluding leap seconds.

So when "2021-01-01 00:00:09 01" is parsed into a system_clock::time_point, the "2021-01-01 00:00:09" is interpreted as local time, and the " 01" is used to transform that local time into UTC. When formatting back out, there is no corresponding transformation back to local time (though that is possible with additional syntax). The format statement simply prints out the UTC time (an hour earlier).

If you would prefer to parse "2021-01-01 00:00:09 01" without the transformation to UTC, that can be done by parsing into a std::chrono::local_time of whatever precision you desire. For example:

std::chrono::local_seconds timePoint;
std::stringstream ss("2021-01-01 00:00:09 01");
from_stream(ss, "%F %T%z", timePoint);
...

Now when you print it back out, you will get "2021/01/01 00:00:09". However the value in the rep is now 1609459209 (3600 seconds later).

  • Related