added: to Date: support for parsing timezone offsets

git-svn-id: svn://ttmath.org/publicrep/pikotools/trunk@1168 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2019-01-31 20:56:40 +00:00
parent 5a63a8c0ec
commit c2e63f9290
2 changed files with 79 additions and 7 deletions

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2012, Tomasz Sowa * Copyright (c) 2012-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -415,6 +415,11 @@ public:
template<class StringType> template<class StringType>
bool ParseHourMin(const StringType & str); 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) parsing hour and minutes (if exists) and seconds (if exists)
@ -507,7 +512,7 @@ private:
void SkipWhite(const CStringType * & str); void SkipWhite(const CStringType * & str);
template<class CStringType> 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> template<class CStringType>
bool SkipSeparator(const CStringType * & str, int separator, int separator2 = -1, int separator3 = -1); 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> template<class CStringType>
bool Date::ParseTime(const CStringType * str, const CStringType ** str_after) 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; const CStringType * after;
bool result = false; bool result = false;
bool is_iso = false;
if( ParseYearMonthDay(str, &after) ) if( ParseYearMonthDay(str, &after) )
{ {
@ -813,17 +878,22 @@ bool is_iso = false;
// https://en.wikipedia.org/wiki/ISO_8601 // https://en.wikipedia.org/wiki/ISO_8601
// at the moment skip the 'T' character only // at the moment skip the 'T' character only
after += 1; after += 1;
is_iso = true;
} }
if( ParseHourMinSec(after, &after) ) if( ParseHourMinSec(after, &after) )
{ {
SkipWhite(after);
result = true; result = true;
if( is_iso && *after == 'Z' ) if( *after == 'Z' )
{ {
after += 1; 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> 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; bool something_read = false;
SkipWhite(str); SkipWhite(str);
result = 0; 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'); result = result * 10 + (*str - '0');
str += 1; str += 1;
len += 1;
something_read = true; something_read = true;
if( result > 10000 ) if( result > 10000 )