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.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -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 )