memcpy (&tmp_tm, &tm, sizeof (tmp_tm));
errno = 0;
- const time_t t = mktime (&tmp_tm);
+
+ time_t t = mktime (&tmp_tm);
if (t == - 1) { /* Glibc does not set errno on out-of-range here! */
const char *datestr = asctime (&tm);
throw conversion_error (errno,
+ "}");
}
+ /*
+ * The timezone shenanigans are there to force we end up using UTC
+ * internally. The trouble with mktime(3) is that the unix timestamp
+ * is defined as “seconds since epoch” but “expressed as local time”.
+ */
+ t += tm.tm_gmtoff;
+ t -= timezone;
+
tmp_time = Time (t, 0l, id, var);
this->swap (tmp_time);
BOOST_CHECK_EQUAL(*t2->format_iso8601 (true, true, false, false), in2);
}
+ BOOST_AUTO_TEST_CASE(FromString_iso8601_offset)
+ {
+ const std::string in1 ("2019-04-25T13:41:47Z");
+ const std::string in2 ("2019-04-25T13:41:47+0200"); /* = UTC(in1 + 2h) */
+ const std::string in3 ("2019-04-25T15:41:47+0000"); /* = UTC(in2) */
+
+ this->set_utc ();
+ boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1, true, true, true);
+ boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2, true, true, true);
+ boost::optional<I2n::clock::Time> t3 = I2n::clock::time_of_iso8601 (in3, true, true, true);
+
+ BOOST_CHECK(t1);
+ BOOST_CHECK(t2);
+ BOOST_CHECK(t3);
+
+ BOOST_CHECK_EQUAL(*t1->format_iso8601 (), "2019-04-25T13:41:47+0000");
+ BOOST_CHECK_EQUAL(t1->get_sec (), 1556199707);
+ BOOST_CHECK_EQUAL(*t2->format_iso8601 (), "2019-04-25T15:41:47+0000");
+ BOOST_CHECK_EQUAL(t2->get_sec (), t1->get_sec () + 2 * 60 * 60);
+ BOOST_CHECK_EQUAL(*t2, *t3);
+ BOOST_CHECK_EQUAL(*t3->format_iso8601 (), "2019-04-25T15:41:47+0000");
+ }
+
+ BOOST_AUTO_TEST_CASE(FromString_iso8601_tzdiff)
+ {
+ const std::string in ("2019-04-26T13:45:02+0000");
+
+ this->set_tz ("UTC");
+ boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in, true, true, false);
+
+ this->set_tz ("CET");
+ boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in, true, true, false);
+
+ BOOST_CHECK_EQUAL(*t1->format_iso8601 (true, true, true, true), in);
+ BOOST_CHECK_EQUAL(*t2->format_iso8601 (true, true, true, true), "2019-04-26T13:45:02+0000");
+ }
+
BOOST_AUTO_TEST_CASE(FromString_iso8601_32bit_time_t_err)
{
const std::string timeless ("11:11:11");