forked from organicmaps/organicmaps
Don’t use sscanf. It’s not working on Android L.
This commit is contained in:
parent
3949d12800
commit
2583a32520
2 changed files with 67 additions and 16 deletions
|
@ -33,12 +33,25 @@ UNIT_TEST(Timer_TimestampConversion)
|
|||
TEST_EQUAL(StringToTimestamp("2012-12-02T21:08:34Z"), 1354482514, ());
|
||||
TEST_EQUAL(StringToTimestamp("2012-12-03T00:38:34+03:30"), 1354482514, ());
|
||||
TEST_EQUAL(StringToTimestamp("2012-12-02T11:08:34-10:00"), 1354482514, ());
|
||||
TEST_EQUAL(StringToTimestamp("2014-09-30T23:59:59+23:59"), 1412035259, ());
|
||||
|
||||
time_t now = time(0);
|
||||
time_t const now = time(0);
|
||||
TEST_EQUAL(now, StringToTimestamp(TimestampToString(now)), ());
|
||||
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("asd23423adsfbhj657"), ());
|
||||
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2012-aa-02T21:08:34Z"), ());
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2012-12-0ZT21:08:34Z"), ());
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2012:12:02T21-08-34Z"), ());
|
||||
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2012-"), ());
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2012-12-02"), ());
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("1970-01-01T"), ());
|
||||
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("2100-01--1T11:08:34-10:00"), ());
|
||||
TEST_EQUAL(INVALID_TIME_STAMP, StringToTimestamp("2012-12-02T11:08:34-25:88"), ());
|
||||
}
|
||||
|
|
|
@ -105,35 +105,73 @@ string TimestampToString(time_t time)
|
|||
return buf;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template <class T> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
time_t StringToTimestamp(string const & s)
|
||||
{
|
||||
tm t;
|
||||
memset(&t, 0, sizeof(t));
|
||||
tm t = {};
|
||||
|
||||
// Return current time in the case of failure
|
||||
time_t res = INVALID_TIME_STAMP;
|
||||
// Parse UTC format
|
||||
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)
|
||||
{
|
||||
if (6 == sscanf(s.c_str(), "%4d-%2d-%2dT%2d:%2d:%2dZ", &t.tm_year,
|
||||
&t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec))
|
||||
{
|
||||
t.tm_year -= 1900;
|
||||
t.tm_mon -= 1;
|
||||
// Parse UTC format
|
||||
if (*p == 'Z')
|
||||
res = my_timegm(&t);
|
||||
}
|
||||
}
|
||||
else if (s.size() == 25)
|
||||
{
|
||||
// Parse custom time zone offset format
|
||||
char sign;
|
||||
char const sign = *p++;
|
||||
int tzHours, tzMinutes;
|
||||
if (9 == sscanf(s.c_str(), "%4d-%2d-%2dT%2d:%2d:%2d%c%2d:%2d", &t.tm_year,
|
||||
&t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec,
|
||||
&sign, &tzHours, &tzMinutes))
|
||||
if (ParseInt(p, tzHours, 2) && *p++ == ':' &&
|
||||
ParseInt(p, tzMinutes, 2) && *p == 0 &&
|
||||
tzHours >= 0 && tzHours <= 23 &&
|
||||
tzMinutes >= 0 && tzMinutes <= 59)
|
||||
{
|
||||
t.tm_year -= 1900;
|
||||
t.tm_mon -= 1;
|
||||
time_t const tt = my_timegm(&t);
|
||||
|
||||
// Fix timezone offset
|
||||
if (sign == '-')
|
||||
res = tt + tzHours * 3600 + tzMinutes * 60;
|
||||
|
|
Loading…
Add table
Reference in a new issue