jelmew
jelmew

Reputation: 583

Formatted timestring when parsed to a time_point gives an hour difference

I found the following problem. I have a string with a time (gotten from a file to which I putoutted using the reverse operations). However, when converting this to a time_point and outputting it to terminal, I find a difference of one hour. I have not been able to find out why. Any ideas?

#include <iostream>
#include <chrono>
#include <sstream>
#include <iomanip>

const char *const TIME_FORMAT = "%Y-%b-%d %H:%M:%S";

int main() {
    //Formatted timestring
    std::string timeString = "2018-Jun-18 09:03:43,24";

    //Logic to parce the string into a time struct
    std::istringstream ss(timeString);
    std::locale locale("");
    ss.imbue(locale);
    std::tm t = {};
    ss >> std::get_time(&t, TIME_FORMAT);

    if (ss.fail()) {
        //TODO throw exception;
        std::cout << "Parse failed\n";
    }

    //Convert to time_point
    time_t time = mktime(&t);
    auto time_point = std::chrono::system_clock::from_time_t(time);

    //Convert  to output string
    auto time_t_again = std::chrono::system_clock::to_time_t(time_point);
    std::cout << "timePoint: " << std::put_time(std::localtime(&time_t_again), TIME_FORMAT);
    return 0;
}

This outputs: timePoint: 2018-Jun-18 10:03:43 instead of the expected 2018-Jun-18 9:03:43

Upvotes: 5

Views: 578

Answers (1)

Naszta
Naszta

Reputation: 7744

The problem is mktime. It modifies the time based on t.tm_isdst. You also need to run a std::memset on the struct tm before run (parsers are filling in what they found in the format).

From this point you could have 2 options:

  1. set t.tm_isdst to -1 as suggested and daylight changes made automatically based on the parsed date (handling time as local time),
  2. use timegm or _mkgmtime and keep t.tm_isdst as 0 against mktime (handling time as UTC, simplify the code).

Upvotes: 4

Related Questions