diff options
| -rw-r--r-- | src/local_time.cc | 59 | ||||
| -rw-r--r-- | test/local_time_test.cc | 14 |
2 files changed, 49 insertions, 24 deletions
diff --git a/src/local_time.cc b/src/local_time.cc index ee5db5de..8a009209 100644 --- a/src/local_time.cc +++ b/src/local_time.cc @@ -109,22 +109,45 @@ LocalTime::set_local_time_zone () _tz_minute = offset.minutes (); } -/** @param s A string of the form 2013-01-05T18:06:59[.123]+04:00 */ +/** @param s A string of the form 2013-01-05T18:06:59[.123][+04:00] */ LocalTime::LocalTime (string s) { - /* 2013-01-05T18:06:59+04:00 or 2013-01-05T18:06:59.123+04:00 */ - /* 0123456789012345678901234 or 01234567890123456789012345678 */ + /* 2013-01-05T18:06:59 or 2013-01-05T18:06:59.123 or 2013-01-05T18:06:59+04:00 or 2013-01-05T18:06:59.123+04:00 */ + /* 0123456789012345678 or 01234567890123456789012 or 0123456789012345678901234 or 01234567890123456789012345678 */ - if (s.length() < 25) { + if (s.length() < 19) { throw TimeFormatError (s); } - /* Check incidental characters */ - bool const common = s[4] == '-' && s[7] == '-' && s[10] == 'T' && s[13] == ':' && s[16] == ':'; - bool const without_millisecond = common && s[22] == ':'; - bool const with_millisecond = common && s[19] == '.' && s[26] == ':'; + bool with_millisecond = false; + bool with_tz = false; + + switch (s.length ()) { + case 19: + break; + case 23: + with_millisecond = true; + break; + case 25: + with_tz = true; + break; + case 29: + with_millisecond = with_tz = true; + break; + default: + throw TimeFormatError (s); + } + + int const tz_pos = with_millisecond ? 23 : 19; - if (!with_millisecond && !without_millisecond) { + /* Check incidental characters */ + if (s[4] != '-' || s[7] != '-' || s[10] != 'T' || s[13] != ':' || s[16] != ':') { + throw TimeFormatError (s); + } + if (with_millisecond && s[19] != '.') { + throw TimeFormatError (s); + } + if (with_tz && s[tz_pos] != '+' && s[tz_pos] != '-') { throw TimeFormatError (s); } @@ -134,22 +157,12 @@ LocalTime::LocalTime (string s) _hour = lexical_cast<int> (s.substr (11, 2)); _minute = lexical_cast<int> (s.substr (14, 2)); _second = lexical_cast<int> (s.substr (17, 2)); - if (without_millisecond) { - _millisecond = 0; - _tz_hour = lexical_cast<int> (s.substr (20, 2)); - _tz_minute = lexical_cast<int> (s.substr (23, 2)); - } else { - _millisecond = lexical_cast<int> (s.substr (20, 3)); - _tz_hour = lexical_cast<int> (s.substr (24, 2)); - _tz_minute = lexical_cast<int> (s.substr (27, 2)); - } - - int const plus_minus_position = with_millisecond ? 23 : 19; + _millisecond = with_millisecond ? lexical_cast<int> (s.substr (20, 3)) : 0; + _tz_hour = with_tz ? lexical_cast<int> (s.substr (tz_pos + 1, 2)) : 0; + _tz_minute = with_tz ? lexical_cast<int> (s.substr (tz_pos + 4, 2)) : 0; - if (s[plus_minus_position] == '-') { + if (with_tz && s[tz_pos] == '-') { _tz_hour = -_tz_hour; - } else if (s[plus_minus_position] != '+') { - throw TimeFormatError (s); } } diff --git a/test/local_time_test.cc b/test/local_time_test.cc index 83e9ba7f..5b954e2f 100644 --- a/test/local_time_test.cc +++ b/test/local_time_test.cc @@ -96,5 +96,17 @@ BOOST_AUTO_TEST_CASE (local_time_test) BOOST_CHECK_EQUAL (b._second, 56); BOOST_CHECK_EQUAL (b._millisecond, 491); } -} + { + dcp::LocalTime b ("2015-11-18T19:26:45"); + BOOST_CHECK_EQUAL (b._year, 2015); + BOOST_CHECK_EQUAL (b._month, 11); + BOOST_CHECK_EQUAL (b._day, 18); + BOOST_CHECK_EQUAL (b._hour, 19); + BOOST_CHECK_EQUAL (b._minute, 26); + BOOST_CHECK_EQUAL (b._second, 45); + BOOST_CHECK_EQUAL (b._millisecond, 0); + BOOST_CHECK_EQUAL (b._tz_hour, 0); + BOOST_CHECK_EQUAL (b._tz_minute, 0); + } +} |
