|
|
|
@ -415,6 +415,11 @@ public:
|
|
|
|
|
template<class StringType>
|
|
|
|
|
bool ParseHourMin(const StringType & str);
|
|
|
|
|
|
|
|
|
|
template<class CStringType>
|
|
|
|
|
bool ParseZoneOffset(const CStringType * str, const CStringType ** str_after = 0);
|
|
|
|
|
|
|
|
|
|
template<class StringType>
|
|
|
|
|
bool ParseZoneOffset(const StringType & str);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
parsing hour and minutes (if exists) and seconds (if exists)
|
|
|
|
@ -507,7 +512,7 @@ private:
|
|
|
|
|
void SkipWhite(const CStringType * & str);
|
|
|
|
|
|
|
|
|
|
template<class CStringType>
|
|
|
|
|
bool ReadInt(const CStringType * & str, int & result);
|
|
|
|
|
bool ReadInt(const CStringType * & str, int & result, size_t max_digits = 0);
|
|
|
|
|
|
|
|
|
|
template<class CStringType>
|
|
|
|
|
bool SkipSeparator(const CStringType * & str, int separator, int separator2 = -1, int separator3 = -1);
|
|
|
|
@ -720,6 +725,67 @@ bool Date::ParseHourMin(const StringType & str)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<class CStringType>
|
|
|
|
|
bool Date::ParseZoneOffset(const CStringType * str, const CStringType ** str_after)
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
bool is_sign = false;
|
|
|
|
|
int offset_hour = 0;
|
|
|
|
|
int offset_min = 0;
|
|
|
|
|
|
|
|
|
|
SkipWhite(str);
|
|
|
|
|
|
|
|
|
|
if( *str == '-' || *str == '+' )
|
|
|
|
|
{
|
|
|
|
|
if( *str == '-' )
|
|
|
|
|
is_sign = true;
|
|
|
|
|
|
|
|
|
|
str += 1;
|
|
|
|
|
|
|
|
|
|
if( ReadInt(str, offset_hour, 2) && offset_hour >= -12 && offset_hour <= 14 )
|
|
|
|
|
{
|
|
|
|
|
SkipWhite(str);
|
|
|
|
|
SetAfter(str, str_after);
|
|
|
|
|
|
|
|
|
|
if( *str == ':' )
|
|
|
|
|
{
|
|
|
|
|
str += 1;
|
|
|
|
|
SkipWhite(str);
|
|
|
|
|
SetAfter(str, str_after);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ReadInt(str, offset_min, 2) && offset_min > -60 && offset_min < 60 )
|
|
|
|
|
{
|
|
|
|
|
SetAfter(str, str_after);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
offset_min = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
time_t offset = (time_t)offset_hour * 60 * 60 + (time_t)offset_min * 60;
|
|
|
|
|
result = true;
|
|
|
|
|
|
|
|
|
|
if( is_sign )
|
|
|
|
|
offset = -offset;
|
|
|
|
|
|
|
|
|
|
FromTime(ToTime() - offset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<class StringType>
|
|
|
|
|
bool Date::ParseZoneOffset(const StringType & str)
|
|
|
|
|
{
|
|
|
|
|
return ParseZoneOffset(str.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<class CStringType>
|
|
|
|
|
bool Date::ParseTime(const CStringType * str, const CStringType ** str_after)
|
|
|
|
@ -801,7 +867,6 @@ bool Date::Parse(const CStringType * str, const CStringType ** str_after)
|
|
|
|
|
{
|
|
|
|
|
const CStringType * after;
|
|
|
|
|
bool result = false;
|
|
|
|
|
bool is_iso = false;
|
|
|
|
|
|
|
|
|
|
if( ParseYearMonthDay(str, &after) )
|
|
|
|
|
{
|
|
|
|
@ -813,17 +878,22 @@ bool is_iso = false;
|
|
|
|
|
// https://en.wikipedia.org/wiki/ISO_8601
|
|
|
|
|
// at the moment skip the 'T' character only
|
|
|
|
|
after += 1;
|
|
|
|
|
is_iso = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ParseHourMinSec(after, &after) )
|
|
|
|
|
{
|
|
|
|
|
SkipWhite(after);
|
|
|
|
|
result = true;
|
|
|
|
|
|
|
|
|
|
if( is_iso && *after == 'Z' )
|
|
|
|
|
if( *after == 'Z' )
|
|
|
|
|
{
|
|
|
|
|
after += 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// we dont have to check errors here
|
|
|
|
|
ParseZoneOffset(after, &after);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -864,17 +934,19 @@ void Date::SkipWhite(const CStringType * & str)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<class CStringType>
|
|
|
|
|
bool Date::ReadInt(const CStringType * & str, int & result)
|
|
|
|
|
bool Date::ReadInt(const CStringType * & str, int & result, size_t max_digits)
|
|
|
|
|
{
|
|
|
|
|
bool something_read = false;
|
|
|
|
|
|
|
|
|
|
SkipWhite(str);
|
|
|
|
|
result = 0;
|
|
|
|
|
size_t len = 0;
|
|
|
|
|
|
|
|
|
|
while( *str >= '0' && *str <= '9' )
|
|
|
|
|
while( *str >= '0' && *str <= '9' && (max_digits == 0 || len < max_digits))
|
|
|
|
|
{
|
|
|
|
|
result = result * 10 + (*str - '0');
|
|
|
|
|
str += 1;
|
|
|
|
|
len += 1;
|
|
|
|
|
something_read = true;
|
|
|
|
|
|
|
|
|
|
if( result > 10000 )
|
|
|
|
|