private static bool ParseTimeZoneOffset(ref __DTString str, int len, ref TimeSpan result) { bool flag = true; int num = 0; int hours; switch (len) { case 1: case 2: { if (!DateTimeParse.ParseSign(ref str, ref flag)) { return false; } if (!DateTimeParse.ParseDigits(ref str, len, out hours)) { return false; } break; } default: { if (!DateTimeParse.ParseSign(ref str, ref flag)) { return false; } if (!DateTimeParse.ParseDigits(ref str, 1, out hours)) { return false; } if (str.Match(":")) { if (!DateTimeParse.ParseDigits(ref str, 2, out num)) { return false; } } else { str.Index--; if (!DateTimeParse.ParseDigits(ref str, 2, out num)) { return false; } } break; } } if (num < 0 || num >= 60) { return false; } result = new TimeSpan(hours, num, 0); if (!flag) { result = result.Negate(); } return true; }
private static bool ParseByFormat(ref __DTString str, ref __DTString format, ref ParsingInfo parseInfo, DateTimeFormatInfo dtfi, ref DateTimeResult result) { int num = 0; int newValue = 0; int newValue2 = 0; int newValue3 = 0; int newValue4 = 0; int newValue5 = 0; int newValue6 = 0; int newValue7 = 0; double num2 = 0.0; DateTimeParse.TM tM = DateTimeParse.TM.AM; char @char = format.GetChar(); char c = @char; if (c <= 'H') { if (c <= '\'') { if (c != '"') { switch (c) { case '%': { if (format.Index >= format.Value.Length - 1 || format.Value[format.Index + 1] == '%') { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } return true; } case '&': { goto IL_991; } case '\'': { break; } default: { goto IL_991; } } } StringBuilder stringBuilder = new StringBuilder(); if (!DateTimeParse.TryParseQuoteString(format.Value, format.Index, stringBuilder, out num)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadQuote", @char); return false; } format.Index += num - 1; string text = stringBuilder.ToString(); for (int i = 0; i < text.Length; i++) { if (text[i] == ' ' && parseInfo.fAllowInnerWhite) { str.SkipWhiteSpaces(); } else { if (!str.Match(text[i])) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } } if ((result.flags & ParseFlags.CaptureOffset) == (ParseFlags)0) { return true; } if ((result.flags & ParseFlags.Rfc1123Pattern) != (ParseFlags)0 && text == "GMT") { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; return true; } if ((result.flags & ParseFlags.UtcSortPattern) != (ParseFlags)0 && text == "Z") { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; return true; } return true; } else { switch (c) { case '.': { if (str.Match(@char)) { return true; } if (format.GetNext() && format.Match('F')) { format.GetRepeatCount(); return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } case '/': { if (!str.Match(dtfi.DateSeparator)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } return true; } default: { if (c != ':') { switch (c) { case 'F': { break; } case 'G': { goto IL_991; } case 'H': { num = format.GetRepeatCount(); if (!DateTimeParse.ParseDigits(ref str, (num < 2) ? 1 : 2, out newValue5)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!DateTimeParse.CheckNewValue(ref result.Hour, newValue5, @char, ref result)) { return false; } return true; } default: { goto IL_991; } } } else { if (!str.Match(dtfi.TimeSeparator)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } return true; } break; } } } } else { if (c <= 'h') { switch (c) { case 'K': { if (str.Match('Z')) { if ((result.flags & ParseFlags.TimeZoneUsed) != (ParseFlags)0 && result.timeZoneOffset != TimeSpan.Zero) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K'); return false; } result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0L); result.flags |= ParseFlags.TimeZoneUtc; return true; } else { if (!str.Match('+') && !str.Match('-')) { return true; } str.Index--; TimeSpan timeSpan = new TimeSpan(0L); if (!DateTimeParse.ParseTimeZoneOffset(ref str, 3, ref timeSpan)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if ((result.flags & ParseFlags.TimeZoneUsed) != (ParseFlags)0 && timeSpan != result.timeZoneOffset) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K'); return false; } result.timeZoneOffset = timeSpan; result.flags |= ParseFlags.TimeZoneUsed; return true; } break; } case 'L': { goto IL_991; } case 'M': { num = format.GetRepeatCount(); if (num <= 2) { if (!DateTimeParse.ParseDigits(ref str, num, out newValue2) && (!parseInfo.fCustomNumberParser || !parseInfo.parseNumberDelegate(ref str, num, out newValue2))) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { if (num == 3) { if (!DateTimeParse.MatchAbbreviatedMonthName(ref str, dtfi, ref newValue2)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { if (!DateTimeParse.MatchMonthName(ref str, dtfi, ref newValue2)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } result.flags |= ParseFlags.ParsedMonthName; } if (!DateTimeParse.CheckNewValue(ref result.Month, newValue2, @char, ref result)) { return false; } return true; } default: { switch (c) { case 'Z': { if ((result.flags & ParseFlags.TimeZoneUsed) != (ParseFlags)0 && result.timeZoneOffset != TimeSpan.Zero) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'Z'); return false; } result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0L); result.flags |= ParseFlags.TimeZoneUtc; str.Index++; if (!DateTimeParse.GetTimeZoneName(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.Index--; return true; } case '[': { goto IL_991; } case '\\': { if (!format.GetNext()) { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } if (!str.Match(format.GetChar())) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } return true; } default: { switch (c) { case 'd': { num = format.GetRepeatCount(); if (num <= 2) { if (!DateTimeParse.ParseDigits(ref str, num, out newValue3) && (!parseInfo.fCustomNumberParser || !parseInfo.parseNumberDelegate(ref str, num, out newValue3))) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!DateTimeParse.CheckNewValue(ref result.Day, newValue3, @char, ref result)) { return false; } return true; } else { if (num == 3) { if (!DateTimeParse.MatchAbbreviatedDayName(ref str, dtfi, ref newValue4)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { if (!DateTimeParse.MatchDayName(ref str, dtfi, ref newValue4)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } if (!DateTimeParse.CheckNewValue(ref parseInfo.dayOfWeek, newValue4, @char, ref result)) { return false; } return true; } break; } case 'e': { goto IL_991; } case 'f': { break; } case 'g': { num = format.GetRepeatCount(); if (!DateTimeParse.MatchEraName(ref str, dtfi, ref result.era)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } return true; } case 'h': { parseInfo.fUseHour12 = true; num = format.GetRepeatCount(); if (!DateTimeParse.ParseDigits(ref str, (num < 2) ? 1 : 2, out newValue5)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!DateTimeParse.CheckNewValue(ref result.Hour, newValue5, @char, ref result)) { return false; } return true; } default: { goto IL_991; } } break; } } break; } } } else { if (c != 'm') { switch (c) { case 's': { num = format.GetRepeatCount(); if (!DateTimeParse.ParseDigits(ref str, (num < 2) ? 1 : 2, out newValue7)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!DateTimeParse.CheckNewValue(ref result.Second, newValue7, @char, ref result)) { return false; } return true; } case 't': { num = format.GetRepeatCount(); if (num == 1) { if (!DateTimeParse.MatchAbbreviatedTimeMark(ref str, dtfi, ref tM)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { if (!DateTimeParse.MatchTimeMark(ref str, dtfi, ref tM)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } if (parseInfo.timeMark == DateTimeParse.TM.NotSet) { parseInfo.timeMark = tM; return true; } if (parseInfo.timeMark != tM) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", @char); return false; } return true; } default: { switch (c) { case 'y': { num = format.GetRepeatCount(); bool flag; if (dtfi.HasForceTwoDigitYears) { flag = DateTimeParse.ParseDigits(ref str, 1, 4, out newValue); } else { if (num <= 2) { parseInfo.fUseTwoDigitYear = true; } flag = DateTimeParse.ParseDigits(ref str, num, out newValue); } if (!flag && parseInfo.fCustomNumberParser) { flag = parseInfo.parseNumberDelegate(ref str, num, out newValue); } if (!flag) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!DateTimeParse.CheckNewValue(ref result.Year, newValue, @char, ref result)) { return false; } return true; } case 'z': { num = format.GetRepeatCount(); TimeSpan timeSpan2 = new TimeSpan(0L); if (!DateTimeParse.ParseTimeZoneOffset(ref str, num, ref timeSpan2)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if ((result.flags & ParseFlags.TimeZoneUsed) != (ParseFlags)0 && timeSpan2 != result.timeZoneOffset) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'z'); return false; } result.timeZoneOffset = timeSpan2; result.flags |= ParseFlags.TimeZoneUsed; return true; } default: { goto IL_991; } } break; } } } else { num = format.GetRepeatCount(); if (!DateTimeParse.ParseDigits(ref str, (num < 2) ? 1 : 2, out newValue6)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!DateTimeParse.CheckNewValue(ref result.Minute, newValue6, @char, ref result)) { return false; } return true; } } } num = format.GetRepeatCount(); if (num > 7) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!DateTimeParse.ParseFractionExact(ref str, num, ref num2) && @char == 'f') { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (result.fraction < 0.0) { result.fraction = num2; return true; } if (num2 != result.fraction) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", @char); return false; } return true; IL_991: if (@char == ' ') { if (!parseInfo.fAllowInnerWhite && !str.Match(@char)) { if (parseInfo.fAllowTrailingWhite && format.GetNext() && DateTimeParse.ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) { return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { if (format.MatchSpecifiedWord("GMT")) { format.Index += "GMT".Length - 1; result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; if (!str.Match("GMT")) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { if (!str.Match(@char)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } } return true; }
// Given a specified format character, parse and update the parsing result. // private static bool ParseByFormat( ref __DTString str, ref __DTString format, ref ParsingInfo parseInfo, DateTimeFormatInfo dtfi, ref DateTimeResult result) { int tokenLen = 0; int tempYear = 0, tempMonth = 0, tempDay = 0, tempDayOfWeek = 0, tempHour = 0, tempMinute = 0, tempSecond = 0; double tempFraction = 0; TM tempTimeMark = 0; char ch = format.GetChar(); switch (ch) { case 'y': tokenLen = format.GetRepeatCount(); bool parseResult; if (dtfi.HasForceTwoDigitYears) { parseResult = ParseDigits(ref str, 1, 4, out tempYear); } else { if (tokenLen <= 2) { parseInfo.fUseTwoDigitYear = true; } parseResult = ParseDigits(ref str, tokenLen, out tempYear); } if (!parseResult && parseInfo.fCustomNumberParser) { parseResult = parseInfo.parseNumberDelegate(ref str, tokenLen, out tempYear); } if (!parseResult) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } if (!CheckNewValue(ref result.Year, tempYear, ch, ref result)) { return (false); } break; case 'M': tokenLen = format.GetRepeatCount(); if (tokenLen <= 2) { if (!ParseDigits(ref str, tokenLen, out tempMonth)) { if (!parseInfo.fCustomNumberParser || !parseInfo.parseNumberDelegate(ref str, tokenLen, out tempMonth)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } } else { if (tokenLen == 3) { if (!MatchAbbreviatedMonthName(ref str, dtfi, ref tempMonth)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } else { if (!MatchMonthName(ref str, dtfi, ref tempMonth)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } result.flags |= ParseFlags.ParsedMonthName; } if (!CheckNewValue(ref result.Month, tempMonth, ch, ref result)) { return (false); } break; case 'd': // Day & Day of week tokenLen = format.GetRepeatCount(); if (tokenLen <= 2) { // "d" & "dd" if (!ParseDigits(ref str, tokenLen, out tempDay)) { if (!parseInfo.fCustomNumberParser || !parseInfo.parseNumberDelegate(ref str, tokenLen, out tempDay)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } if (!CheckNewValue(ref result.Day, tempDay, ch, ref result)) { return (false); } } else { if (tokenLen == 3) { // "ddd" if (!MatchAbbreviatedDayName(ref str, dtfi, ref tempDayOfWeek)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } else { // "dddd*" if (!MatchDayName(ref str, dtfi, ref tempDayOfWeek)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } if (!CheckNewValue(ref parseInfo.dayOfWeek, tempDayOfWeek, ch, ref result)) { return (false); } } break; case 'g': tokenLen = format.GetRepeatCount(); // Put the era value in result.era. if (!MatchEraName(ref str, dtfi, ref result.era)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } break; case 'h': parseInfo.fUseHour12 = true; tokenLen = format.GetRepeatCount(); if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempHour)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } if (!CheckNewValue(ref result.Hour, tempHour, ch, ref result)) { return (false); } break; case 'H': tokenLen = format.GetRepeatCount(); if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempHour)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } if (!CheckNewValue(ref result.Hour, tempHour, ch, ref result)) { return (false); } break; case 'm': tokenLen = format.GetRepeatCount(); if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempMinute)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } if (!CheckNewValue(ref result.Minute, tempMinute, ch, ref result)) { return (false); } break; case 's': tokenLen = format.GetRepeatCount(); if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempSecond)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } if (!CheckNewValue(ref result.Second, tempSecond, ch, ref result)) { return (false); } break; case 'f': case 'F': tokenLen = format.GetRepeatCount(); if (tokenLen <= DateTimeFormat.MaxSecondsFractionDigits) { if (!ParseFractionExact(ref str, tokenLen, ref tempFraction)) { if (ch == 'f') { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } if (result.fraction < 0) { result.fraction = tempFraction; } else { if (tempFraction != result.fraction) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", ch); return (false); } } } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } break; case 't': // AM/PM designator tokenLen = format.GetRepeatCount(); if (tokenLen == 1) { if (!MatchAbbreviatedTimeMark(ref str, dtfi, ref tempTimeMark)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } else { if (!MatchTimeMark(ref str, dtfi, ref tempTimeMark)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } } if (parseInfo.timeMark == TM.NotSet) { parseInfo.timeMark = tempTimeMark; } else { if (parseInfo.timeMark != tempTimeMark) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", ch); return (false); } } break; case 'z': // timezone offset tokenLen = format.GetRepeatCount(); { TimeSpan tempTimeZoneOffset = new TimeSpan(0); if (!ParseTimeZoneOffset(ref str, tokenLen, ref tempTimeZoneOffset)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && tempTimeZoneOffset != result.timeZoneOffset) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'z'); return (false); } result.timeZoneOffset = tempTimeZoneOffset; result.flags |= ParseFlags.TimeZoneUsed; } break; case 'Z': if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && result.timeZoneOffset != TimeSpan.Zero) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'Z'); return (false); } result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0); result.flags |= ParseFlags.TimeZoneUtc; // The updating of the indexes is to reflect that ParseExact MatchXXX methods assume that // they need to increment the index and Parse GetXXX do not. Since we are calling a Parse // method from inside ParseExact we need to adjust this. Long term, we should try to // eliminate this discrepancy. str.Index++; if (!GetTimeZoneName(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.Index--; break; case 'K': // This should parse either as a blank, the 'Z' character or a local offset like "-07:00" if (str.Match('Z')) { if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && result.timeZoneOffset != TimeSpan.Zero) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K'); return (false); } result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0); result.flags |= ParseFlags.TimeZoneUtc; } else if (str.Match('+') || str.Match('-')) { str.Index--; // Put the character back for the parser TimeSpan tempTimeZoneOffset = new TimeSpan(0); if (!ParseTimeZoneOffset(ref str, 3, ref tempTimeZoneOffset)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return (false); } if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && tempTimeZoneOffset != result.timeZoneOffset) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K'); return (false); } result.timeZoneOffset = tempTimeZoneOffset; result.flags |= ParseFlags.TimeZoneUsed; } // Otherwise it is unspecified and we consume no characters break; case ':': // We match the separator in time pattern with the character in the time string if both equal to ':' or the date separator is matching the characters in the date string // We have to exclude the case when the time separator is more than one character and starts with ':' something like "::" for instance. if (((dtfi.TimeSeparator.Length > 1 && dtfi.TimeSeparator[0] == ':') || !str.Match(':')) && !str.Match(dtfi.TimeSeparator)) { // A time separator is expected. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } break; case '/': // We match the separator in date pattern with the character in the date string if both equal to '/' or the date separator is matching the characters in the date string // We have to exclude the case when the date separator is more than one character and starts with '/' something like "//" for instance. if (((dtfi.DateSeparator.Length > 1 && dtfi.DateSeparator[0] == '/') || !str.Match('/')) && !str.Match(dtfi.DateSeparator)) { // A date separator is expected. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } break; case '\"': case '\'': StringBuilder enquotedString = new StringBuilder(); // Use ParseQuoteString so that we can handle escape characters within the quoted string. if (!TryParseQuoteString(format.Value, format.Index, enquotedString, out tokenLen)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadQuote", ch); return (false); } format.Index += tokenLen - 1; // Some cultures uses space in the quoted string. E.g. Spanish has long date format as: // "dddd, dd' de 'MMMM' de 'yyyy". When inner spaces flag is set, we should skip whitespaces if there is space // in the quoted string. String quotedStr = enquotedString.ToString(); for (int i = 0; i < quotedStr.Length; i++) { if (quotedStr[i] == ' ' && parseInfo.fAllowInnerWhite) { str.SkipWhiteSpaces(); } else if (!str.Match(quotedStr[i])) { // Can not find the matching quoted string. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } // The "r" and "u" formats incorrectly quoted 'GMT' and 'Z', respectively. We cannot // correct this mistake for DateTime.ParseExact for compatibility reasons, but we can // fix it for DateTimeOffset.ParseExact as DateTimeOffset has not been publically released // with this issue. if ((result.flags & ParseFlags.CaptureOffset) != 0) { if ((result.flags & ParseFlags.Rfc1123Pattern) != 0 && quotedStr == GMTName) { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; } else if ((result.flags & ParseFlags.UtcSortPattern) != 0 && quotedStr == ZuluName) { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; } } break; case '%': // Skip this so we can get to the next pattern character. // Used in case like "%d", "%y" // Make sure the next character is not a '%' again. if (format.Index >= format.Value.Length - 1 || format.Value[format.Index + 1] == '%') { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } break; case '\\': // Escape character. For example, "\d". // Get the next character in format, and see if we can // find a match in str. if (format.GetNext()) { if (!str.Match(format.GetChar())) { // Can not find a match for the escaped character. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } break; case '.': if (!str.Match(ch)) { if (format.GetNext()) { // If we encounter the pattern ".F", and the dot is not present, it is an optional // second fraction and we can skip this format. if (format.Match('F')) { format.GetRepeatCount(); break; } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } break; default: if (ch == ' ') { if (parseInfo.fAllowInnerWhite) { // Skip whitespaces if AllowInnerWhite. // Do nothing here. } else { if (!str.Match(ch)) { // If the space does not match, and trailing space is allowed, we do // one more step to see if the next format character can lead to // successful parsing. // This is used to deal with special case that a empty string can match // a specific pattern. // The example here is af-ZA, which has a time format like "hh:mm:ss tt". However, // its AM symbol is "" (empty string). If fAllowTrailingWhite is used, and time is in // the AM, we will trim the whitespaces at the end, which will lead to a failure // when we are trying to match the space before "tt". if (parseInfo.fAllowTrailingWhite) { if (format.GetNext()) { if (ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) { return (true); } } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } // Found a macth. } } else { if (format.MatchSpecifiedWord(GMTName)) { format.Index += (GMTName.Length - 1); // Found GMT string in format. This means the DateTime string // is in GMT timezone. result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; if (!str.Match(GMTName)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else if (!str.Match(ch)) { // ch is expected. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } break; } // switch return (true); }
private static bool ParseISO8601(ref DateTimeRawInfo raw, ref __DTString str, DateTimeStyles styles, ref DateTimeResult result) { if (raw.year >= 0 && raw.GetNumber(0) >= 0) { raw.GetNumber(1); } str.Index--; int second = 0; double num = 0.0; str.SkipWhiteSpaces(); int hour; if (!DateTimeParse.ParseDigits(ref str, 2, out hour)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (!str.Match(':')) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); int minute; if (!DateTimeParse.ParseDigits(ref str, 2, out minute)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (str.Match(':')) { str.SkipWhiteSpaces(); if (!DateTimeParse.ParseDigits(ref str, 2, out second)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (str.Match('.')) { if (!DateTimeParse.ParseFraction(ref str, out num)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.Index--; } str.SkipWhiteSpaces(); } if (str.GetNext()) { char @char = str.GetChar(); if (@char == '+' || @char == '-') { result.flags |= ParseFlags.TimeZoneUsed; if (!DateTimeParse.ParseTimeZone(ref str, ref result.timeZoneOffset)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else { if (@char == 'Z' || @char == 'z') { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; result.flags |= ParseFlags.TimeZoneUtc; } else { str.Index--; } } str.SkipWhiteSpaces(); if (str.Match('#')) { if (!DateTimeParse.VerifyValidPunctuation(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); } if (str.Match('\0') && !DateTimeParse.VerifyValidPunctuation(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (str.GetNext()) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } Calendar defaultInstance = GregorianCalendar.GetDefaultInstance(); DateTime parsedDate; if (!defaultInstance.TryToDateTime(raw.year, raw.GetNumber(0), raw.GetNumber(1), hour, minute, second, 0, result.era, out parsedDate)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } parsedDate = parsedDate.AddTicks((long)Math.Round(num * 10000000.0)); result.parsedDate = parsedDate; return DateTimeParse.DetermineTimeZoneAdjustments(ref result, styles, false); }
// // Parse the ISO8601 format string found during Parse(); // // private static bool ParseISO8601(ref DateTimeRawInfo raw, ref __DTString str, DateTimeStyles styles, ref DateTimeResult result) { if (raw.year < 0 || raw.GetNumber(0) < 0 || raw.GetNumber(1) < 0) { } str.Index--; int hour, minute; int second = 0; double partSecond = 0; str.SkipWhiteSpaces(); if (!ParseDigits(ref str, 2, out hour)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (!str.Match(':')) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (!ParseDigits(ref str, 2, out minute)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (str.Match(':')) { str.SkipWhiteSpaces(); if (!ParseDigits(ref str, 2, out second)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (str.Match('.')) { if (!ParseFraction(ref str, out partSecond)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.Index--; } str.SkipWhiteSpaces(); } if (str.GetNext()) { char ch = str.GetChar(); if (ch == '+' || ch == '-') { result.flags |= ParseFlags.TimeZoneUsed; if (!ParseTimeZone(ref str, ref result.timeZoneOffset)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else if (ch == 'Z' || ch == 'z') { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; result.flags |= ParseFlags.TimeZoneUtc; } else { str.Index--; } str.SkipWhiteSpaces(); if (str.Match('#')) { if (!VerifyValidPunctuation(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); } if (str.Match('\0')) { if (!VerifyValidPunctuation(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } if (str.GetNext()) { // If this is true, there were non-white space characters remaining in the DateTime result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } DateTime time; Calendar calendar = GregorianCalendar.GetDefaultInstance(); if (!calendar.TryToDateTime(raw.year, raw.GetNumber(0), raw.GetNumber(1), hour, minute, second, 0, result.era, out time)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } time = time.AddTicks((long)Math.Round(partSecond * Calendar.TicksPerSecond)); result.parsedDate = time; if (!DetermineTimeZoneAdjustments(ref result, styles, false)) { return false; } return true; }
/*=================================ParseTimeZoneOffset================================== **Action: Parse the string formatted using "z", "zz", "zzz" in DateTime.Format(). **Returns: the TimeSpan for the parsed timezone offset. **Arguments: str: a __DTString. The parsing will start from the ** next character after str.Index. ** len: the repeated number of the "z" **Exceptions: FormatException if errors in parsing. ==============================================================================*/ private static bool ParseTimeZoneOffset(ref __DTString str, int len, ref TimeSpan result) { bool isPositive = true; int hourOffset; int minuteOffset = 0; switch (len) { case 1: case 2: if (!ParseSign(ref str, ref isPositive)) { return (false); } if (!ParseDigits(ref str, len, out hourOffset)) { return (false); } break; default: if (!ParseSign(ref str, ref isPositive)) { return (false); } // Parsing 1 digit will actually parse 1 or 2. if (!ParseDigits(ref str, 1, out hourOffset)) { return (false); } // ':' is optional. if (str.Match(":")) { // Found ':' if (!ParseDigits(ref str, 2, out minuteOffset)) { return (false); } } else { // Since we can not match ':', put the char back. str.Index--; if (!ParseDigits(ref str, 2, out minuteOffset)) { return (false); } } break; } if (minuteOffset < 0 || minuteOffset >= 60) { return false; } result = (new TimeSpan(hourOffset, minuteOffset, 0)); if (!isPositive) { result = result.Negate(); } return (true); }
private static bool ParseTimeZoneOffset(ref __DTString str, int len, ref TimeSpan result) { int num; bool flag = true; int num2 = 0; switch (len) { case 1: case 2: if (ParseSign(ref str, ref flag)) { if (ParseDigits(ref str, len, out num)) { break; } return false; } return false; default: if (!ParseSign(ref str, ref flag)) { return false; } if (!ParseDigits(ref str, 1, out num)) { return false; } if (str.Match(":")) { if (!ParseDigits(ref str, 2, out num2)) { return false; } } else { str.Index--; if (!ParseDigits(ref str, 2, out num2)) { return false; } } break; } if ((num2 < 0) || (num2 >= 60)) { return false; } result = new TimeSpan(num, num2, 0); if (!flag) { result = result.Negate(); } return true; }
private static bool ParseISO8601(ref DateTimeRawInfo raw, ref __DTString str, DateTimeStyles styles, ref DateTimeResult result) { int num; int num2; DateTime time; if ((raw.year >= 0) && (raw.GetNumber(0) >= 0)) { raw.GetNumber(1); } str.Index--; int num3 = 0; double num4 = 0.0; str.SkipWhiteSpaces(); if (!ParseDigits(ref str, 2, out num)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (!str.Match(':')) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (!ParseDigits(ref str, 2, out num2)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); if (str.Match(':')) { str.SkipWhiteSpaces(); if (!ParseDigits(ref str, 2, out num3)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (str.Match('.')) { if (!ParseFraction(ref str, out num4)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.Index--; } str.SkipWhiteSpaces(); } if (str.GetNext()) { switch (str.GetChar()) { case '+': case '-': result.flags |= ParseFlags.TimeZoneUsed; if (!ParseTimeZone(ref str, ref result.timeZoneOffset)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } break; case 'Z': case 'z': result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; result.flags |= ParseFlags.TimeZoneUtc; break; default: str.Index--; break; } str.SkipWhiteSpaces(); if (str.Match('#')) { if (!VerifyValidPunctuation(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.SkipWhiteSpaces(); } if (str.Match('\0') && !VerifyValidPunctuation(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (str.GetNext()) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } if (!GregorianCalendar.GetDefaultInstance().TryToDateTime(raw.year, raw.GetNumber(0), raw.GetNumber(1), num, num2, num3, 0, result.era, out time)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } time = time.AddTicks((long) Math.Round((double) (num4 * 10000000.0))); result.parsedDate = time; if (!DetermineTimeZoneAdjustments(ref result, styles, false)) { return false; } return true; }
private static bool ParseByFormat(ref __DTString str, ref __DTString format, ref ParsingInfo parseInfo, DateTimeFormatInfo dtfi, ref DateTimeResult result) { bool flag; int returnValue = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; double num9 = 0.0; TM aM = TM.AM; char failureMessageFormatArgument = format.GetChar(); switch (failureMessageFormatArgument) { case '%': if ((format.Index < (format.Value.Length - 1)) && (format.Value[format.Index + 1] != '%')) { goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; case '\'': case '"': { StringBuilder builder = new StringBuilder(); if (!TryParseQuoteString(format.Value, format.Index, builder, out returnValue)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadQuote", failureMessageFormatArgument); return false; } format.Index += returnValue - 1; string str2 = builder.ToString(); for (int i = 0; i < str2.Length; i++) { if ((str2[i] == ' ') && parseInfo.fAllowInnerWhite) { str.SkipWhiteSpaces(); } else if (!str.Match(str2[i])) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } if ((result.flags & ParseFlags.CaptureOffset) != 0) { if (((result.flags & ParseFlags.Rfc1123Pattern) != 0) && (str2 == "GMT")) { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; } else if (((result.flags & ParseFlags.UtcSortPattern) != 0) && (str2 == "Z")) { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; } } goto Label_0A5A; } case '.': if (!str.Match(failureMessageFormatArgument)) { if (!format.GetNext() || !format.Match('F')) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } format.GetRepeatCount(); } goto Label_0A5A; case '/': if (str.Match(dtfi.DateSeparator)) { goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case ':': if (str.Match(dtfi.TimeSeparator)) { goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'F': case 'f': returnValue = format.GetRepeatCount(); if (returnValue <= 7) { if (!ParseFractionExact(ref str, returnValue, ref num9) && (failureMessageFormatArgument == 'f')) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (result.fraction >= 0.0) { if (num9 != result.fraction) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", failureMessageFormatArgument); return false; } } else { result.fraction = num9; } goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'H': returnValue = format.GetRepeatCount(); if (ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num6)) { if (!CheckNewValue(ref result.Hour, num6, failureMessageFormatArgument, ref result)) { return false; } goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'K': if (!str.Match('Z')) { if (str.Match('+') || str.Match('-')) { str.Index--; TimeSpan span2 = new TimeSpan(0L); if (!ParseTimeZoneOffset(ref str, 3, ref span2)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (((result.flags & ParseFlags.TimeZoneUsed) != 0) && (span2 != result.timeZoneOffset)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K'); return false; } result.timeZoneOffset = span2; result.flags |= ParseFlags.TimeZoneUsed; } goto Label_0A5A; } if (((result.flags & ParseFlags.TimeZoneUsed) == 0) || !(result.timeZoneOffset != TimeSpan.Zero)) { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0L); result.flags |= ParseFlags.TimeZoneUtc; goto Label_0A5A; } result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K'); return false; case 'M': returnValue = format.GetRepeatCount(); if (returnValue > 2) { if (returnValue == 3) { if (!MatchAbbreviatedMonthName(ref str, dtfi, ref num3)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else if (!MatchMonthName(ref str, dtfi, ref num3)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.flags |= ParseFlags.ParsedMonthName; goto Label_0223; } if (ParseDigits(ref str, returnValue, out num3) || (parseInfo.fCustomNumberParser && parseInfo.parseNumberDelegate(ref str, returnValue, out num3))) { goto Label_0223; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'Z': if (((result.flags & ParseFlags.TimeZoneUsed) == 0) || !(result.timeZoneOffset != TimeSpan.Zero)) { result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0L); result.flags |= ParseFlags.TimeZoneUtc; str.Index++; if (!GetTimeZoneName(ref str)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } str.Index--; goto Label_0A5A; } result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'Z'); return false; case '\\': if (!format.GetNext()) { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } if (str.Match(format.GetChar())) { goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'd': returnValue = format.GetRepeatCount(); if (returnValue > 2) { if (returnValue == 3) { if (!MatchAbbreviatedDayName(ref str, dtfi, ref num5)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else if (!MatchDayName(ref str, dtfi, ref num5)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (!CheckNewValue(ref parseInfo.dayOfWeek, num5, failureMessageFormatArgument, ref result)) { return false; } goto Label_0A5A; } if (ParseDigits(ref str, returnValue, out num4) || (parseInfo.fCustomNumberParser && parseInfo.parseNumberDelegate(ref str, returnValue, out num4))) { if (!CheckNewValue(ref result.Day, num4, failureMessageFormatArgument, ref result)) { return false; } goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'g': returnValue = format.GetRepeatCount(); if (MatchEraName(ref str, dtfi, ref result.era)) { goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'h': parseInfo.fUseHour12 = true; returnValue = format.GetRepeatCount(); if (ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num6)) { if (!CheckNewValue(ref result.Hour, num6, failureMessageFormatArgument, ref result)) { return false; } goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 's': returnValue = format.GetRepeatCount(); if (ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num8)) { if (!CheckNewValue(ref result.Second, num8, failureMessageFormatArgument, ref result)) { return false; } goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 't': if (format.GetRepeatCount() != 1) { if (!MatchTimeMark(ref str, dtfi, ref aM)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } goto Label_04DE; } if (MatchAbbreviatedTimeMark(ref str, dtfi, ref aM)) { goto Label_04DE; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; case 'm': returnValue = format.GetRepeatCount(); if (!ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num7)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (CheckNewValue(ref result.Minute, num7, failureMessageFormatArgument, ref result)) { goto Label_0A5A; } return false; case 'y': returnValue = format.GetRepeatCount(); if (!dtfi.HasForceTwoDigitYears) { if (returnValue <= 2) { parseInfo.fUseTwoDigitYear = true; } flag = ParseDigits(ref str, returnValue, out num2); break; } flag = ParseDigits(ref str, 1, 4, out num2); break; case 'z': { returnValue = format.GetRepeatCount(); TimeSpan span = new TimeSpan(0L); if (ParseTimeZoneOffset(ref str, returnValue, ref span)) { if (((result.flags & ParseFlags.TimeZoneUsed) != 0) && (span != result.timeZoneOffset)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'z'); return false; } result.timeZoneOffset = span; result.flags |= ParseFlags.TimeZoneUsed; goto Label_0A5A; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } default: if (failureMessageFormatArgument == ' ') { if (!parseInfo.fAllowInnerWhite && !str.Match(failureMessageFormatArgument)) { if ((parseInfo.fAllowTrailingWhite && format.GetNext()) && ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) { return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else if (format.MatchSpecifiedWord("GMT")) { format.Index += "GMT".Length - 1; result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = TimeSpan.Zero; if (!str.Match("GMT")) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } else if (!str.Match(failureMessageFormatArgument)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } goto Label_0A5A; } if (!flag && parseInfo.fCustomNumberParser) { flag = parseInfo.parseNumberDelegate(ref str, returnValue, out num2); } if (!flag) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (CheckNewValue(ref result.Year, num2, failureMessageFormatArgument, ref result)) { goto Label_0A5A; } return false; Label_0223: if (CheckNewValue(ref result.Month, num3, failureMessageFormatArgument, ref result)) { goto Label_0A5A; } return false; Label_04DE: if (parseInfo.timeMark == TM.NotSet) { parseInfo.timeMark = aM; } else if (parseInfo.timeMark != aM) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", failureMessageFormatArgument); return false; } Label_0A5A: return true; }
// Given a specified format character, parse and update the parsing result. // private static bool ParseByFormat( __DTString str, __DTString format, ParsingInfo parseInfo, DateTimeFormatInfo dtfi, bool isThrowExp, DateTimeResult result) { int tokenLen = 0; int tempYear = 0, tempMonth = 0, tempDay = 0, tempDayOfWeek = 0, tempHour = 0, tempMinute = 0, tempSecond = 0; double tempFraction = 0; int tempTimeMark = 0; char ch = format.GetChar(); switch (ch) { case 'y': tokenLen = format.GetRepeatCount(); if (tokenLen <= 2) { parseInfo.fUseTwoDigitYear = true; } if (!ParseDigits(str, tokenLen, isThrowExp, out tempYear)) { return (false); } if (!CheckNewValue(ref result.Year, tempYear, ch, isThrowExp)) { return (false); } break; case 'M': tokenLen = format.GetRepeatCount(); if (tokenLen <= 2) { if (!ParseDigits(str, tokenLen, isThrowExp, out tempMonth)) { return (false); } } else { if (tokenLen == 3) { if (!MatchAbbreviatedMonthName(str, dtfi, isThrowExp, ref tempMonth)) { return (false); } } else { if (!MatchMonthName(str, dtfi, isThrowExp, ref tempMonth)) { return (false); } } } if (!CheckNewValue(ref result.Month, tempMonth, ch, isThrowExp)) { return (false); } break; case 'd': // Day & Day of week tokenLen = format.GetRepeatCount(); if (tokenLen <= 2) { // "d" & "dd" if (!ParseDigits(str, tokenLen, isThrowExp, out tempDay)) { return (false); } if (!CheckNewValue(ref result.Day, tempDay, ch, isThrowExp)) { return (false); } } else { if (tokenLen == 3) { // "ddd" if (!MatchAbbreviatedDayName(str, dtfi, isThrowExp, ref tempDayOfWeek)) { return (false); } } else { // "dddd*" if (!MatchDayName(str, dtfi, isThrowExp, ref tempDayOfWeek)) { return (false); } } if (!CheckNewValue(ref parseInfo.dayOfWeek, tempDayOfWeek, ch, isThrowExp)) { return (false); } } break; case 'g': tokenLen = format.GetRepeatCount(); // Put the era value in result.era. if (!MatchEraName(str, dtfi, isThrowExp, ref result.era)) { return (false); } break; case 'h': parseInfo.fUseHour12 = true; tokenLen = format.GetRepeatCount(); if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempHour)) { return (false); } if (!CheckNewValue(ref result.Hour, tempHour, ch, isThrowExp)) { return (false); } break; case 'H': tokenLen = format.GetRepeatCount(); if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempHour)) { return (false); } if (!CheckNewValue(ref result.Hour, tempHour, ch, isThrowExp)) { return (false); } break; case 'm': tokenLen = format.GetRepeatCount(); if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempMinute)) { return (false); } if (!CheckNewValue(ref result.Minute, tempMinute, ch, isThrowExp)) { return (false); } break; case 's': tokenLen = format.GetRepeatCount(); if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempSecond)) { return (false); } if (!CheckNewValue(ref result.Second, tempSecond, ch, isThrowExp)) { return (false); } break; case 'f': tokenLen = format.GetRepeatCount(); if (tokenLen <= DateTimeFormat.MaxSecondsFractionDigits) { if (!ParseFractionExact(str, tokenLen, isThrowExp, ref tempFraction)) { return (false); } if (result.fraction < 0) { result.fraction = tempFraction; } else { if (tempFraction != result.fraction) { if (isThrowExp) { throw new ArgumentException( String.Format(Environment.GetResourceString("Format_RepeatDateTimePattern"), ch), "str"); } else { return (false); } } } } else { return ParseFormatError(isThrowExp, "Format_BadDateTime"); } break; case 't': // AM/PM designator tokenLen = format.GetRepeatCount(); if (tokenLen == 1) { if (!MatchAbbreviatedTimeMark(str, dtfi, isThrowExp, ref tempTimeMark)) { return (false); } } else { if (!MatchTimeMark(str, dtfi, isThrowExp, ref tempTimeMark)) { return (false); } } if (!CheckNewValue(ref parseInfo.timeMark, tempTimeMark, ch, isThrowExp)) { return (false); } break; case 'z': // timezone offset if (parseInfo.fUseTimeZone) { throw new ArgumentException(Environment.GetResourceString("Argument_TwoTimeZoneSpecifiers"), "str"); } parseInfo.fUseTimeZone = true; tokenLen = format.GetRepeatCount(); if (!ParseTimeZoneOffset(str, tokenLen, isThrowExp, ref parseInfo.timeZoneOffset)) { return (false); } break; case 'Z': if (parseInfo.fUseTimeZone) { throw new ArgumentException(Environment.GetResourceString("Argument_TwoTimeZoneSpecifiers"), "str"); } parseInfo.fUseTimeZone = true; parseInfo.timeZoneOffset = new TimeSpan(0); str.Index++; if (!GetTimeZoneName(str)) { BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): 'Z' or 'GMT' are expected"); return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } break; case ':': if (!str.Match(dtfi.TimeSeparator)) { // A time separator is expected. BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): ':' is expected"); return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } break; case '/': if (!str.Match(dtfi.DateSeparator)) { // A date separator is expected. BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): date separator is expected"); return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } break; case '\"': case '\'': StringBuilder enquotedString = new StringBuilder(); try { // Use ParseQuoteString so that we can handle escape characters within the quoted string. tokenLen = DateTimeFormat.ParseQuoteString(format.Value, format.Index, enquotedString); } catch (Exception) { if (isThrowExp) { throw new FormatException(String.Format(Environment.GetResourceString("Format_BadQuote"), ch)); } else { return (false); } } format.Index += tokenLen - 1; // Some cultures uses space in the quoted string. E.g. Spanish has long date format as: // "dddd, dd' de 'MMMM' de 'yyyy". When inner spaces flag is set, we should skip whitespaces if there is space // in the quoted string. String quotedStr = enquotedString.ToString(); for (int i = 0; i < quotedStr.Length; i++) { if (quotedStr[i] == ' ' && parseInfo.fAllowInnerWhite) { str.SkipWhiteSpaces(); } else if (!str.Match(quotedStr[i])) { // Can not find the matching quoted string. BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse():Quote string doesn't match"); return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } } break; case '%': // Skip this so we can get to the next pattern character. // Used in case like "%d", "%y" // Make sure the next character is not a '%' again. if (format.Index >= format.Value.Length - 1 || format.Value[format.Index + 1] == '%') { BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse():%% is not permitted"); return (ParseFormatError(isThrowExp, "Format_BadFormatSpecifier")); } break; case '\\': // Escape character. For example, "\d". // Get the next character in format, and see if we can // find a match in str. if (format.GetNext()) { if (!str.Match(format.GetChar())) { // Can not find a match for the escaped character. BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): Can not find a match for the escaped character"); return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } } else { BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): \\ is at the end of the format string"); return (ParseFormatError(isThrowExp, "Format_BadFormatSpecifier")); } break; default: if (ch == ' ') { if (parseInfo.fAllowInnerWhite) { // Skip whitespaces if AllowInnerWhite. // Do nothing here. } else { if (!str.Match(ch)) { // If the space does not match, and trailing space is allowed, we do // one more step to see if the next format character can lead to // successful parsing. // This is used to deal with special case that a empty string can match // a specific pattern. // The example here is af-ZA, which has a time format like "hh:mm:ss tt". However, // its AM symbol is "" (empty string). If fAllowTrailingWhite is used, and time is in // the AM, we will trim the whitespaces at the end, which will lead to a failure // when we are trying to match the space before "tt". if (parseInfo.fAllowTrailingWhite) { if (format.GetNext()) { if (ParseByFormat(str, format, parseInfo, dtfi, isThrowExp, result)) { return (true); } } } return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } // Found a macth. } } else { if (format.MatchSpecifiedWord(GMTName)) { format.Index += (GMTName.Length - 1); // Found GMT string in format. This means the DateTime string // is in GMT timezone. parseInfo.fUseTimeZone = true; if (!str.Match(GMTName)) { BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): GMT in format, but not in str"); return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } } else if (!str.Match(ch)) { // ch is expected. BCLDebug.Trace ("NLS", "DateTimeParse.DoStrictParse(): '", ch, "' is expected"); return (ParseFormatError(isThrowExp, "Format_BadDateTime")); } } break; } // switch return (true); }
// // Parse the ISO8601 format string found during Parse(); // // private static DateTime ParseISO8601(DateTimeRawInfo raw, __DTString str, DateTimeStyles styles) { if (raw.year < 0 || raw.num[0] < 0 || raw.num[1] < 0) { } str.Index--; int hour, minute, second; bool timeZoneUsed = false; TimeSpan timeZoneOffset = new TimeSpan(); DateTime time = new DateTime(0); double partSecond = 0; str.SkipWhiteSpaces(); ParseDigits(str, 2, true, out hour); str.SkipWhiteSpaces(); if (str.Match(':')) { str.SkipWhiteSpaces(); ParseDigits(str, 2, true, out minute); str.SkipWhiteSpaces(); if (str.Match(':')) { str.SkipWhiteSpaces(); ParseDigits(str, 2, true, out second); str.SkipWhiteSpaces(); if (str.GetNext()) { char ch = str.GetChar(); if (ch == '+' || ch == '-') { timeZoneUsed = true; timeZoneOffset = ParseTimeZone(str, str.GetChar()); } else if (ch == '.') { str.Index++; //ParseFraction requires us to advance to the next character. partSecond = ParseFraction(str); } else if (ch == 'Z' || ch == 'z') { timeZoneUsed = true; } else { throw new FormatException(Environment.GetResourceString("Format_BadDateTime")); } } time =new DateTime(raw.year, raw.num[0], raw.num[1], hour, minute, second); time = time.AddTicks((long)Math.Round(partSecond * Calendar.TicksPerSecond)); if (timeZoneUsed) { time = AdjustTimeZone(time, timeZoneOffset, styles, false); } return time; } } throw new FormatException(Environment.GetResourceString("Format_BadDateTime")); }