Add time zone parsing support for HH:MM

This commit is contained in:
Dimitri Schoolwerth
2017-06-20 16:38:14 +04:00
committed by Dimitri Schoolwerth
parent a3a4e7c638
commit 101433190f
2 changed files with 51 additions and 8 deletions

View File

@@ -90,11 +90,13 @@ namespace
// all the functions below taking non-const wxString::const_iterator p advance // all the functions below taking non-const wxString::const_iterator p advance
// it until the end of the match // it until the end of the match
// scans all digits (but no more than len) and returns the resulting number // Scans all digits (but no more than len) and returns the resulting number.
// Optionally writes number of digits scanned to numScannedDigits.
bool GetNumericToken(size_t len, bool GetNumericToken(size_t len,
wxString::const_iterator& p, wxString::const_iterator& p,
const wxString::const_iterator& end, const wxString::const_iterator& end,
unsigned long *number) unsigned long *number,
size_t *numScannedDigits = NULL)
{ {
size_t n = 1; size_t n = 1;
wxString s; wxString s;
@@ -106,6 +108,11 @@ bool GetNumericToken(size_t len,
break; break;
} }
if (numScannedDigits)
{
*numScannedDigits = n - 1;
}
return !s.empty() && s.ToULong(number); return !s.empty() && s.ToULong(number);
} }
@@ -1499,14 +1506,34 @@ wxDateTime::ParseFormat(const wxString& date,
else else
return false; // no match return false; // no match
// here should follow 4 digits HHMM
++input; ++input;
unsigned long tzHourMin;
if ( !GetNumericToken(4, input, end, &tzHourMin) )
return false; // no match
const unsigned hours = tzHourMin / 100; // Here should follow exactly 2 digits for hours (HH).
const unsigned minutes = tzHourMin % 100; const size_t numRequiredDigits = 2;
size_t numScannedDigits;
unsigned long hours;
if ( !GetNumericToken(numRequiredDigits, input, end,
&hours, &numScannedDigits)
|| numScannedDigits != numRequiredDigits)
{
return false; // No match.
}
// Optionally followed by a colon separator.
if ( input != end && *input == wxS(':') )
{
++input;
}
// Followed by exactly 2 digits for minutes (MM).
unsigned long minutes;
if ( !GetNumericToken(numRequiredDigits, input, end,
&minutes, &numScannedDigits)
|| numScannedDigits != numRequiredDigits)
{
return false; // No match.
}
if ( hours > 12 || minutes > 59 ) if ( hours > 12 || minutes > 59 )
return false; // bad format return false; // bad format

View File

@@ -906,9 +906,25 @@ void DateTimeTestCase::TestTimeZoneParse()
// Z as UTC designator. // Z as UTC designator.
{ "13:37Z", true }, { "13:37Z", true },
// Colon as HH and MM separator.
{ "17:37+04:00", true },
// // Colon separator and non-zero MM.
{ "09:07-04:30", true },
{ "19:22+05:45", true },
// Some invalid ones too. // Some invalid ones too.
{ "00:00-1300" }, // Offset out of range. { "00:00-1300" }, // Offset out of range.
{ "00:00+1300" }, // Offset out of range. { "00:00+1300" }, // Offset out of range.
// Not exactly 2 digits for hours and minutes.
{ "17:37+4" },
{ "17:37+400" },
{ "17:37+040" },
{ "17:37+4:0" },
{ "17:37+4:00" },
{ "17:37+04:0" },
}; };
for ( size_t n = 0; n < WXSIZEOF(parseTestTimeZones); ++n ) for ( size_t n = 0; n < WXSIZEOF(parseTestTimeZones); ++n )