Nathan
Nathan

Reputation: 45

parse std::chrono::utc_clock from string

I am trying to simply parse a string to a std::chrono::utc_clock::time_point but it is such a pain with all time zone stuff

Here what I tried :

    // The given string IS in UTC, ALWAYS
    //"2023-12-02 01:22:36.675349139 +00:00:00"

    std::istringstream ss(j.get<std::string>());
    std::tm t = {};
    ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");

    // Convert to time_point
    long timeSinceEpoch = std::mktime(&t);
    auto duration = std::chrono::seconds(timeSinceEpoch);
    time_point = std::chrono::utc_clock::time_point(duration);
    std::cout << "time_point: " << time_point << std::endl;

But the output is always offset by my timezone (for me it's +9h, so the result is shifted by -9h). I don't understand where the shift is happening, is it in mktime() or time_point() ?

Is there a good and easy way to parse a string given in UTC into a std::chrono::utc_clock::time_point ?

Upvotes: 0

Views: 530

Answers (2)

Alan Birtles
Alan Birtles

Reputation: 36479

It's much simpler to use std::chrono::from_stream:

std::istringstream ss("2023-12-02 01:22:36.675349139 +00:00:00");
std::chrono::utc_clock::time_point time_point;
std::chrono::from_stream(ss, "%Y-%m-%d %H:%M:%S %z",time_point);
std::cout << "time_point: " << time_point << std::endl;

Upvotes: 2

John Zwinck
John Zwinck

Reputation: 249394

std::mktime() uses your local time zone, as you've discovered. The related function for UTC is std::timegm(). It is available on GNU and BSD systems, but not everywhere, so if your system does not have it or you need a portable solution, see timegm cross platform.

Using std::timegm() where you have std::mktime() will solve your problem and parse as UTC.

Upvotes: 0

Related Questions