// 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 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; }
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; }