private SetFailure ( ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument ) : void | ||
failure | ParseFailureKind | |
failureMessageID | string | |
failureMessageFormatArgument | object | |
return | void |
internal static bool TryParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, ref DateTimeResult result) { if (s == null) { result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "s"); return false; } if (format == null) { result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "format"); return false; } if (s.Length == 0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (format.Length == 0) { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } BCLDebug.Assert(dtfi != null, "dtfi == null"); return DoStrictParse(s, format, style, dtfi, ref result); }
// // 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; }
private static bool HandleTimeZone(ref __DTString str, ref DateTimeResult result) { if (str.Index < str.len - 1) { char c = str.Value[str.Index]; int num = 0; while (char.IsWhiteSpace(c) && str.Index + num < str.len - 1) { num++; c = str.Value[str.Index + num]; } if (c == '+' || c == '-') { str.Index += num; if ((result.flags & ParseFlags.TimeZoneUsed) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.flags |= ParseFlags.TimeZoneUsed; if (!DateTimeParse.ParseTimeZone(ref str, ref result.timeZoneOffset)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } } return true; }
private static bool DoStrictParse(string s, string formatParam, DateTimeStyles styles, DateTimeFormatInfo dtfi, ref DateTimeResult result) { ParsingInfo parsingInfo = default(ParsingInfo); parsingInfo.Init(); parsingInfo.calendar = dtfi.Calendar; parsingInfo.fAllowInnerWhite = ((styles & DateTimeStyles.AllowInnerWhite) != DateTimeStyles.None); parsingInfo.fAllowTrailingWhite = ((styles & DateTimeStyles.AllowTrailingWhite) != DateTimeStyles.None); if (formatParam.Length == 1) { if ((result.flags & ParseFlags.CaptureOffset) != (ParseFlags)0 && formatParam[0] == 'U') { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } formatParam = DateTimeParse.ExpandPredefinedFormat(formatParam, ref dtfi, ref parsingInfo, ref result); } result.calendar = parsingInfo.calendar; if (parsingInfo.calendar.ID == 8) { parsingInfo.parseNumberDelegate = DateTimeParse.m_hebrewNumberParser; parsingInfo.fCustomNumberParser = true; } result.Hour = (result.Minute = (result.Second = -1)); __DTString _DTString = new __DTString(formatParam, dtfi, false); __DTString _DTString2 = new __DTString(s, dtfi, false); if (parsingInfo.fAllowTrailingWhite) { _DTString.TrimTail(); _DTString.RemoveTrailingInQuoteSpaces(); _DTString2.TrimTail(); } if ((styles & DateTimeStyles.AllowLeadingWhite) != DateTimeStyles.None) { _DTString.SkipWhiteSpaces(); _DTString.RemoveLeadingInQuoteSpaces(); _DTString2.SkipWhiteSpaces(); } while (_DTString.GetNext()) { if (parsingInfo.fAllowInnerWhite) { _DTString2.SkipWhiteSpaces(); } if (!DateTimeParse.ParseByFormat(ref _DTString2, ref _DTString, ref parsingInfo, dtfi, ref result)) { return false; } } if (_DTString2.Index < _DTString2.Value.Length - 1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (parsingInfo.fUseTwoDigitYear && (dtfi.FormatFlags & DateTimeFormatFlags.UseHebrewRule) == DateTimeFormatFlags.None) { if (result.Year >= 100) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.Year = parsingInfo.calendar.ToFourDigitYear(result.Year); } if (parsingInfo.fUseHour12) { if (parsingInfo.timeMark == DateTimeParse.TM.NotSet) { parsingInfo.timeMark = DateTimeParse.TM.AM; } if (result.Hour > 12) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (parsingInfo.timeMark == DateTimeParse.TM.AM) { if (result.Hour == 12) { result.Hour = 0; } } else { result.Hour = ((result.Hour == 12) ? 12 : (result.Hour + 12)); } } else { if ((parsingInfo.timeMark == DateTimeParse.TM.AM && result.Hour >= 12) || (parsingInfo.timeMark == DateTimeParse.TM.PM && result.Hour < 12)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } bool flag = result.Year == -1 && result.Month == -1 && result.Day == -1; if (!DateTimeParse.CheckDefaultDateTime(ref result, ref parsingInfo.calendar, styles)) { return false; } if (!flag && dtfi.HasYearMonthAdjustment && !dtfi.YearMonthAdjustment(ref result.Year, ref result.Month, (result.flags & ParseFlags.ParsedMonthName) != (ParseFlags)0)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (!parsingInfo.calendar.TryToDateTime(result.Year, result.Month, result.Day, result.Hour, result.Minute, result.Second, 0, result.era, out result.parsedDate)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (result.fraction > 0.0) { result.parsedDate = result.parsedDate.AddTicks((long)Math.Round(result.fraction * 10000000.0)); } if (parsingInfo.dayOfWeek != -1 && parsingInfo.dayOfWeek != (int)parsingInfo.calendar.GetDayOfWeek(result.parsedDate)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDayOfWeek", null); return false; } return DateTimeParse.DetermineTimeZoneAdjustments(ref result, styles, flag); }
private static bool CheckDefaultDateTime(ref DateTimeResult result, ref Calendar cal, DateTimeStyles styles) { if ((result.flags & ParseFlags.CaptureOffset) != (ParseFlags)0 && (result.Month != -1 || result.Day != -1) && (result.Year == -1 || (result.flags & ParseFlags.YearDefault) != (ParseFlags)0) && (result.flags & ParseFlags.TimeZoneUsed) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_MissingIncompleteDate", null); return false; } if (result.Year == -1 || result.Month == -1 || result.Day == -1) { DateTime dateTimeNow = DateTimeParse.GetDateTimeNow(ref result, ref styles); if (result.Month == -1 && result.Day == -1) { if (result.Year == -1) { if ((styles & DateTimeStyles.NoCurrentDateDefault) != DateTimeStyles.None) { cal = GregorianCalendar.GetDefaultInstance(); result.Year = (result.Month = (result.Day = 1)); } else { result.Year = cal.GetYear(dateTimeNow); result.Month = cal.GetMonth(dateTimeNow); result.Day = cal.GetDayOfMonth(dateTimeNow); } } else { result.Month = 1; result.Day = 1; } } else { if (result.Year == -1) { result.Year = cal.GetYear(dateTimeNow); } if (result.Month == -1) { result.Month = 1; } if (result.Day == -1) { result.Day = 1; } } } if (result.Hour == -1) { result.Hour = 0; } if (result.Minute == -1) { result.Minute = 0; } if (result.Second == -1) { result.Second = 0; } if (result.era == -1) { result.era = 0; } 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); }
private static bool AdjustTimeZoneToUniversal(ref DateTimeResult result) { long num = result.parsedDate.Ticks; num -= result.timeZoneOffset.Ticks; if (num < 0L) { num += 864000000000L; } if (num < 0L || num > 3155378975999999999L) { result.SetFailure(ParseFailureKind.Format, "Format_DateOutOfRange", null); return false; } result.parsedDate = new DateTime(num, DateTimeKind.Utc); return true; }
internal unsafe static bool TryParse(string s, DateTimeFormatInfo dtfi, DateTimeStyles styles, ref DateTimeResult result) { if (s == null) { result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "s"); return false; } if (s.Length == 0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } DateTimeParse.DS dS = DateTimeParse.DS.BEGIN; bool flag = false; DateTimeToken dateTimeToken = default(DateTimeToken); dateTimeToken.suffix = TokenType.SEP_Unk; DateTimeRawInfo dateTimeRawInfo = default(DateTimeRawInfo); int* numberBuffer = stackalloc int[(UIntPtr)3]; dateTimeRawInfo.Init(numberBuffer); result.calendar = dtfi.Calendar; result.era = 0; __DTString _DTString = new __DTString(s, dtfi); _DTString.GetNext(); while (DateTimeParse.Lex(dS, ref _DTString, ref dateTimeToken, ref dateTimeRawInfo, ref result, ref dtfi)) { if (dateTimeToken.dtt != DateTimeParse.DTT.Unk) { if (dateTimeToken.suffix != TokenType.SEP_Unk) { if (!DateTimeParse.ProcessDateTimeSuffix(ref result, ref dateTimeRawInfo, ref dateTimeToken)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } dateTimeToken.suffix = TokenType.SEP_Unk; } if (dateTimeToken.dtt == DateTimeParse.DTT.NumLocalTimeMark) { if (dS == DateTimeParse.DS.D_YNd || dS == DateTimeParse.DS.D_YN) { return DateTimeParse.ParseISO8601(ref dateTimeRawInfo, ref _DTString, styles, ref result); } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } else { dS = DateTimeParse.dateParsingStates[(int)dS][(int)dateTimeToken.dtt]; if (dS == DateTimeParse.DS.ERROR) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (dS > DateTimeParse.DS.ERROR) { if ((dtfi.FormatFlags & DateTimeFormatFlags.UseHebrewRule) != DateTimeFormatFlags.None) { if (!DateTimeParse.ProcessHebrewTerminalState(dS, ref result, ref styles, ref dateTimeRawInfo, dtfi)) { return false; } } else { if (!DateTimeParse.ProcessTerminaltState(dS, ref result, ref styles, ref dateTimeRawInfo, dtfi)) { return false; } } flag = true; dS = DateTimeParse.DS.BEGIN; } } } if (dateTimeToken.dtt == DateTimeParse.DTT.End || dateTimeToken.dtt == DateTimeParse.DTT.NumEnd || dateTimeToken.dtt == DateTimeParse.DTT.MonthEnd) { if (!flag) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } DateTimeParse.AdjustTimeMark(dtfi, ref dateTimeRawInfo); if (!DateTimeParse.AdjustHour(ref result.Hour, dateTimeRawInfo.timeMark)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } bool bTimeOnly = result.Year == -1 && result.Month == -1 && result.Day == -1; if (!DateTimeParse.CheckDefaultDateTime(ref result, ref result.calendar, styles)) { return false; } DateTime dateTime; if (!result.calendar.TryToDateTime(result.Year, result.Month, result.Day, result.Hour, result.Minute, result.Second, 0, result.era, out dateTime)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (dateTimeRawInfo.fraction > 0.0) { dateTime = dateTime.AddTicks((long)Math.Round(dateTimeRawInfo.fraction * 10000000.0)); } if (dateTimeRawInfo.dayOfWeek != -1 && dateTimeRawInfo.dayOfWeek != (int)result.calendar.GetDayOfWeek(dateTime)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDayOfWeek", null); return false; } result.parsedDate = dateTime; return DateTimeParse.DetermineTimeZoneAdjustments(ref result, styles, bTimeOnly); } } return false; }
private static bool GetDayOfNM(ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { if ((result.flags & ParseFlags.HaveDate) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } int num; if (!DateTimeParse.GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out num)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern); return false; } if (num == 6) { int num2; if (!DateTimeParse.GetYearMonthOrder(dtfi.YearMonthPattern, dtfi, out num2)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.YearMonthPattern); return false; } if (num2 == 4) { if (!DateTimeParse.SetDateYMD(ref result, DateTimeParse.AdjustYear(ref result, raw.GetNumber(0)), raw.month, 1)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } return true; } } DateTimeParse.GetDefaultYear(ref result, ref styles); if (!DateTimeParse.SetDateYMD(ref result, result.Year, raw.month, raw.GetNumber(0))) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } return true; }
private static bool GetHebrewDayOfNM(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { int num; if (!DateTimeParse.GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out num)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern); return false; } result.Month = raw.month; if ((num == 7 || num == 6) && result.calendar.IsValidDay(result.Year, result.Month, raw.GetNumber(0), result.era)) { result.Day = raw.GetNumber(0); return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; }
[System.Security.SecuritySafeCritical] // auto-generated private static Boolean Lex(DS dps, ref __DTString str, ref DateTimeToken dtok, ref DateTimeRawInfo raw, ref DateTimeResult result, ref DateTimeFormatInfo dtfi, DateTimeStyles styles) { TokenType tokenType; int tokenValue; int indexBeforeSeparator; char charBeforeSeparator; TokenType sep; dtok.dtt = DTT.Unk; // Assume the token is unkown. str.GetRegularToken(out tokenType, out tokenValue, dtfi); #if _LOGGING // Builds with _LOGGING defined (x86dbg, amd64chk, etc) support tracing // Set the following internal-only/unsupported environment variables to enable DateTime tracing to the console: // // COMPlus_LogEnable=1 // COMPlus_LogToConsole=1 // COMPlus_LogLevel=9 // COMPlus_ManagedLogFacility=0x00001000 if (_tracingEnabled) { BCLDebug.Trace("DATETIME", "[DATETIME] Lex({0})\tpos:{1}({2}), {3}, DS.{4}", Hex(str.Value), str.Index, Hex(str.m_current), tokenType, dps); } #endif // _LOGGING // Look at the regular token. switch (tokenType) { case TokenType.NumberToken: case TokenType.YearNumberToken: if (raw.numCount == 3 || tokenValue == -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0010", dps); return false; } // // This is a digit. // // If the previous parsing state is DS.T_NNt (like 12:01), and we got another number, // so we will have a terminal state DS.TX_NNN (like 12:01:02). // If the previous parsing state is DS.T_Nt (like 12:), and we got another number, // so we will have a terminal state DS.TX_NN (like 12:01). // // Look ahead to see if the following character is a decimal point or timezone offset. // This enables us to parse time in the forms of: // "11:22:33.1234" or "11:22:33-08". if (dps == DS.T_NNt) { if ((str.Index < str.len - 1)) { char nextCh = str.Value[str.Index]; if (nextCh == '.') { // While ParseFraction can fail, it just means that there were no digits after // the dot. In this case ParseFraction just removes the dot. This is actually // valid for cultures like Albanian, that join the time marker to the time with // with a dot: e.g. "9:03.MD" ParseFraction(ref str, out raw.fraction); } } } if (dps == DS.T_NNt || dps == DS.T_Nt) { if ((str.Index < str.len - 1)) { if (false == HandleTimeZone(ref str, ref result)) { LexTraceExit("0020 (value like \"12:01\" or \"12:\" followed by a non-TZ number", dps); return false; } } } dtok.num = tokenValue; if (tokenType == TokenType.YearNumberToken) { if (raw.year == -1) { raw.year = tokenValue; // // If we have number which has 3 or more digits (like "001" or "0001"), // we assume this number is a year. Save the currnet raw.numCount in // raw.year. // switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) { case TokenType.SEP_End: dtok.dtt = DTT.YearEnd; break; case TokenType.SEP_Am: case TokenType.SEP_Pm: if (raw.timeMark == TM.NotSet) { raw.timeMark = (sep == TokenType.SEP_Am ? TM.AM : TM.PM); dtok.dtt = DTT.YearSpace; } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0030 (TM.AM/TM.PM Happened more than 1x)", dps); } break; case TokenType.SEP_Space: dtok.dtt = DTT.YearSpace; break; case TokenType.SEP_Date: dtok.dtt = DTT.YearDateSep; break; case TokenType.SEP_Time: if (!raw.hasSameDateAndTimeSeparators) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0040 (Invalid separator after number)", dps); return false; } // we have the date and time separators are same and getting a year number, then change the token to YearDateSep as // we are sure we are not parsing time. dtok.dtt = DTT.YearDateSep; break; case TokenType.SEP_DateOrOffset: // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset. if ((dateParsingStates[(int)dps][(int) DTT.YearDateSep] == DS.ERROR) && (dateParsingStates[(int)dps][(int) DTT.YearSpace] > DS.ERROR)) { str.Index = indexBeforeSeparator; str.m_current = charBeforeSeparator; dtok.dtt = DTT.YearSpace; } else { dtok.dtt = DTT.YearDateSep; } break; case TokenType.SEP_YearSuff: case TokenType.SEP_MonthSuff: case TokenType.SEP_DaySuff: dtok.dtt = DTT.NumDatesuff; dtok.suffix = sep; break; case TokenType.SEP_HourSuff: case TokenType.SEP_MinuteSuff: case TokenType.SEP_SecondSuff: dtok.dtt = DTT.NumTimesuff; dtok.suffix = sep; break; default: // Invalid separator after number number. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0040 (Invalid separator after number)", dps); return false; } // // Found the token already. Return now. // LexTraceExit("0050 (success)", dps); return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0060", dps); return false; } switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) { // // Note here we check if the numCount is less than three. // When we have more than three numbers, it will be caught as error in the state machine. // case TokenType.SEP_End: dtok.dtt = DTT.NumEnd; raw.AddNumber(dtok.num); break; case TokenType.SEP_Am: case TokenType.SEP_Pm: if (raw.timeMark == TM.NotSet) { raw.timeMark = (sep == TokenType.SEP_Am ? TM.AM : TM.PM); dtok.dtt = DTT.NumAmpm; // Fix AM/PM parsing case, e.g. "1/10 5 AM" if (dps == DS.D_NN #if !FEATURE_CORECLR && enableAmPmParseAdjustment #endif ) { if (!ProcessTerminaltState(DS.DX_NN, ref result, ref styles, ref raw, dtfi)) { return false; } } raw.AddNumber(dtok.num); } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); break; } if (dps == DS.T_NNt || dps == DS.T_Nt) { if (false == HandleTimeZone(ref str, ref result)) { LexTraceExit("0070 (HandleTimeZone returned false)", dps); return false; } } break; case TokenType.SEP_Space: dtok.dtt = DTT.NumSpace; raw.AddNumber(dtok.num); break; case TokenType.SEP_Date: dtok.dtt = DTT.NumDatesep; raw.AddNumber(dtok.num); break; case TokenType.SEP_DateOrOffset: // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset. if ((dateParsingStates[(int)dps][(int) DTT.NumDatesep] == DS.ERROR) && (dateParsingStates[(int)dps][(int) DTT.NumSpace] > DS.ERROR)) { str.Index = indexBeforeSeparator; str.m_current = charBeforeSeparator; dtok.dtt = DTT.NumSpace; } else { dtok.dtt = DTT.NumDatesep; } raw.AddNumber(dtok.num); break; case TokenType.SEP_Time: if (raw.hasSameDateAndTimeSeparators && (dps == DS.D_Y || dps == DS.D_YN || dps == DS.D_YNd || dps == DS.D_YM || dps == DS.D_YMd)) { // we are parsing a date and we have the time separator same as date separator, so we mark the token as date separator dtok.dtt = DTT.NumDatesep; raw.AddNumber(dtok.num); break; } dtok.dtt = DTT.NumTimesep; raw.AddNumber(dtok.num); break; case TokenType.SEP_YearSuff: try { dtok.num = dtfi.Calendar.ToFourDigitYear(tokenValue); } catch (ArgumentOutOfRangeException e) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", e); LexTraceExit("0075 (Calendar.ToFourDigitYear failed)", dps); return false; } dtok.dtt = DTT.NumDatesuff; dtok.suffix = sep; break; case TokenType.SEP_MonthSuff: case TokenType.SEP_DaySuff: dtok.dtt = DTT.NumDatesuff; dtok.suffix = sep; break; case TokenType.SEP_HourSuff: case TokenType.SEP_MinuteSuff: case TokenType.SEP_SecondSuff: dtok.dtt = DTT.NumTimesuff; dtok.suffix = sep; break; case TokenType.SEP_LocalTimeMark: dtok.dtt = DTT.NumLocalTimeMark; raw.AddNumber(dtok.num); break; default: // Invalid separator after number number. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0080", dps); return false; } break; case TokenType.HebrewNumber: if (tokenValue >= 100) { // This is a year number if (raw.year == -1) { raw.year = tokenValue; // // If we have number which has 3 or more digits (like "001" or "0001"), // we assume this number is a year. Save the currnet raw.numCount in // raw.year. // switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) { case TokenType.SEP_End: dtok.dtt = DTT.YearEnd; break; case TokenType.SEP_Space: dtok.dtt = DTT.YearSpace; break; case TokenType.SEP_DateOrOffset: // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset. if (dateParsingStates[(int)dps][(int) DTT.YearSpace] > DS.ERROR) { str.Index = indexBeforeSeparator; str.m_current = charBeforeSeparator; dtok.dtt = DTT.YearSpace; break; } goto default; default: // Invalid separator after number number. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0090", dps); return false; } } else { // Invalid separator after number number. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0100", dps); return false; } } else { // This is a day number dtok.num = tokenValue; raw.AddNumber(dtok.num); switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) { // // Note here we check if the numCount is less than three. // When we have more than three numbers, it will be caught as error in the state machine. // case TokenType.SEP_End: dtok.dtt = DTT.NumEnd; break; case TokenType.SEP_Space: case TokenType.SEP_Date: dtok.dtt = DTT.NumDatesep; break; case TokenType.SEP_DateOrOffset: // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset. if ((dateParsingStates[(int)dps][(int) DTT.NumDatesep] == DS.ERROR) && (dateParsingStates[(int)dps][(int) DTT.NumSpace] > DS.ERROR)) { str.Index = indexBeforeSeparator; str.m_current = charBeforeSeparator; dtok.dtt = DTT.NumSpace; } else { dtok.dtt = DTT.NumDatesep; } break; default: // Invalid separator after number number. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0110", dps); return false; } } break; case TokenType.DayOfWeekToken: if (raw.dayOfWeek == -1) { // // This is a day of week name. // raw.dayOfWeek = tokenValue; dtok.dtt = DTT.DayOfWeek; } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0120 (DayOfWeek seen more than 1x)", dps); return false; } break; case TokenType.MonthToken: if (raw.month == -1) { // // This is a month name // switch(sep=str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) { case TokenType.SEP_End: dtok.dtt = DTT.MonthEnd; break; case TokenType.SEP_Space: dtok.dtt = DTT.MonthSpace; break; case TokenType.SEP_Date: dtok.dtt = DTT.MonthDatesep; break; case TokenType.SEP_Time: if (!raw.hasSameDateAndTimeSeparators) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0130 (Invalid separator after month name)", dps); return false; } // we have the date and time separators are same and getting a Month name, then change the token to MonthDatesep as // we are sure we are not parsing time. dtok.dtt = DTT.MonthDatesep; break; case TokenType.SEP_DateOrOffset: // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset. if ((dateParsingStates[(int)dps][(int) DTT.MonthDatesep] == DS.ERROR) && (dateParsingStates[(int)dps][(int) DTT.MonthSpace] > DS.ERROR)) { str.Index = indexBeforeSeparator; str.m_current = charBeforeSeparator; dtok.dtt = DTT.MonthSpace; } else { dtok.dtt = DTT.MonthDatesep; } break; default: //Invalid separator after month name result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0130 (Invalid separator after month name)", dps); return false; } raw.month = tokenValue; } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0140 (MonthToken seen more than 1x)", dps); return false; } break; case TokenType.EraToken: if (result.era != -1) { result.era = tokenValue; dtok.dtt = DTT.Era; } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0150 (EraToken seen when result.era already set)", dps); return false; } break; case TokenType.JapaneseEraToken: // Special case for Japanese. We allow Japanese era name to be used even if the calendar is not Japanese Calendar. result.calendar = JapaneseCalendar.GetDefaultInstance(); dtfi = DateTimeFormatInfo.GetJapaneseCalendarDTFI(); if (result.era != -1) { result.era = tokenValue; dtok.dtt = DTT.Era; } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0160 (JapaneseEraToken seen when result.era already set)", dps); return false; } break; case TokenType.TEraToken: result.calendar = TaiwanCalendar.GetDefaultInstance(); dtfi = DateTimeFormatInfo.GetTaiwanCalendarDTFI(); if (result.era != -1) { result.era = tokenValue; dtok.dtt = DTT.Era; } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0170 (TEraToken seen when result.era already set)", dps); return false; } break; case TokenType.TimeZoneToken: // // This is a timezone designator // // NOTENOTE : for now, we only support "GMT" and "Z" (for Zulu time). // if ((result.flags & ParseFlags.TimeZoneUsed) != 0) { // Should not have two timezone offsets. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0180 (seen GMT or Z more than 1x)", dps); return false; } dtok.dtt = DTT.TimeZone; result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0); result.flags |= ParseFlags.TimeZoneUtc; break; case TokenType.EndOfString: dtok.dtt = DTT.End; break; case TokenType.DateWordToken: case TokenType.IgnorableSymbol: // Date words and ignorable symbols can just be skipped over break; case TokenType.Am: case TokenType.Pm: if (raw.timeMark == TM.NotSet) { raw.timeMark = (TM)tokenValue; } else { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0190 (AM/PM timeMark already set)", dps); return false; } break; case TokenType.UnknownToken: if (Char.IsLetter(str.m_current)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_UnknowDateTimeWord", str.Index); LexTraceExit("0200", dps); return (false); } #if !FEATURE_CORECLR // If DateTimeParseIgnorePunctuation is defined, we want to have the V1.1 behavior of just // ignoring any unrecognized punctuation and moving on to the next character if (Environment.GetCompatibilityFlag(CompatibilityFlag.DateTimeParseIgnorePunctuation) && ((result.flags & ParseFlags.CaptureOffset) == 0)) { str.GetNext(); LexTraceExit("0210 (success)", dps); return true; } #endif // FEATURE_CORECLR if ((str.m_current == '-' || str.m_current == '+') && ((result.flags & ParseFlags.TimeZoneUsed) == 0)) { Int32 originalIndex = str.Index; if (ParseTimeZone(ref str, ref result.timeZoneOffset)) { result.flags |= ParseFlags.TimeZoneUsed; LexTraceExit("0220 (success)", dps); return true; } else { // Time zone parse attempt failed. Fall through to punctuation handling. str.Index = originalIndex; } } // Visual Basic implements string to date conversions on top of DateTime.Parse: // CDate("#10/10/95#") // if (VerifyValidPunctuation(ref str)) { LexTraceExit("0230 (success)", dps); return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); LexTraceExit("0240", dps); return false; } LexTraceExit("0250 (success)", dps); return true; }
// This is the helper function to handle timezone in string in the format like +/-0800 private static bool HandleTimeZone(ref __DTString str, ref DateTimeResult result) { if ((str.Index < str.len - 1)) { char nextCh = str.Value[str.Index]; // Skip whitespace, but don't update the index unless we find a time zone marker int whitespaceCount = 0; while (Char.IsWhiteSpace(nextCh) && str.Index + whitespaceCount < str.len - 1) { whitespaceCount++; nextCh = str.Value[str.Index + whitespaceCount]; } if (nextCh == '+' || nextCh == '-') { str.Index += whitespaceCount; if ((result.flags & ParseFlags.TimeZoneUsed) != 0) { // Should not have two timezone offsets. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.flags |= ParseFlags.TimeZoneUsed; if (!ParseTimeZone(ref str, ref result.timeZoneOffset)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } } return true; }
/*=================================DoStrictParse================================== **Action: Do DateTime parsing using the format in formatParam. **Returns: The parsed DateTime. **Arguments: **Exceptions: ** **Notes: ** When the following general formats are used, InvariantInfo is used in dtfi: ** 'r', 'R', 's'. ** When the following general formats are used, the time is assumed to be in Universal time. ** **Limitations: ** Only GregarianCalendar is supported for now. ** Only support GMT timezone. ==============================================================================*/ private static bool DoStrictParse( String s, String formatParam, DateTimeStyles styles, DateTimeFormatInfo dtfi, ref DateTimeResult result) { ParsingInfo parseInfo = new ParsingInfo(); parseInfo.Init(); parseInfo.calendar = dtfi.Calendar; parseInfo.fAllowInnerWhite = ((styles & DateTimeStyles.AllowInnerWhite) != 0); parseInfo.fAllowTrailingWhite = ((styles & DateTimeStyles.AllowTrailingWhite) != 0); // We need the original values of the following two below. String originalFormat = formatParam; if (formatParam.Length == 1) { if (((result.flags & ParseFlags.CaptureOffset) != 0) && formatParam[0] == 'U') { // The 'U' format is not allowed for DateTimeOffset result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } formatParam = ExpandPredefinedFormat(formatParam, ref dtfi, ref parseInfo, ref result); } bool bTimeOnly = false; result.calendar = parseInfo.calendar; if (parseInfo.calendar.ID == Calendar.CAL_HEBREW) { parseInfo.parseNumberDelegate = m_hebrewNumberParser; parseInfo.fCustomNumberParser = true; } // Reset these values to negative one so that we could throw exception // if we have parsed every item twice. result.Hour = result.Minute = result.Second = -1; __DTString format = new __DTString(formatParam, dtfi, false); __DTString str = new __DTString(s, dtfi, false); if (parseInfo.fAllowTrailingWhite) { // Trim trailing spaces if AllowTrailingWhite. format.TrimTail(); format.RemoveTrailingInQuoteSpaces(); str.TrimTail(); } if ((styles & DateTimeStyles.AllowLeadingWhite) != 0) { format.SkipWhiteSpaces(); format.RemoveLeadingInQuoteSpaces(); str.SkipWhiteSpaces(); } // // Scan every character in format and match the pattern in str. // while (format.GetNext()) { // We trim inner spaces here, so that we will not eat trailing spaces when // AllowTrailingWhite is not used. if (parseInfo.fAllowInnerWhite) { str.SkipWhiteSpaces(); } if (!ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) { return (false); } } if (str.Index < str.Value.Length - 1) { // There are still remaining character in str. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (parseInfo.fUseTwoDigitYear && ((dtfi.FormatFlags & DateTimeFormatFlags.UseHebrewRule) == 0)) { // A two digit year value is expected. Check if the parsed year value is valid. if (result.Year >= 100) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } try { result.Year = parseInfo.calendar.ToFourDigitYear(result.Year); } catch (ArgumentOutOfRangeException e) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", e); return false; } } if (parseInfo.fUseHour12) { if (parseInfo.timeMark == TM.NotSet) { // hh is used, but no AM/PM designator is specified. // Assume the time is AM. // Don't throw exceptions in here becasue it is very confusing for the caller. // I always got confused myself when I use "hh:mm:ss" to parse a time string, // and ParseExact() throws on me (because I didn't use the 24-hour clock 'HH'). parseInfo.timeMark = TM.AM; } if (result.Hour > 12) { // AM/PM is used, but the value for HH is too big. result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (parseInfo.timeMark == TM.AM) { if (result.Hour == 12) { result.Hour = 0; } } else { result.Hour = (result.Hour == 12) ? 12 : result.Hour + 12; } } else { // Military (24-hour time) mode // // AM cannot be set with a 24-hour time like 17:15. // PM cannot be set with a 24-hour time like 03:15. if ( (parseInfo.timeMark == TM.AM && result.Hour >= 12) ||(parseInfo.timeMark == TM.PM && result.Hour < 12)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } } // Check if the parased string only contains hour/minute/second values. bTimeOnly = (result.Year == -1 && result.Month == -1 && result.Day == -1); if (!CheckDefaultDateTime(ref result, ref parseInfo.calendar, styles)) { return false; } if (!bTimeOnly && dtfi.HasYearMonthAdjustment) { if (!dtfi.YearMonthAdjustment(ref result.Year, ref result.Month, ((result.flags & ParseFlags.ParsedMonthName) != 0))) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } } if (!parseInfo.calendar.TryToDateTime(result.Year, result.Month, result.Day, result.Hour, result.Minute, result.Second, 0, result.era, out result.parsedDate)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (result.fraction > 0) { result.parsedDate = result.parsedDate.AddTicks((long)Math.Round(result.fraction * Calendar.TicksPerSecond)); } // // We have to check day of week before we adjust to the time zone. // It is because the value of day of week may change after adjusting // to the time zone. // if (parseInfo.dayOfWeek != -1) { // // Check if day of week is correct. // if (parseInfo.dayOfWeek != (int)parseInfo.calendar.GetDayOfWeek(result.parsedDate)) { result.SetFailure(ParseFailureKind.Format, "Format_BadDayOfWeek", null); return false; } } if (!DetermineTimeZoneAdjustments(ref result, styles, bTimeOnly)) { 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 CheckDefaultDateTime(ref DateTimeResult result, ref Calendar cal, DateTimeStyles styles) { if ((result.flags & ParseFlags.CaptureOffset) != 0) { // DateTimeOffset.Parse should allow dates without a year, but only if there is also no time zone marker; // e.g. "May 1 5pm" is OK, but "May 1 5pm -08:30" is not. This is somewhat pragmatic, since we would // have to rearchitect parsing completely to allow this one case to correctly handle things like leap // years and leap months. Is is an extremely corner case, and DateTime is basically incorrect in that // case today. // // values like "11:00Z" or "11:00 -3:00" are also acceptable // // if ((month or day is set) and (year is not set and time zone is set)) // if ( ((result.Month != -1) || (result.Day != -1)) && ((result.Year == -1 || ((result.flags & ParseFlags.YearDefault) != 0)) && (result.flags & ParseFlags.TimeZoneUsed) != 0) ) { result.SetFailure(ParseFailureKind.Format, "Format_MissingIncompleteDate", null); return false; } } if ((result.Year == -1) || (result.Month == -1) || (result.Day == -1)) { /* The following table describes the behaviors of getting the default value when a certain year/month/day values are missing. An "X" means that the value exists. And "--" means that value is missing. Year Month Day => ResultYear ResultMonth ResultDay Note X X X Parsed year Parsed month Parsed day X X -- Parsed Year Parsed month First day If we have year and month, assume the first day of that month. X -- X Parsed year First month Parsed day If the month is missing, assume first month of that year. X -- -- Parsed year First month First day If we have only the year, assume the first day of that year. -- X X CurrentYear Parsed month Parsed day If the year is missing, assume the current year. -- X -- CurrentYear Parsed month First day If we have only a month value, assume the current year and current day. -- -- X CurrentYear First month Parsed day If we have only a day value, assume current year and first month. -- -- -- CurrentYear Current month Current day So this means that if the date string only contains time, you will get current date. */ DateTime now = GetDateTimeNow(ref result, ref styles); if (result.Month == -1 && result.Day == -1) { if (result.Year == -1) { if ((styles & DateTimeStyles.NoCurrentDateDefault) != 0) { // If there is no year/month/day values, and NoCurrentDateDefault flag is used, // set the year/month/day value to the beginning year/month/day of DateTime(). // Note we should be using Gregorian for the year/month/day. cal = GregorianCalendar.GetDefaultInstance(); result.Year = result.Month = result.Day = 1; } else { // Year/Month/Day are all missing. result.Year = cal.GetYear(now); result.Month = cal.GetMonth(now); result.Day = cal.GetDayOfMonth(now); } } else { // Month/Day are both missing. result.Month = 1; result.Day = 1; } } else { if (result.Year == -1) { result.Year = cal.GetYear(now); } if (result.Month == -1) { result.Month = 1; } if (result.Day == -1) { result.Day = 1; } } } // Set Hour/Minute/Second to zero if these value are not in str. if (result.Hour == -1) result.Hour = 0; if (result.Minute == -1) result.Minute = 0; if (result.Second == -1) result.Second = 0; if (result.era == -1) result.era = Calendar.CurrentEra; return true; }
private static bool GetDateOfNNDS(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { if ((result.flags & ParseFlags.HaveYear) != (ParseFlags)0) { if ((result.flags & ParseFlags.HaveMonth) == (ParseFlags)0 && (result.flags & ParseFlags.HaveDay) == (ParseFlags)0 && DateTimeParse.SetDateYMD(ref result, result.Year = DateTimeParse.AdjustYear(ref result, raw.year), raw.GetNumber(0), raw.GetNumber(1))) { return true; } } else { if ((result.flags & ParseFlags.HaveMonth) != (ParseFlags)0 && (result.flags & ParseFlags.HaveYear) == (ParseFlags)0 && (result.flags & ParseFlags.HaveDay) == (ParseFlags)0) { int num; if (!DateTimeParse.GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out num)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern); return false; } if (num == 0) { if (DateTimeParse.SetDateYMD(ref result, DateTimeParse.AdjustYear(ref result, raw.GetNumber(0)), result.Month, raw.GetNumber(1))) { return true; } } else { if (DateTimeParse.SetDateYMD(ref result, DateTimeParse.AdjustYear(ref result, raw.GetNumber(1)), result.Month, raw.GetNumber(0))) { return true; } } } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; }
internal static bool ProcessHebrewTerminalState(DateTimeParse.DS dps, ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { switch (dps) { case DateTimeParse.DS.DX_MN: case DateTimeParse.DS.DX_NM: { DateTimeParse.GetDefaultYear(ref result, ref styles); if (!dtfi.YearMonthAdjustment(ref result.Year, ref raw.month, true)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (!DateTimeParse.GetHebrewDayOfNM(ref result, ref raw, dtfi)) { return false; } goto IL_160; } case DateTimeParse.DS.DX_MNN: { raw.year = raw.GetNumber(1); if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (!DateTimeParse.GetDayOfMNN(ref result, ref raw, dtfi)) { return false; } goto IL_160; } case DateTimeParse.DS.DX_YMN: { if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (!DateTimeParse.GetDayOfYMN(ref result, ref raw, dtfi)) { return false; } goto IL_160; } case DateTimeParse.DS.DX_YM: { if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true)) { result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null); return false; } if (!DateTimeParse.GetDayOfYM(ref result, ref raw, dtfi)) { return false; } goto IL_160; } case DateTimeParse.DS.TX_N: { if (!DateTimeParse.GetTimeOfN(dtfi, ref result, ref raw)) { return false; } goto IL_160; } case DateTimeParse.DS.TX_NN: { if (!DateTimeParse.GetTimeOfNN(dtfi, ref result, ref raw)) { return false; } goto IL_160; } case DateTimeParse.DS.TX_NNN: { if (!DateTimeParse.GetTimeOfNNN(dtfi, ref result, ref raw)) { return false; } goto IL_160; } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; IL_160: if (dps > DateTimeParse.DS.ERROR) { raw.numCount = 0; } return true; }
private static bool GetDayOfMNN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { if ((result.flags & ParseFlags.HaveDate) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } int number = raw.GetNumber(0); int number2 = raw.GetNumber(1); int num; if (!DateTimeParse.GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out num)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern); return false; } if (num == 1) { int year; if (result.calendar.IsValidDay(year = DateTimeParse.AdjustYear(ref result, number2), raw.month, number, result.era)) { result.SetDate(year, raw.month, number); result.flags |= ParseFlags.HaveDate; return true; } if (result.calendar.IsValidDay(year = DateTimeParse.AdjustYear(ref result, number), raw.month, number2, result.era)) { result.SetDate(year, raw.month, number2); result.flags |= ParseFlags.HaveDate; return true; } } else { if (num == 0) { int year; if (result.calendar.IsValidDay(year = DateTimeParse.AdjustYear(ref result, number), raw.month, number2, result.era)) { result.SetDate(year, raw.month, number2); result.flags |= ParseFlags.HaveDate; return true; } if (result.calendar.IsValidDay(year = DateTimeParse.AdjustYear(ref result, number2), raw.month, number, result.era)) { result.SetDate(year, raw.month, number); result.flags |= ParseFlags.HaveDate; return true; } } else { if (num == 2) { int year; if (result.calendar.IsValidDay(year = DateTimeParse.AdjustYear(ref result, number2), raw.month, number, result.era)) { result.SetDate(year, raw.month, number); result.flags |= ParseFlags.HaveDate; return true; } if (result.calendar.IsValidDay(year = DateTimeParse.AdjustYear(ref result, number), raw.month, number2, result.era)) { result.SetDate(year, raw.month, number2); result.flags |= ParseFlags.HaveDate; return true; } } } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; }
private static bool DateTimeOffsetTimeZonePostProcessing(ref DateTimeResult result, DateTimeStyles styles) { if ((result.flags & ParseFlags.TimeZoneUsed) == (ParseFlags)0) { if ((styles & DateTimeStyles.AssumeUniversal) != DateTimeStyles.None) { result.timeZoneOffset = TimeSpan.Zero; } else { result.timeZoneOffset = TimeZoneInfo.Local.GetUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime); } } long ticks = result.timeZoneOffset.Ticks; long num = result.parsedDate.Ticks - ticks; if (num < 0L || num > 3155378975999999999L) { result.SetFailure(ParseFailureKind.Format, "Format_UTCOutOfRange", null); return false; } if (ticks < -504000000000L || ticks > 504000000000L) { result.SetFailure(ParseFailureKind.Format, "Format_OffsetOutOfRange", null); return false; } if ((styles & DateTimeStyles.AdjustToUniversal) != DateTimeStyles.None) { if ((result.flags & ParseFlags.TimeZoneUsed) == (ParseFlags)0 && (styles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.None) { bool result2 = DateTimeParse.AdjustTimeZoneToUniversal(ref result); result.timeZoneOffset = TimeSpan.Zero; return result2; } result.parsedDate = new DateTime(num, DateTimeKind.Utc); result.timeZoneOffset = TimeSpan.Zero; } return true; }
private static bool GetDayOfNNY(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { if ((result.flags & ParseFlags.HaveDate) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } int number = raw.GetNumber(0); int number2 = raw.GetNumber(1); int num; if (!DateTimeParse.GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out num)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern); return false; } if (num == 1 || num == 0) { if (DateTimeParse.SetDateYMD(ref result, raw.year, number, number2)) { result.flags |= ParseFlags.HaveDate; return true; } } else { if (DateTimeParse.SetDateYMD(ref result, raw.year, number2, number)) { result.flags |= ParseFlags.HaveDate; return true; } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; }
private static bool AdjustTimeZoneToLocal(ref DateTimeResult result, bool bTimeOnly) { long num = result.parsedDate.Ticks; TimeZoneInfo local = TimeZoneInfo.Local; bool isAmbiguousDst = false; if (num < 864000000000L) { num -= result.timeZoneOffset.Ticks; num += local.GetUtcOffset(bTimeOnly ? DateTime.Now : result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks; if (num < 0L) { num += 864000000000L; } } else { num -= result.timeZoneOffset.Ticks; if (num < 0L || num > 3155378975999999999L) { num += local.GetUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks; } else { DateTime time = new DateTime(num, DateTimeKind.Utc); bool flag = false; num += TimeZoneInfo.GetUtcOffsetFromUtc(time, TimeZoneInfo.Local, out flag, out isAmbiguousDst).Ticks; } } if (num < 0L || num > 3155378975999999999L) { result.parsedDate = DateTime.MinValue; result.SetFailure(ParseFailureKind.Format, "Format_DateOutOfRange", null); return false; } result.parsedDate = new DateTime(num, DateTimeKind.Local, isAmbiguousDst); return true; }
private static bool GetDayOfYM(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) { if ((result.flags & ParseFlags.HaveDate) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (DateTimeParse.SetDateYMD(ref result, raw.year, raw.month, 1)) { result.flags |= ParseFlags.HaveDate; return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; }
private static bool CheckNewValue(ref int currentValue, int newValue, char patternChar, ref DateTimeResult result) { if (currentValue == -1) { currentValue = newValue; return true; } if (newValue != currentValue) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", patternChar); return false; } return true; }
private static bool GetTimeOfN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw) { if ((result.flags & ParseFlags.HaveTime) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (raw.timeMark == DateTimeParse.TM.NotSet) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.Hour = raw.GetNumber(0); result.flags |= ParseFlags.HaveTime; 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 GetTimeOfNNN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw) { if ((result.flags & ParseFlags.HaveTime) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.Hour = raw.GetNumber(0); result.Minute = raw.GetNumber(1); result.Second = raw.GetNumber(2); result.flags |= ParseFlags.HaveTime; return true; }
internal static bool TryParseExactMultiple(string s, string[] formats, DateTimeFormatInfo dtfi, DateTimeStyles style, ref DateTimeResult result) { if (s == null) { result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "s"); return false; } if (formats == null) { result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "formats"); return false; } if (s.Length == 0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (formats.Length == 0) { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } for (int i = 0; i < formats.Length; i++) { if (formats[i] == null || formats[i].Length == 0) { result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null); return false; } DateTimeResult dateTimeResult = default(DateTimeResult); dateTimeResult.Init(); dateTimeResult.flags = result.flags; if (DateTimeParse.TryParseExact(s, formats[i], dtfi, style, ref dateTimeResult)) { result.parsedDate = dateTimeResult.parsedDate; result.timeZoneOffset = dateTimeResult.timeZoneOffset; return true; } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; }
private static bool GetDateOfDSN(ref DateTimeResult result, ref DateTimeRawInfo raw) { if (raw.numCount != 1 || result.Day != -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.Day = raw.GetNumber(0); return true; }
private static bool Lex(DateTimeParse.DS dps, ref __DTString str, ref DateTimeToken dtok, ref DateTimeRawInfo raw, ref DateTimeResult result, ref DateTimeFormatInfo dtfi) { dtok.dtt = DateTimeParse.DTT.Unk; TokenType tokenType; int num; str.GetRegularToken(out tokenType, out num, dtfi); switch (tokenType) { case TokenType.NumberToken: case TokenType.YearNumberToken: { if (raw.numCount == 3 || num == -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (dps == DateTimeParse.DS.T_NNt && str.Index < str.len - 1) { char c = str.Value[str.Index]; if (c == '.') { DateTimeParse.ParseFraction(ref str, out raw.fraction); } } if ((dps == DateTimeParse.DS.T_NNt || dps == DateTimeParse.DS.T_Nt) && str.Index < str.len - 1 && !DateTimeParse.HandleTimeZone(ref str, ref result)) { return false; } dtok.num = num; if (tokenType != TokenType.YearNumberToken) { int index; char current; TokenType separatorToken; TokenType tokenType2 = separatorToken = str.GetSeparatorToken(dtfi, out index, out current); if (separatorToken > TokenType.SEP_YearSuff) { if (separatorToken <= TokenType.SEP_HourSuff) { if (separatorToken == TokenType.SEP_MonthSuff || separatorToken == TokenType.SEP_DaySuff) { dtok.dtt = DateTimeParse.DTT.NumDatesuff; dtok.suffix = tokenType2; break; } if (separatorToken != TokenType.SEP_HourSuff) { goto IL_52A; } } else { if (separatorToken <= TokenType.SEP_SecondSuff) { if (separatorToken != TokenType.SEP_MinuteSuff && separatorToken != TokenType.SEP_SecondSuff) { goto IL_52A; } } else { if (separatorToken == TokenType.SEP_LocalTimeMark) { dtok.dtt = DateTimeParse.DTT.NumLocalTimeMark; raw.AddNumber(dtok.num); break; } if (separatorToken != TokenType.SEP_DateOrOffset) { goto IL_52A; } if (DateTimeParse.dateParsingStates[(int)dps][4] == DateTimeParse.DS.ERROR && DateTimeParse.dateParsingStates[(int)dps][3] > DateTimeParse.DS.ERROR) { str.Index = index; str.m_current = current; dtok.dtt = DateTimeParse.DTT.NumSpace; } else { dtok.dtt = DateTimeParse.DTT.NumDatesep; } raw.AddNumber(dtok.num); break; } } dtok.dtt = DateTimeParse.DTT.NumTimesuff; dtok.suffix = tokenType2; break; } if (separatorToken <= TokenType.SEP_Am) { if (separatorToken == TokenType.SEP_End) { dtok.dtt = DateTimeParse.DTT.NumEnd; raw.AddNumber(dtok.num); break; } if (separatorToken == TokenType.SEP_Space) { dtok.dtt = DateTimeParse.DTT.NumSpace; raw.AddNumber(dtok.num); break; } if (separatorToken != TokenType.SEP_Am) { goto IL_52A; } } else { if (separatorToken <= TokenType.SEP_Date) { if (separatorToken != TokenType.SEP_Pm) { if (separatorToken != TokenType.SEP_Date) { goto IL_52A; } dtok.dtt = DateTimeParse.DTT.NumDatesep; raw.AddNumber(dtok.num); break; } } else { if (separatorToken == TokenType.SEP_Time) { dtok.dtt = DateTimeParse.DTT.NumTimesep; raw.AddNumber(dtok.num); break; } if (separatorToken != TokenType.SEP_YearSuff) { goto IL_52A; } dtok.num = dtfi.Calendar.ToFourDigitYear(num); dtok.dtt = DateTimeParse.DTT.NumDatesuff; dtok.suffix = tokenType2; break; } } if (raw.timeMark != DateTimeParse.TM.NotSet) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); break; } raw.timeMark = ((tokenType2 == TokenType.SEP_Am) ? DateTimeParse.TM.AM : DateTimeParse.TM.PM); dtok.dtt = DateTimeParse.DTT.NumAmpm; raw.AddNumber(dtok.num); if ((dps == DateTimeParse.DS.T_NNt || dps == DateTimeParse.DS.T_Nt) && !DateTimeParse.HandleTimeZone(ref str, ref result)) { return false; } break; IL_52A: result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (raw.year == -1) { raw.year = num; int index; char current; TokenType separatorToken2; TokenType tokenType2 = separatorToken2 = str.GetSeparatorToken(dtfi, out index, out current); if (separatorToken2 > TokenType.SEP_YearSuff) { if (separatorToken2 <= TokenType.SEP_HourSuff) { if (separatorToken2 == TokenType.SEP_MonthSuff || separatorToken2 == TokenType.SEP_DaySuff) { goto IL_26A; } if (separatorToken2 != TokenType.SEP_HourSuff) { goto IL_28E; } } else { if (separatorToken2 != TokenType.SEP_MinuteSuff && separatorToken2 != TokenType.SEP_SecondSuff) { if (separatorToken2 != TokenType.SEP_DateOrOffset) { goto IL_28E; } if (DateTimeParse.dateParsingStates[(int)dps][13] == DateTimeParse.DS.ERROR && DateTimeParse.dateParsingStates[(int)dps][12] > DateTimeParse.DS.ERROR) { str.Index = index; str.m_current = current; dtok.dtt = DateTimeParse.DTT.YearSpace; return true; } dtok.dtt = DateTimeParse.DTT.YearDateSep; return true; } } dtok.dtt = DateTimeParse.DTT.NumTimesuff; dtok.suffix = tokenType2; return true; } if (separatorToken2 <= TokenType.SEP_Am) { if (separatorToken2 == TokenType.SEP_End) { dtok.dtt = DateTimeParse.DTT.YearEnd; return true; } if (separatorToken2 == TokenType.SEP_Space) { dtok.dtt = DateTimeParse.DTT.YearSpace; return true; } if (separatorToken2 != TokenType.SEP_Am) { goto IL_28E; } } else { if (separatorToken2 != TokenType.SEP_Pm) { if (separatorToken2 == TokenType.SEP_Date) { dtok.dtt = DateTimeParse.DTT.YearDateSep; return true; } if (separatorToken2 != TokenType.SEP_YearSuff) { goto IL_28E; } goto IL_26A; } } if (raw.timeMark == DateTimeParse.TM.NotSet) { raw.timeMark = ((tokenType2 == TokenType.SEP_Am) ? DateTimeParse.TM.AM : DateTimeParse.TM.PM); dtok.dtt = DateTimeParse.DTT.YearSpace; return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return true; IL_26A: dtok.dtt = DateTimeParse.DTT.NumDatesuff; dtok.suffix = tokenType2; return true; IL_28E: result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } case TokenType.Am: case TokenType.Pm: { if (raw.timeMark != DateTimeParse.TM.NotSet) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } raw.timeMark = (DateTimeParse.TM)num; break; } case TokenType.MonthToken: { if (raw.month != -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } int index; char current; TokenType separatorToken3 = str.GetSeparatorToken(dtfi, out index, out current); if (separatorToken3 <= TokenType.SEP_Space) { if (separatorToken3 == TokenType.SEP_End) { dtok.dtt = DateTimeParse.DTT.MonthEnd; goto IL_786; } if (separatorToken3 == TokenType.SEP_Space) { dtok.dtt = DateTimeParse.DTT.MonthSpace; goto IL_786; } } else { if (separatorToken3 == TokenType.SEP_Date) { dtok.dtt = DateTimeParse.DTT.MonthDatesep; goto IL_786; } if (separatorToken3 == TokenType.SEP_DateOrOffset) { if (DateTimeParse.dateParsingStates[(int)dps][8] == DateTimeParse.DS.ERROR && DateTimeParse.dateParsingStates[(int)dps][7] > DateTimeParse.DS.ERROR) { str.Index = index; str.m_current = current; dtok.dtt = DateTimeParse.DTT.MonthSpace; goto IL_786; } dtok.dtt = DateTimeParse.DTT.MonthDatesep; goto IL_786; } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; IL_786: raw.month = num; break; } case TokenType.EndOfString: { dtok.dtt = DateTimeParse.DTT.End; break; } case TokenType.DayOfWeekToken: { if (raw.dayOfWeek != -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } raw.dayOfWeek = num; dtok.dtt = DateTimeParse.DTT.DayOfWeek; break; } case TokenType.TimeZoneToken: { if ((result.flags & ParseFlags.TimeZoneUsed) != (ParseFlags)0) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } dtok.dtt = DateTimeParse.DTT.TimeZone; result.flags |= ParseFlags.TimeZoneUsed; result.timeZoneOffset = new TimeSpan(0L); result.flags |= ParseFlags.TimeZoneUtc; break; } case TokenType.EraToken: { if (result.era == -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.era = num; dtok.dtt = DateTimeParse.DTT.Era; break; } case TokenType.UnknownToken: { if (char.IsLetter(str.m_current)) { result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_UnknowDateTimeWord", str.Index); return false; } if (Environment.GetCompatibilityFlag(CompatibilityFlag.DateTimeParseIgnorePunctuation) && (result.flags & ParseFlags.CaptureOffset) == (ParseFlags)0) { str.GetNext(); return true; } if ((str.m_current == '-' || str.m_current == '+') && (result.flags & ParseFlags.TimeZoneUsed) == (ParseFlags)0) { int index2 = str.Index; if (DateTimeParse.ParseTimeZone(ref str, ref result.timeZoneOffset)) { result.flags |= ParseFlags.TimeZoneUsed; return true; } str.Index = index2; } if (DateTimeParse.VerifyValidPunctuation(ref str)) { return true; } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } case TokenType.HebrewNumber: { int index; char current; if (num < 100) { dtok.num = num; raw.AddNumber(dtok.num); TokenType separatorToken4 = str.GetSeparatorToken(dtfi, out index, out current); if (separatorToken4 <= TokenType.SEP_Space) { if (separatorToken4 == TokenType.SEP_End) { dtok.dtt = DateTimeParse.DTT.NumEnd; break; } if (separatorToken4 != TokenType.SEP_Space) { goto IL_695; } } else { if (separatorToken4 != TokenType.SEP_Date) { if (separatorToken4 != TokenType.SEP_DateOrOffset) { goto IL_695; } if (DateTimeParse.dateParsingStates[(int)dps][4] == DateTimeParse.DS.ERROR && DateTimeParse.dateParsingStates[(int)dps][3] > DateTimeParse.DS.ERROR) { str.Index = index; str.m_current = current; dtok.dtt = DateTimeParse.DTT.NumSpace; break; } dtok.dtt = DateTimeParse.DTT.NumDatesep; break; } } dtok.dtt = DateTimeParse.DTT.NumDatesep; break; IL_695: result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (raw.year != -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } raw.year = num; TokenType separatorToken5 = str.GetSeparatorToken(dtfi, out index, out current); if (separatorToken5 != TokenType.SEP_End) { if (separatorToken5 != TokenType.SEP_Space) { if (separatorToken5 == TokenType.SEP_DateOrOffset) { if (DateTimeParse.dateParsingStates[(int)dps][12] > DateTimeParse.DS.ERROR) { str.Index = index; str.m_current = current; dtok.dtt = DateTimeParse.DTT.YearSpace; break; } } result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } dtok.dtt = DateTimeParse.DTT.YearSpace; } else { dtok.dtt = DateTimeParse.DTT.YearEnd; } break; } case TokenType.JapaneseEraToken: { result.calendar = JapaneseCalendar.GetDefaultInstance(); dtfi = DateTimeFormatInfo.GetJapaneseCalendarDTFI(); if (result.era == -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.era = num; dtok.dtt = DateTimeParse.DTT.Era; break; } case TokenType.TEraToken: { result.calendar = TaiwanCalendar.GetDefaultInstance(); dtfi = DateTimeFormatInfo.GetTaiwanCalendarDTFI(); if (result.era == -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.era = num; dtok.dtt = DateTimeParse.DTT.Era; break; } } return true; }
private static bool GetDateOfNDS(ref DateTimeResult result, ref DateTimeRawInfo raw) { if (result.Month == -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } if (result.Year != -1) { result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null); return false; } result.Year = DateTimeParse.AdjustYear(ref result, raw.GetNumber(0)); result.Day = 1; return true; }