Refactor time zone parsing into a separate function from ParseRfc822Date()
For now, the new function is private and undocumented.
This commit is contained in:
parent
770cf26afe
commit
136b1713e1
@ -1150,6 +1150,10 @@ private:
|
||||
// assign the preferred first day of a week to flags, if necessary
|
||||
void UseEffectiveWeekDayFlags(WeekFlags &flags) const;
|
||||
|
||||
// parse time zone (e.g. "+0100") between [iterator,dateEnd)
|
||||
bool ParseRFC822TimeZone(wxString::const_iterator* iterator,
|
||||
const wxString::const_iterator& dateEnd);
|
||||
|
||||
// the internal representation of the time is the amount of milliseconds
|
||||
// elapsed since the origin which is set by convention to the UNIX/C epoch
|
||||
// value: the midnight of January 1, 1970 (UTC)
|
||||
|
@ -736,6 +736,106 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
wxDateTime::ParseRFC822TimeZone(wxString::const_iterator *iterator,
|
||||
const wxString::const_iterator &pEnd)
|
||||
{
|
||||
wxString::const_iterator& p = *iterator;
|
||||
int offset = 0; // just to suppress warnings
|
||||
if ( *p == '-' || *p == '+' )
|
||||
{
|
||||
// the explicit offset given: it has the form of hhmm
|
||||
bool plus = *p++ == '+';
|
||||
|
||||
if ( p == pEnd || !wxIsdigit(*p) ||
|
||||
p + 1 == pEnd || !wxIsdigit(*(p + 1)) )
|
||||
return false;
|
||||
|
||||
|
||||
// hours
|
||||
offset = MIN_PER_HOUR*(10*(*p - '0') + (*(p + 1) - '0'));
|
||||
|
||||
p += 2;
|
||||
|
||||
if ( p == pEnd || !wxIsdigit(*p) ||
|
||||
p + 1 == pEnd || !wxIsdigit(*(p + 1)) )
|
||||
return false;
|
||||
|
||||
// minutes
|
||||
offset += 10*(*p - '0') + (*(p + 1) - '0');
|
||||
|
||||
if ( !plus )
|
||||
offset = -offset;
|
||||
|
||||
p += 2;
|
||||
}
|
||||
else // not numeric
|
||||
{
|
||||
// the symbolic timezone given: may be either military timezone or one
|
||||
// of standard abbreviations
|
||||
if ( p + 1 == pEnd )
|
||||
{
|
||||
// military: Z = UTC, J unused, A = -1, ..., Y = +12
|
||||
static const int offsets[26] =
|
||||
{
|
||||
//A B C D E F G H I J K L M
|
||||
-1, -2, -3, -4, -5, -6, -7, -8, -9, 0, -10, -11, -12,
|
||||
//N O P R Q S T U V W Z Y Z
|
||||
+1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, 0
|
||||
};
|
||||
|
||||
if ( *p < wxT('A') || *p > wxT('Z') || *p == wxT('J') )
|
||||
return false;
|
||||
|
||||
offset = offsets[*p++ - 'A'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// abbreviation
|
||||
const wxString tz(p, pEnd);
|
||||
if ( tz == wxT("UT") || tz == wxT("UTC") || tz == wxT("GMT") )
|
||||
offset = 0;
|
||||
else if ( tz == wxT("AST") )
|
||||
offset = AST - GMT0;
|
||||
else if ( tz == wxT("ADT") )
|
||||
offset = ADT - GMT0;
|
||||
else if ( tz == wxT("EST") )
|
||||
offset = EST - GMT0;
|
||||
else if ( tz == wxT("EDT") )
|
||||
offset = EDT - GMT0;
|
||||
else if ( tz == wxT("CST") )
|
||||
offset = CST - GMT0;
|
||||
else if ( tz == wxT("CDT") )
|
||||
offset = CDT - GMT0;
|
||||
else if ( tz == wxT("MST") )
|
||||
offset = MST - GMT0;
|
||||
else if ( tz == wxT("MDT") )
|
||||
offset = MDT - GMT0;
|
||||
else if ( tz == wxT("PST") )
|
||||
offset = PST - GMT0;
|
||||
else if ( tz == wxT("PDT") )
|
||||
offset = PDT - GMT0;
|
||||
else
|
||||
return false;
|
||||
|
||||
p += tz.length();
|
||||
}
|
||||
|
||||
// make it minutes
|
||||
offset *= MIN_PER_HOUR;
|
||||
}
|
||||
|
||||
// As always, dealing with the time zone is the most interesting part: we
|
||||
// can't just use MakeFromTimeZone() here because it wouldn't handle the
|
||||
// DST correctly because the TZ specified in the string is DST-invariant
|
||||
// and so we have to manually shift to the UTC first and then convert to
|
||||
// the local TZ.
|
||||
*this -= wxTimeSpan::Minutes(offset);
|
||||
MakeFromUTC();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// this function parses a string in (strict) RFC 822 format: see the section 5
|
||||
// of the RFC for the detailed description, but briefly it's something of the
|
||||
// form "Sat, 18 Dec 1999 00:48:30 +0100"
|
||||
@ -889,102 +989,13 @@ wxDateTime::ParseRfc822Date(const wxString& originalDate, wxString::const_iterat
|
||||
if ( *p++ != ' ' )
|
||||
return false;
|
||||
|
||||
// 7. now the interesting part: the timezone
|
||||
int offset = 0; // just to suppress warnings
|
||||
if ( *p == '-' || *p == '+' )
|
||||
{
|
||||
// the explicit offset given: it has the form of hhmm
|
||||
bool plus = *p++ == '+';
|
||||
|
||||
if ( p == pEnd || !wxIsdigit(*p) ||
|
||||
p + 1 == pEnd || !wxIsdigit(*(p + 1)) )
|
||||
return false;
|
||||
|
||||
|
||||
// hours
|
||||
offset = MIN_PER_HOUR*(10*(*p - '0') + (*(p + 1) - '0'));
|
||||
|
||||
p += 2;
|
||||
|
||||
if ( p == pEnd || !wxIsdigit(*p) ||
|
||||
p + 1 == pEnd || !wxIsdigit(*(p + 1)) )
|
||||
return false;
|
||||
|
||||
// minutes
|
||||
offset += 10*(*p - '0') + (*(p + 1) - '0');
|
||||
|
||||
if ( !plus )
|
||||
offset = -offset;
|
||||
|
||||
p += 2;
|
||||
}
|
||||
else // not numeric
|
||||
{
|
||||
// the symbolic timezone given: may be either military timezone or one
|
||||
// of standard abbreviations
|
||||
if ( p + 1 == pEnd )
|
||||
{
|
||||
// military: Z = UTC, J unused, A = -1, ..., Y = +12
|
||||
static const int offsets[26] =
|
||||
{
|
||||
//A B C D E F G H I J K L M
|
||||
-1, -2, -3, -4, -5, -6, -7, -8, -9, 0, -10, -11, -12,
|
||||
//N O P R Q S T U V W Z Y Z
|
||||
+1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, 0
|
||||
};
|
||||
|
||||
if ( *p < wxT('A') || *p > wxT('Z') || *p == wxT('J') )
|
||||
return false;
|
||||
|
||||
offset = offsets[*p++ - 'A'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// abbreviation
|
||||
const wxString tz(p, pEnd);
|
||||
if ( tz == wxT("UT") || tz == wxT("UTC") || tz == wxT("GMT") )
|
||||
offset = 0;
|
||||
else if ( tz == wxT("AST") )
|
||||
offset = AST - GMT0;
|
||||
else if ( tz == wxT("ADT") )
|
||||
offset = ADT - GMT0;
|
||||
else if ( tz == wxT("EST") )
|
||||
offset = EST - GMT0;
|
||||
else if ( tz == wxT("EDT") )
|
||||
offset = EDT - GMT0;
|
||||
else if ( tz == wxT("CST") )
|
||||
offset = CST - GMT0;
|
||||
else if ( tz == wxT("CDT") )
|
||||
offset = CDT - GMT0;
|
||||
else if ( tz == wxT("MST") )
|
||||
offset = MST - GMT0;
|
||||
else if ( tz == wxT("MDT") )
|
||||
offset = MDT - GMT0;
|
||||
else if ( tz == wxT("PST") )
|
||||
offset = PST - GMT0;
|
||||
else if ( tz == wxT("PDT") )
|
||||
offset = PDT - GMT0;
|
||||
else
|
||||
return false;
|
||||
|
||||
p += tz.length();
|
||||
}
|
||||
|
||||
// make it minutes
|
||||
offset *= MIN_PER_HOUR;
|
||||
}
|
||||
|
||||
|
||||
// the spec was correct, construct the date from the values we found
|
||||
Set(day, mon, year, hour, min, sec);
|
||||
|
||||
// As always, dealing with the time zone is the most interesting part: we
|
||||
// can't just use MakeFromTimeZone() here because it wouldn't handle the
|
||||
// DST correctly because the TZ specified in the string is DST-invariant
|
||||
// and so we have to manually shift to the UTC first and then convert to
|
||||
// the local TZ.
|
||||
*this -= wxTimeSpan::Minutes(offset);
|
||||
MakeFromUTC();
|
||||
// 7. now the interesting part: the timezone
|
||||
|
||||
if ( !ParseRFC822TimeZone(&p, pEnd) )
|
||||
return false;
|
||||
|
||||
if ( end )
|
||||
*end = originalDate.begin() + (p - date.begin());
|
||||
|
Loading…
Reference in New Issue
Block a user