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 MatchWord(ref __DTString str, string target) { int length = target.Length; if (length > str.Value.Length - str.Index) { return false; } if (str.CompareInfo.Compare(str.Value, str.Index, length, target, 0, length, CompareOptions.IgnoreCase) != 0) { return false; } int num = str.Index + target.Length; if (num < str.Value.Length) { char c = str.Value[num]; if (char.IsLetter(c)) { return false; } } str.Index = num; if (str.Index < str.len) { str.m_current = str.Value[str.Index]; } return true; }
private static bool ParseFraction(ref __DTString str, out double result) { result = 0.0; double num = 0.1; int num2 = 0; char current; while (str.GetNext() && DateTimeParse.IsDigit(current = str.m_current)) { result += (double)(current - '0') * num; num *= 0.1; num2++; } return num2 > 0; }
private static bool MatchTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, ref DateTimeParse.TM result) { result = DateTimeParse.TM.NotSet; if (dtfi.AMDesignator.Length == 0) { result = DateTimeParse.TM.AM; } if (dtfi.PMDesignator.Length == 0) { result = DateTimeParse.TM.PM; } if (str.GetNext()) { string text = dtfi.AMDesignator; if (text.Length > 0 && str.MatchSpecifiedWord(text)) { str.Index += text.Length - 1; result = DateTimeParse.TM.AM; return true; } text = dtfi.PMDesignator; if (text.Length > 0 && str.MatchSpecifiedWord(text)) { str.Index += text.Length - 1; result = DateTimeParse.TM.PM; return true; } str.Index--; } return result != -1; }
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 ParseTimeZoneOffset(ref __DTString str, int len, ref TimeSpan result) { bool flag = true; int num = 0; int hours; switch (len) { case 1: case 2: { if (!DateTimeParse.ParseSign(ref str, ref flag)) { return false; } if (!DateTimeParse.ParseDigits(ref str, len, out hours)) { return false; } break; } default: { if (!DateTimeParse.ParseSign(ref str, ref flag)) { return false; } if (!DateTimeParse.ParseDigits(ref str, 1, out hours)) { return false; } if (str.Match(":")) { if (!DateTimeParse.ParseDigits(ref str, 2, out num)) { return false; } } else { str.Index--; if (!DateTimeParse.ParseDigits(ref str, 2, out num)) { return false; } } break; } } if (num < 0 || num >= 60) { return false; } result = new TimeSpan(hours, num, 0); if (!flag) { result = result.Negate(); } return true; }
private static bool MatchDayName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) { int num = 0; result = -1; if (str.GetNext()) { for (DayOfWeek dayOfWeek = DayOfWeek.Sunday; dayOfWeek <= DayOfWeek.Saturday; dayOfWeek += DayOfWeek.Monday) { string dayName = dtfi.GetDayName(dayOfWeek); int length = dayName.Length; if ((dtfi.HasSpacesInDayNames ? str.MatchSpecifiedWords(dayName, false, ref length) : str.MatchSpecifiedWord(dayName)) && length > num) { num = length; result = (int)dayOfWeek; } } } if (result >= 0) { str.Index += num - 1; return true; } return false; }
/*=================================ParseTimeZone========================== **Action: Parse the timezone offset in the following format: ** "+8", "+08", "+0800", "+0800" ** This method is used by DateTime.Parse(). **Returns: The TimeZone offset. **Arguments: ** str the parsing string **Exceptions: ** FormatException if invalid timezone format is found. ============================================================================*/ private static bool ParseTimeZone(ref __DTString str, ref TimeSpan result) { // The hour/minute offset for timezone. int hourOffset = 0; int minuteOffset = 0; DTSubString sub; // Consume the +/- character that has already been read sub = str.GetSubString(); if (sub.length != 1) { return false; } char offsetChar = sub[0]; if (offsetChar != '+' && offsetChar != '-') { return false; } str.ConsumeSubString(sub); sub = str.GetSubString(); if (sub.type != DTSubStringType.Number) { return false; } int value = sub.value; int length = sub.length; if (length == 1 || length == 2) { // Parsing "+8" or "+08" hourOffset = value; str.ConsumeSubString(sub); // See if we have minutes sub = str.GetSubString(); if (sub.length == 1 && sub[0] == ':') { // Parsing "+8:00" or "+08:00" str.ConsumeSubString(sub); sub = str.GetSubString(); if (sub.type != DTSubStringType.Number || sub.length < 1 || sub.length > 2) { return false; } minuteOffset = sub.value; str.ConsumeSubString(sub); } } else if (length == 3 || length == 4) { // Parsing "+800" or "+0800" hourOffset = value / 100; minuteOffset = value % 100; str.ConsumeSubString(sub); } else { // Wrong number of digits return false; } Contract.Assert(hourOffset >= 0 && hourOffset <= 99, "hourOffset >= 0 && hourOffset <= 99"); Contract.Assert(minuteOffset >= 0 && minuteOffset <= 99, "minuteOffset >= 0 && minuteOffset <= 99"); if (minuteOffset < 0 || minuteOffset >= 60) { return false; } result = new TimeSpan(hourOffset, minuteOffset, 0); if (offsetChar == '-') { result = result.Negate(); } return true; }
// 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; }
// // Check the word at the current index to see if it matches GMT name or Zulu name. // private static bool GetTimeZoneName(ref __DTString str) { if (MatchWord(ref str, GMTName)) { return (true); } if (MatchWord(ref str, ZuluName)) { return (true); } return (false); }
/*=================================ParseFraction========================== **Action: Starting at the str.Index, which should be a decimal symbol. ** if the current character is a digit, parse the remaining ** numbers as fraction. For example, if the sub-string starting at str.Index is "123", then ** the method will return 0.123 **Returns: The fraction number. **Arguments: ** str the parsing string **Exceptions: ============================================================================*/ private static bool ParseFraction(ref __DTString str, out double result) { result = 0; double decimalBase = 0.1; int digits = 0; char ch; while (str.GetNext() && IsDigit(ch = str.m_current)) { result += (ch - '0') * decimalBase; decimalBase *= 0.1; digits++; } return (digits > 0); }
// // Search from the index of str at str.Index to see if the target string exists in the str. // private static bool MatchWord(ref __DTString str, String target) { int length = target.Length; if (length > (str.Value.Length - str.Index)) { return false; } if (str.CompareInfo.Compare(str.Value, str.Index, length, target, 0, length, CompareOptions.IgnoreCase)!=0) { return (false); } int nextCharIndex = str.Index + target.Length; if (nextCharIndex < str.Value.Length) { char nextCh = str.Value[nextCharIndex]; if (Char.IsLetter(nextCh)) { return (false); } } str.Index = nextCharIndex; if (str.Index < str.len) { str.m_current = str.Value[str.Index]; } return (true); }
internal static bool IsDigit(char ch) => default; // 0x00000001809090F0-0x0000000180909110 private static bool ParseFraction(ref __DTString str, out double result) { result = default; return(default);
private static bool MatchWord(ref __DTString str, string target) => default; // 0x000000018090A9C0-0x000000018090AB00 private static bool GetTimeZoneName(ref __DTString str) => default; // 0x0000000180908B70-0x0000000180908C10
//////////////////////////////////////////////////////////////////////// // // Actions: // Try to parse the current word to see if it is a Hebrew number. // Tokens will be updated accordingly. // This is called by the Lexer of DateTime.Parse(). // // Unlike most of the functions in this class, the return value indicates // whether or not it started to parse. The badFormat parameter indicates // if parsing began, but the format was bad. // //////////////////////////////////////////////////////////////////////// private static bool TryParseHebrewNumber( ref __DTString str, out Boolean badFormat, out int number) { number = -1; badFormat = false; int i = str.Index; if (!HebrewNumber.IsDigit(str.Value[i])) { // If the current character is not a Hebrew digit, just return false. // There is no chance that we can parse a valid Hebrew number from here. return (false); } // The current character is a Hebrew digit. Try to parse this word as a Hebrew number. HebrewNumberParsingContext context = new HebrewNumberParsingContext(0); HebrewNumberParsingState state; do { state = HebrewNumber.ParseByChar(str.Value[i++], ref context); switch (state) { case HebrewNumberParsingState.InvalidHebrewNumber: // Not a valid Hebrew number. case HebrewNumberParsingState.NotHebrewDigit: // The current character is not a Hebrew digit character. // Break out so that we don't continue to try parse this as a Hebrew number. return (false); } } while (i < str.Value.Length && (state != HebrewNumberParsingState.FoundEndOfHebrewNumber)); // When we are here, we are either at the end of the string, or we find a valid Hebrew number. Contract.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber, "Invalid returned state from HebrewNumber.ParseByChar()"); if (state != HebrewNumberParsingState.FoundEndOfHebrewNumber) { // We reach end of the string but we can't find a terminal state in parsing Hebrew number. return (false); } // We have found a valid Hebrew number. Update the index. str.Advance(i - str.Index); // Get the final Hebrew number value from the HebrewNumberParsingContext. number = context.result; return (true); }
[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; }
internal static bool TryParseExactMultiple(string s, string[] formats, DateTimeFormatInfo dtfi, DateTimeStyles style, ref DateTimeResult result) => default; // 0x000000018090E570-0x000000018090E800 private static bool MatchWord(ref __DTString str, string target) => default; // 0x000000018090A9C0-0x000000018090AB00
private static bool VerifyValidPunctuation(ref __DTString str) { char c = str.Value[str.Index]; if (c == '#') { bool flag = false; bool flag2 = false; for (int i = 0; i < str.len; i++) { c = str.Value[i]; if (c == '#') { if (flag) { if (flag2) { return false; } flag2 = true; } else { flag = true; } } else { if (c == '\0') { if (!flag2) { return false; } } else { if (!char.IsWhiteSpace(c) && (!flag || flag2)) { return false; } } } } if (!flag2) { return false; } str.GetNext(); return true; } else { if (c == '\0') { for (int j = str.Index; j < str.len; j++) { if (str.Value[j] != '\0') { return false; } } str.Index = str.len; return true; } return false; } }
private static bool MatchMonthName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) { int num = 0; result = -1; if (str.GetNext()) { int num2 = (dtfi.GetMonthName(13).Length == 0) ? 12 : 13; for (int i = 1; i <= num2; i++) { string monthName = dtfi.GetMonthName(i); int length = monthName.Length; if ((dtfi.HasSpacesInMonthNames ? str.MatchSpecifiedWords(monthName, false, ref length) : str.MatchSpecifiedWord(monthName)) && length > num) { num = length; result = i; } } if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != DateTimeFormatFlags.None) { int num3 = str.MatchLongestWords(dtfi.MonthGenitiveNames, ref num); if (num3 >= 0) { result = num3 + 1; } } if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != DateTimeFormatFlags.None) { int num4 = str.MatchLongestWords(dtfi.internalGetLeapYearMonthNames(), ref num); if (num4 >= 0) { result = num4 + 1; } } } if (result > 0) { str.Index += num - 1; return true; } return false; }
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 MatchEraName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) { if (str.GetNext()) { int[] eras = dtfi.Calendar.Eras; if (eras != null) { for (int i = 0; i < eras.Length; i++) { string text = dtfi.GetEraName(eras[i]); if (str.MatchSpecifiedWord(text)) { str.Index += text.Length - 1; result = eras[i]; return true; } text = dtfi.GetAbbreviatedEraName(eras[i]); if (str.MatchSpecifiedWord(text)) { str.Index += text.Length - 1; result = eras[i]; return true; } } } } return false; }
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 MatchAbbreviatedTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, ref DateTimeParse.TM result) { if (str.GetNext()) { if (str.GetChar() == dtfi.AMDesignator[0]) { result = DateTimeParse.TM.AM; return true; } if (str.GetChar() == dtfi.PMDesignator[0]) { result = DateTimeParse.TM.PM; return true; } } return false; }
internal static bool MatchHebrewDigits(ref __DTString str, int digitLen, out int number) { number = 0; HebrewNumberParsingContext hebrewNumberParsingContext = new HebrewNumberParsingContext(0); HebrewNumberParsingState hebrewNumberParsingState = HebrewNumberParsingState.ContinueParsing; while (hebrewNumberParsingState == HebrewNumberParsingState.ContinueParsing && str.GetNext()) { hebrewNumberParsingState = HebrewNumber.ParseByChar(str.GetChar(), ref hebrewNumberParsingContext); } if (hebrewNumberParsingState == HebrewNumberParsingState.FoundEndOfHebrewNumber) { number = hebrewNumberParsingContext.result; return true; } return false; }
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); }
internal static bool ParseDigits(ref __DTString str, int digitLen, out int result) { if (digitLen == 1) { return DateTimeParse.ParseDigits(ref str, 1, 2, out result); } return DateTimeParse.ParseDigits(ref str, digitLen, digitLen, out result); }
private static bool GetTimeZoneName(ref __DTString str) { return DateTimeParse.MatchWord(ref str, "GMT") || DateTimeParse.MatchWord(ref str, "Z"); }
internal static bool ParseDigits(ref __DTString str, int minDigitLen, int maxDigitLen, out int result) { result = 0; int index = str.Index; int i; for (i = 0; i < maxDigitLen; i++) { if (!str.GetNextDigit()) { str.Index--; break; } result = result * 10 + str.GetDigit(); } if (i < minDigitLen) { str.Index = index; return false; } return true; }
private static bool ParseTimeZone(ref __DTString str, ref TimeSpan result) { int hours = 0; int num = 0; DTSubString subString = str.GetSubString(); if (subString.length != 1) { return false; } char c = subString[0]; if (c != '+' && c != '-') { return false; } str.ConsumeSubString(subString); subString = str.GetSubString(); if (subString.type != DTSubStringType.Number) { return false; } int value = subString.value; int length = subString.length; if (length == 1 || length == 2) { hours = value; str.ConsumeSubString(subString); subString = str.GetSubString(); if (subString.length == 1 && subString[0] == ':') { str.ConsumeSubString(subString); subString = str.GetSubString(); if (subString.type != DTSubStringType.Number || subString.length < 1 || subString.length > 2) { return false; } num = subString.value; str.ConsumeSubString(subString); } } else { if (length != 3 && length != 4) { return false; } hours = value / 100; num = value % 100; str.ConsumeSubString(subString); } if (num < 0 || num >= 60) { return false; } result = new TimeSpan(hours, num, 0); if (c == '-') { result = result.Negate(); } return true; }
private static bool ParseFractionExact(ref __DTString str, int maxDigitLen, ref double result) { if (!str.GetNextDigit()) { str.Index--; return false; } result = (double)str.GetDigit(); int i; for (i = 1; i < maxDigitLen; i++) { if (!str.GetNextDigit()) { str.Index--; break; } result = result * 10.0 + (double)str.GetDigit(); } result /= Math.Pow(10.0, (double)i); return i == maxDigitLen; }
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 ParseSign(ref __DTString str, ref bool result) { if (!str.GetNext()) { return false; } char @char = str.GetChar(); if (@char == '+') { result = true; return true; } if (@char == '-') { result = false; return true; } return false; }
[System.Security.SecurityCritical] // auto-generated internal bool Tokenize(TokenType TokenMask, out TokenType tokenType, out int tokenValue, ref __DTString str) { tokenType = TokenType.UnknownToken; tokenValue = 0; TokenHashValue value; Contract.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length"); char ch = str.m_current; bool isLetter = Char.IsLetter(ch); if (isLetter) { ch = Char.ToLower(ch, this.Culture); if (IsHebrewChar(ch) && TokenMask == TokenType.RegularTokenMask) { bool badFormat; if (TryParseHebrewNumber(ref str, out badFormat, out tokenValue)) { if (badFormat) { tokenType = TokenType.UnknownToken; return (false); } // This is a Hebrew number. // Do nothing here. TryParseHebrewNumber() will update token accordingly. tokenType = TokenType.HebrewNumber; return (true); } } } int hashcode = ch % TOKEN_HASH_SIZE; int hashProbe = 1 + ch % SECOND_PRIME; int remaining = str.len - str.Index; int i = 0; TokenHashValue[] hashTable = m_dtfiTokenHash; if (hashTable == null) { hashTable = CreateTokenHashTable(); } do { value = hashTable[hashcode]; if (value == null) { // Not found. break; } // Check this value has the right category (regular token or separator token) that we are looking for. if (((int)value.tokenType & (int)TokenMask) > 0 && value.tokenString.Length <= remaining) { if (String.Compare(str.Value, str.Index, value.tokenString, 0, value.tokenString.Length, this.Culture, CompareOptions.IgnoreCase)==0) { if (isLetter) { // If this token starts with a letter, make sure that we won't allow partial match. So you can't tokenize "MarchWed" separately. int nextCharIndex; if ((nextCharIndex = str.Index + value.tokenString.Length) < str.len) { // Check word boundary. The next character should NOT be a letter. char nextCh = str.Value[nextCharIndex]; if (Char.IsLetter(nextCh)) { return (false); } } } tokenType = value.tokenType & TokenMask; tokenValue = value.tokenValue; str.Advance(value.tokenString.Length); return (true); } else if (value.tokenType == TokenType.MonthToken && HasSpacesInMonthNames) { // For month token, we will match the month names which have spaces. int matchStrLen = 0; if (str.MatchSpecifiedWords(value.tokenString, true, ref matchStrLen)) { tokenType = value.tokenType & TokenMask; tokenValue = value.tokenValue; str.Advance(matchStrLen); return (true); } } else if (value.tokenType == TokenType.DayOfWeekToken && HasSpacesInDayNames) { // For month token, we will match the month names which have spaces. int matchStrLen = 0; if (str.MatchSpecifiedWords(value.tokenString, true, ref matchStrLen)) { tokenType = value.tokenType & TokenMask; tokenValue = value.tokenValue; str.Advance(matchStrLen); return (true); } } } i++; hashcode += hashProbe; if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE; }while (i < TOKEN_HASH_SIZE); return (false); }
internal __DTString(string str, DateTimeFormatInfo dtfi, bool checkDigitToken) { this = new __DTString(str, dtfi); this.m_checkDigitToken = checkDigitToken; }