From 2875a76a1db343a52fa09a5b739ed86abd91013f Mon Sep 17 00:00:00 2001 From: vng Date: Fri, 10 Oct 2014 13:38:03 +0300 Subject: [PATCH] [core] Use std::get_time function to parse date. --- base/base_tests/timer_test.cpp | 5 ++- base/timer.cpp | 69 +++++++++++----------------------- std/iomanip.hpp | 1 + 3 files changed, 26 insertions(+), 49 deletions(-) diff --git a/base/base_tests/timer_test.cpp b/base/base_tests/timer_test.cpp index c2446aea98..f6932153bb 100644 --- a/base/base_tests/timer_test.cpp +++ b/base/base_tests/timer_test.cpp @@ -50,8 +50,11 @@ UNIT_TEST(Timer_TimestampConversion) TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("1970-01-01T21:"), ()); TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("1970-01-01T21:08:34"), ()); - TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("1000-12-02T11:08:34-10:00"), ()); TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2000-00-02T11:08:34-10:00"), ()); + TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2000-13-02T11:08:34-10:00"), ()); + TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2000-01-00T11:08:34-10:00"), ()); + TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2000-01-32T11:08:34-10:00"), ()); TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2100-01--1T11:08:34-10:00"), ()); + TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2100--1-02T11:08:34-10:00"), ()); TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2012-12-02T11:08:34-25:88"), ()); } diff --git a/base/timer.cpp b/base/timer.cpp index 731fa9d8a2..d80f97d7f1 100644 --- a/base/timer.cpp +++ b/base/timer.cpp @@ -5,7 +5,8 @@ #include "../std/target_os.hpp" #include "../std/systime.hpp" #include "../std/cstdio.hpp" -#include "../std/cstring.hpp" +#include "../std/sstream.hpp" +#include "../std/iomanip.hpp" namespace my @@ -108,75 +109,47 @@ string TimestampToString(time_t time) namespace { -template bool ParseInt(char const * & s, T & i, size_t sz) -{ - char * stop; - long const x = strtol(s, &stop, 10); - if (stop && (stop - s == sz)) - { - i = x; - s = stop; - return true; - } - return false; -} - bool IsValid(tm const & t) { - return (t.tm_year >= 1900 && - t.tm_mon >= 1 && t.tm_mon <= 12 && - t.tm_mday >= 1 && t.tm_mday <= 31 && - t.tm_hour >= 0 && t.tm_hour <= 23 && - t.tm_min >= 0 && t.tm_min <= 59 && - t.tm_sec >= 0 && t.tm_sec <= 59); + /// @todo Funny thing, but "00" month is accepted as valid in get_time function. + /// Seems like a bug in the std library. + return (t.tm_mon >= 0 && t.tm_mon <= 11); } } time_t StringToTimestamp(string const & s) { - tm t = {}; - // Return current time in the case of failure time_t res = INVALID_TIME_STAMP; - char const * p = s.c_str(); - - if (ParseInt(p, t.tm_year, 4) && *p++ == '-' && - ParseInt(p, t.tm_mon, 2) && *p++ == '-' && - ParseInt(p, t.tm_mday, 2) && *p++ == 'T' && - ParseInt(p, t.tm_hour, 2) && *p++ == ':' && - ParseInt(p, t.tm_min, 2) && *p++ == ':' && - ParseInt(p, t.tm_sec, 2) && IsValid(t)) - { - t.tm_year -= 1900; - t.tm_mon -= 1; - } - else - return res; if (s.size() == 20) { - // Parse UTC format - if (*p == 'Z') + // Parse UTC format: 1970-01-01T00:00:00Z + tm t; + istringstream ss(s); + ss >> get_time(&t, "%Y-%m-%dT%H:%M:%SZ"); + + if (!ss.fail() && IsValid(t)) res = my_timegm(&t); } else if (s.size() == 25) { - // Parse custom time zone offset format - char const sign = *p++; - int tzHours, tzMinutes; - if (ParseInt(p, tzHours, 2) && *p++ == ':' && - ParseInt(p, tzMinutes, 2) && *p == 0 && - tzHours >= 0 && tzHours <= 23 && - tzMinutes >= 0 && tzMinutes <= 59) + // Parse custom time zone offset format: 2012-12-03T00:38:34+03:30 + tm t1, t2; + char sign; + istringstream ss(s); + ss >> get_time(&t1, "%Y-%m-%dT%H:%M:%S") >> sign >> get_time(&t2, "%H:%M"); + + if (!ss.fail() && IsValid(t1)) { - time_t const tt = my_timegm(&t); + time_t const tt = my_timegm(&t1); // Fix timezone offset if (sign == '-') - res = tt + tzHours * 3600 + tzMinutes * 60; + res = tt + t2.tm_hour * 3600 + t2.tm_min * 60; else if (sign == '+') - res = tt - tzHours * 3600 - tzMinutes * 60; + res = tt - t2.tm_hour * 3600 - t2.tm_min * 60; } } diff --git a/std/iomanip.hpp b/std/iomanip.hpp index 93c74e0bb7..b24867e6f0 100644 --- a/std/iomanip.hpp +++ b/std/iomanip.hpp @@ -11,6 +11,7 @@ using std::setfill; using std::hex; using std::fixed; using std::setprecision; +using std::get_time; #ifdef DEBUG_NEW #define new DEBUG_NEW