/*=================================ParseTimeZone==========================
**Action: Parse the timezone offset in the following format:
** "+8", "+08", "+0800", "+0800"
** This method is used by DateTime.Parse().
**Returns: The TimeZone offset.
**Arguments:
** str the parsing string
**Exceptions:
** FormatException if invalid timezone format is found.
============================================================================*/
private static bool ParseTimeZone(ref __DTString str, ref TimeSpan result) {
// The hour/minute offset for timezone.
int hourOffset = 0;
int minuteOffset = 0;
DTSubString sub;
// Consume the +/- character that has already been read
sub = str.GetSubString();
if (sub.length != 1) {
return false;
}
char offsetChar = sub[0];
if (offsetChar != '+' && offsetChar != '-') {
return false;
}
str.ConsumeSubString(sub);
sub = str.GetSubString();
if (sub.type != DTSubStringType.Number) {
return false;
}
int value = sub.value;
int length = sub.length;
if (length == 1 || length == 2) {
// Parsing "+8" or "+08"
hourOffset = value;
str.ConsumeSubString(sub);
// See if we have minutes
sub = str.GetSubString();
if (sub.length == 1 && sub[0] == ':') {
// Parsing "+8:00" or "+08:00"
str.ConsumeSubString(sub);
sub = str.GetSubString();
if (sub.type != DTSubStringType.Number || sub.length < 1 || sub.length > 2) {
return false;
}
minuteOffset = sub.value;
str.ConsumeSubString(sub);
}
}
else if (length == 3 || length == 4) {
// Parsing "+800" or "+0800"
hourOffset = value / 100;
minuteOffset = value % 100;
str.ConsumeSubString(sub);
}
else {
// Wrong number of digits
return false;
}
Contract.Assert(hourOffset >= 0 && hourOffset <= 99, "hourOffset >= 0 && hourOffset <= 99");
Contract.Assert(minuteOffset >= 0 && minuteOffset <= 99, "minuteOffset >= 0 && minuteOffset <= 99");
if (minuteOffset < 0 || minuteOffset >= 60) {
return false;
}
result = new TimeSpan(hourOffset, minuteOffset, 0);
if (offsetChar == '-') {
result = result.Negate();
}
return true;
}