0

I have made two simple functions that can serialize and deserialize a time_t to a iso 8601 string format:

#include <stdexcept>
#include <boost/format.hpp>

std::string time_t_to_iso_format(std::time_t time)
{
    char buf[sizeof "2017-05-01T00:00:00"];
    strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S", gmtime(&time));
    return std::string(buf);
}

std::time_t iso_format_to_time_t(std::string& iso_time)
{
    auto error_message = boost::format{"Invalid iso_time: %1%"} % iso_time;
    if (iso_time.length() != std::string("2017-05-01T00:00:00").length())
    {
        throw std::invalid_argument(error_message.str());
    }

    struct tm t  = { 0 };
    auto c_str = iso_time.c_str();
    t.tm_sec = std::stoi(std::string(c_str + 17));
    t.tm_min = std::stoi(std::string(c_str + 14));
    t.tm_hour = std::stoi(std::string(c_str + 11));
    t.tm_mday = std::stoi(std::string(c_str + 8));
    t.tm_mon = std::stoi(std::string(c_str + 5)) - 1;
    t.tm_year = std::stoi(std::string(c_str)) - 1900;

    return mktime(&t);
}

Now this almost works. I have two testcases where I check if this function works using boost unit test framework:

BOOST_AUTO_TEST_CASE(time_t_tools)
{
    auto iso_time = std::string("2017-05-01T23:15:29");
    auto converted = iso_format_to_time_t(iso_time);
    auto round_trip = time_t_to_iso_format(converted);

    BOOST_REQUIRE_MESSAGE(
        iso_time.compare(round_trip) == 0,
        "Iso times are not equal: " << iso_time << ", " << round_trip << ". It didn't survive the round-trip iso time -> time_t -> iso time."
    );

    iso_time = std::string("1980-12-04T14:00:10");
    converted = iso_format_to_time_t(iso_time);
    round_trip = time_t_to_iso_format(converted);

    BOOST_REQUIRE_MESSAGE(
        iso_time.compare(round_trip) == 0,
        "Iso times are not equal: " << iso_time << ", " << round_trip << ". It didn't survive the round-trip iso time -> time_t -> iso time."
    );
}

How all the values are correct except for the hour. Which is off by one. The output of this test case:

Why is the hour of by one? And how can I fix this issue?

fatal error: in "time_t_tools": Iso times are not equal: 2017-05-01T23:15:29, 2017-05-01T22:15:29. It didn't survive the round-trip iso time -> time_t -> iso time.
too honest for this site
  • 12,050
  • 4
  • 30
  • 52
  • 1
    Daylight Saving Time? – Myst May 02 '17 at 00:32
  • @Myst How can it be magically added? And if so is there anyway I can avoid it? –  May 02 '17 at 00:36
  • It might be added when you run `gmtime`, since it converts from the time structure to UTC (it assumes the time structure is local time)... see the answer referenced in the duplicate question for more details. – Myst May 02 '17 at 00:42
  • @JohnSmith: Here is a [open-source modern C++ date/time library](https://howardhinnant.github.io/date/date.html) which is much easier to use, and cross platform. Here is a [working demo](https://wandbox.org/permlink/7w5ob61dBEkViP63) of your code above using this library. Feel free to modify the working demo and experiment with it. – Howard Hinnant May 02 '17 at 14:28

0 Answers0