GetChar() приватный Метод

private GetChar ( ) : char
Результат char
		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);
		}
Пример #2
0
        /*=================================MatchAbbreviatedTimeMark==================================
        **Action: Parse the abbreviated time mark (AM/PM) from string starting at str.Index.
        **Returns: TM_AM or TM_PM.
        **Arguments:    str: a __DTString.  The parsing will start from the
        **              next character after str.Index.
        **Exceptions: FormatException if a abbreviated time mark can not be found.
        ==============================================================================*/

        private static bool MatchAbbreviatedTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, ref TM result) {
            // NOTENOTE : the assumption here is that abbreviated time mark is the first
            // character of the AM/PM designator.  If this invariant changes, we have to
            // change the code below.
            if (str.GetNext())
            {
                if (str.GetChar() == dtfi.AMDesignator[0]) {
                    result = TM.AM;
                    return (true);
                }
                if (str.GetChar() == dtfi.PMDesignator[0]) {
                    result = TM.PM;
                    return (true);
                }
            }
            return false;
        }
Пример #3
0
        // 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);
        }
Пример #4
0
        ////////////////////////////////////////////////////////////////////////
        //
        // Actions:
        //    Parse the current word as a Hebrew number.
        //      This is used by DateTime.ParseExact().
        //
        ////////////////////////////////////////////////////////////////////////

        internal static bool MatchHebrewDigits(ref __DTString str, int digitLen, out int number) {
            number = 0;

            // Create a context object so that we can parse the Hebrew number text character by character.
            HebrewNumberParsingContext context = new HebrewNumberParsingContext(0);

            // Set this to ContinueParsing so that we will run the following while loop in the first time.
            HebrewNumberParsingState state = HebrewNumberParsingState.ContinueParsing;

            while (state == HebrewNumberParsingState.ContinueParsing && str.GetNext()) {
                state = HebrewNumber.ParseByChar(str.GetChar(), ref context);
            }

            if (state == HebrewNumberParsingState.FoundEndOfHebrewNumber) {
                // If we have reached a terminal state, update the result and returns.
                number = context.result;
                return (true);
            }

            // If we run out of the character before reaching FoundEndOfHebrewNumber, or
            // the state is InvalidHebrewNumber or ContinueParsing, we fail to match a Hebrew number.
            // Return an error.
            return false;
        }
Пример #5
0
        /*=================================ParseSign==================================
        **Action: Parse a positive or a negative sign.
        **Returns:      true if postive sign.  flase if negative sign.
        **Arguments:    str: a __DTString.  The parsing will start from the
        **              next character after str.Index.
        **Exceptions:   FormatException if end of string is encountered or a sign
        **              symbol is not found.
        ==============================================================================*/

        private static bool ParseSign(ref __DTString str, ref bool result) {
            if (!str.GetNext()) {
                // A sign symbol ('+' or '-') is expected. However, end of string is encountered.
                return false;
            }
            char ch = str.GetChar();
            if (ch == '+') {
                result = true;
                return (true);
            } else if (ch == '-') {
                result = false;
                return (true);
            }
            // A sign symbol ('+' or '-') is expected.
            return 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;
		}
Пример #7
0
        /*=================================ParseSign==================================
        **Action: Parse a positive or a negative sign.
        **Returns:      true if postive sign.  flase if negative sign.
        **Arguments:    str: a __DTString.  The parsing will start from the
        **              next character after str.Index.
        **Exceptions:   FormatException if end of string is encountered or a sign
        **              symbol is not found.
        ==============================================================================*/

        private static bool ParseSign(__DTString str, bool isThrowExp, ref bool result) {
            if (!str.GetNext()) {
                // A sign symbol ('+' or '-') is expected. However, end of string is encountered.
                return (ParseFormatError(isThrowExp, "Format_BadDateTime"));    
            }
            char ch = str.GetChar();
            if (ch == '+') {
                result = true;
                return (true);
            } else if (ch == '-') {
                result = false;
                return (true);
            }
            // A sign symbol ('+' or '-') is expected.
            return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
        }
Пример #8
0
        private static bool ParseByFormat(ref __DTString str, ref __DTString format, ref ParsingInfo parseInfo, DateTimeFormatInfo dtfi, ref DateTimeResult result)
        {
            bool flag;
            int returnValue = 0;
            int num2 = 0;
            int num3 = 0;
            int num4 = 0;
            int num5 = 0;
            int num6 = 0;
            int num7 = 0;
            int num8 = 0;
            double num9 = 0.0;
            TM aM = TM.AM;
            char failureMessageFormatArgument = format.GetChar();
            switch (failureMessageFormatArgument)
            {
                case '%':
                    if ((format.Index < (format.Value.Length - 1)) && (format.Value[format.Index + 1] != '%'))
                    {
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
                    return false;

                case '\'':
                case '"':
                {
                    StringBuilder builder = new StringBuilder();
                    if (!TryParseQuoteString(format.Value, format.Index, builder, out returnValue))
                    {
                        result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadQuote", failureMessageFormatArgument);
                        return false;
                    }
                    format.Index += returnValue - 1;
                    string str2 = builder.ToString();
                    for (int i = 0; i < str2.Length; i++)
                    {
                        if ((str2[i] == ' ') && parseInfo.fAllowInnerWhite)
                        {
                            str.SkipWhiteSpaces();
                        }
                        else if (!str.Match(str2[i]))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                    }
                    if ((result.flags & ParseFlags.CaptureOffset) != 0)
                    {
                        if (((result.flags & ParseFlags.Rfc1123Pattern) != 0) && (str2 == "GMT"))
                        {
                            result.flags |= ParseFlags.TimeZoneUsed;
                            result.timeZoneOffset = TimeSpan.Zero;
                        }
                        else if (((result.flags & ParseFlags.UtcSortPattern) != 0) && (str2 == "Z"))
                        {
                            result.flags |= ParseFlags.TimeZoneUsed;
                            result.timeZoneOffset = TimeSpan.Zero;
                        }
                    }
                    goto Label_0A5A;
                }
                case '.':
                    if (!str.Match(failureMessageFormatArgument))
                    {
                        if (!format.GetNext() || !format.Match('F'))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                        format.GetRepeatCount();
                    }
                    goto Label_0A5A;

                case '/':
                    if (str.Match(dtfi.DateSeparator))
                    {
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case ':':
                    if (str.Match(dtfi.TimeSeparator))
                    {
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'F':
                case 'f':
                    returnValue = format.GetRepeatCount();
                    if (returnValue <= 7)
                    {
                        if (!ParseFractionExact(ref str, returnValue, ref num9) && (failureMessageFormatArgument == 'f'))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                        if (result.fraction >= 0.0)
                        {
                            if (num9 != result.fraction)
                            {
                                result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", failureMessageFormatArgument);
                                return false;
                            }
                        }
                        else
                        {
                            result.fraction = num9;
                        }
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'H':
                    returnValue = format.GetRepeatCount();
                    if (ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num6))
                    {
                        if (!CheckNewValue(ref result.Hour, num6, failureMessageFormatArgument, ref result))
                        {
                            return false;
                        }
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'K':
                    if (!str.Match('Z'))
                    {
                        if (str.Match('+') || str.Match('-'))
                        {
                            str.Index--;
                            TimeSpan span2 = new TimeSpan(0L);
                            if (!ParseTimeZoneOffset(ref str, 3, ref span2))
                            {
                                result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                                return false;
                            }
                            if (((result.flags & ParseFlags.TimeZoneUsed) != 0) && (span2 != result.timeZoneOffset))
                            {
                                result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K');
                                return false;
                            }
                            result.timeZoneOffset = span2;
                            result.flags |= ParseFlags.TimeZoneUsed;
                        }
                        goto Label_0A5A;
                    }
                    if (((result.flags & ParseFlags.TimeZoneUsed) == 0) || !(result.timeZoneOffset != TimeSpan.Zero))
                    {
                        result.flags |= ParseFlags.TimeZoneUsed;
                        result.timeZoneOffset = new TimeSpan(0L);
                        result.flags |= ParseFlags.TimeZoneUtc;
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K');
                    return false;

                case 'M':
                    returnValue = format.GetRepeatCount();
                    if (returnValue > 2)
                    {
                        if (returnValue == 3)
                        {
                            if (!MatchAbbreviatedMonthName(ref str, dtfi, ref num3))
                            {
                                result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                                return false;
                            }
                        }
                        else if (!MatchMonthName(ref str, dtfi, ref num3))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                        result.flags |= ParseFlags.ParsedMonthName;
                        goto Label_0223;
                    }
                    if (ParseDigits(ref str, returnValue, out num3) || (parseInfo.fCustomNumberParser && parseInfo.parseNumberDelegate(ref str, returnValue, out num3)))
                    {
                        goto Label_0223;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'Z':
                    if (((result.flags & ParseFlags.TimeZoneUsed) == 0) || !(result.timeZoneOffset != TimeSpan.Zero))
                    {
                        result.flags |= ParseFlags.TimeZoneUsed;
                        result.timeZoneOffset = new TimeSpan(0L);
                        result.flags |= ParseFlags.TimeZoneUtc;
                        str.Index++;
                        if (!GetTimeZoneName(ref str))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                        str.Index--;
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'Z');
                    return false;

                case '\\':
                    if (!format.GetNext())
                    {
                        result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
                        return false;
                    }
                    if (str.Match(format.GetChar()))
                    {
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'd':
                    returnValue = format.GetRepeatCount();
                    if (returnValue > 2)
                    {
                        if (returnValue == 3)
                        {
                            if (!MatchAbbreviatedDayName(ref str, dtfi, ref num5))
                            {
                                result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                                return false;
                            }
                        }
                        else if (!MatchDayName(ref str, dtfi, ref num5))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                        if (!CheckNewValue(ref parseInfo.dayOfWeek, num5, failureMessageFormatArgument, ref result))
                        {
                            return false;
                        }
                        goto Label_0A5A;
                    }
                    if (ParseDigits(ref str, returnValue, out num4) || (parseInfo.fCustomNumberParser && parseInfo.parseNumberDelegate(ref str, returnValue, out num4)))
                    {
                        if (!CheckNewValue(ref result.Day, num4, failureMessageFormatArgument, ref result))
                        {
                            return false;
                        }
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'g':
                    returnValue = format.GetRepeatCount();
                    if (MatchEraName(ref str, dtfi, ref result.era))
                    {
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'h':
                    parseInfo.fUseHour12 = true;
                    returnValue = format.GetRepeatCount();
                    if (ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num6))
                    {
                        if (!CheckNewValue(ref result.Hour, num6, failureMessageFormatArgument, ref result))
                        {
                            return false;
                        }
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 's':
                    returnValue = format.GetRepeatCount();
                    if (ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num8))
                    {
                        if (!CheckNewValue(ref result.Second, num8, failureMessageFormatArgument, ref result))
                        {
                            return false;
                        }
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 't':
                    if (format.GetRepeatCount() != 1)
                    {
                        if (!MatchTimeMark(ref str, dtfi, ref aM))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                        goto Label_04DE;
                    }
                    if (MatchAbbreviatedTimeMark(ref str, dtfi, ref aM))
                    {
                        goto Label_04DE;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;

                case 'm':
                    returnValue = format.GetRepeatCount();
                    if (!ParseDigits(ref str, (returnValue < 2) ? 1 : 2, out num7))
                    {
                        result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                        return false;
                    }
                    if (CheckNewValue(ref result.Minute, num7, failureMessageFormatArgument, ref result))
                    {
                        goto Label_0A5A;
                    }
                    return false;

                case 'y':
                    returnValue = format.GetRepeatCount();
                    if (!dtfi.HasForceTwoDigitYears)
                    {
                        if (returnValue <= 2)
                        {
                            parseInfo.fUseTwoDigitYear = true;
                        }
                        flag = ParseDigits(ref str, returnValue, out num2);
                        break;
                    }
                    flag = ParseDigits(ref str, 1, 4, out num2);
                    break;

                case 'z':
                {
                    returnValue = format.GetRepeatCount();
                    TimeSpan span = new TimeSpan(0L);
                    if (ParseTimeZoneOffset(ref str, returnValue, ref span))
                    {
                        if (((result.flags & ParseFlags.TimeZoneUsed) != 0) && (span != result.timeZoneOffset))
                        {
                            result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'z');
                            return false;
                        }
                        result.timeZoneOffset = span;
                        result.flags |= ParseFlags.TimeZoneUsed;
                        goto Label_0A5A;
                    }
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;
                }
                default:
                    if (failureMessageFormatArgument == ' ')
                    {
                        if (!parseInfo.fAllowInnerWhite && !str.Match(failureMessageFormatArgument))
                        {
                            if ((parseInfo.fAllowTrailingWhite && format.GetNext()) && ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result))
                            {
                                return true;
                            }
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                    }
                    else if (format.MatchSpecifiedWord("GMT"))
                    {
                        format.Index += "GMT".Length - 1;
                        result.flags |= ParseFlags.TimeZoneUsed;
                        result.timeZoneOffset = TimeSpan.Zero;
                        if (!str.Match("GMT"))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                    }
                    else if (!str.Match(failureMessageFormatArgument))
                    {
                        result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                        return false;
                    }
                    goto Label_0A5A;
            }
            if (!flag && parseInfo.fCustomNumberParser)
            {
                flag = parseInfo.parseNumberDelegate(ref str, returnValue, out num2);
            }
            if (!flag)
            {
                result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                return false;
            }
            if (CheckNewValue(ref result.Year, num2, failureMessageFormatArgument, ref result))
            {
                goto Label_0A5A;
            }
            return false;
        Label_0223:
            if (CheckNewValue(ref result.Month, num3, failureMessageFormatArgument, ref result))
            {
                goto Label_0A5A;
            }
            return false;
        Label_04DE:
            if (parseInfo.timeMark == TM.NotSet)
            {
                parseInfo.timeMark = aM;
            }
            else if (parseInfo.timeMark != aM)
            {
                result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", failureMessageFormatArgument);
                return false;
            }
        Label_0A5A:
            return true;
        }
Пример #9
0
        private static bool ParseISO8601(ref DateTimeRawInfo raw, ref __DTString str, DateTimeStyles styles, ref DateTimeResult result)
        {
            int num;
            int num2;
            DateTime time;
            if ((raw.year >= 0) && (raw.GetNumber(0) >= 0))
            {
                raw.GetNumber(1);
            }
            str.Index--;
            int num3 = 0;
            double num4 = 0.0;
            str.SkipWhiteSpaces();
            if (!ParseDigits(ref str, 2, out num))
            {
                result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                return false;
            }
            str.SkipWhiteSpaces();
            if (!str.Match(':'))
            {
                result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                return false;
            }
            str.SkipWhiteSpaces();
            if (!ParseDigits(ref str, 2, out num2))
            {
                result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                return false;
            }
            str.SkipWhiteSpaces();
            if (str.Match(':'))
            {
                str.SkipWhiteSpaces();
                if (!ParseDigits(ref str, 2, out num3))
                {
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;
                }
                if (str.Match('.'))
                {
                    if (!ParseFraction(ref str, out num4))
                    {
                        result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                        return false;
                    }
                    str.Index--;
                }
                str.SkipWhiteSpaces();
            }
            if (str.GetNext())
            {
                switch (str.GetChar())
                {
                    case '+':
                    case '-':
                        result.flags |= ParseFlags.TimeZoneUsed;
                        if (!ParseTimeZone(ref str, ref result.timeZoneOffset))
                        {
                            result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                            return false;
                        }
                        break;

                    case 'Z':
                    case 'z':
                        result.flags |= ParseFlags.TimeZoneUsed;
                        result.timeZoneOffset = TimeSpan.Zero;
                        result.flags |= ParseFlags.TimeZoneUtc;
                        break;

                    default:
                        str.Index--;
                        break;
                }
                str.SkipWhiteSpaces();
                if (str.Match('#'))
                {
                    if (!VerifyValidPunctuation(ref str))
                    {
                        result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                        return false;
                    }
                    str.SkipWhiteSpaces();
                }
                if (str.Match('\0') && !VerifyValidPunctuation(ref str))
                {
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;
                }
                if (str.GetNext())
                {
                    result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
                    return false;
                }
            }
            if (!GregorianCalendar.GetDefaultInstance().TryToDateTime(raw.year, raw.GetNumber(0), raw.GetNumber(1), num, num2, num3, 0, result.era, out time))
            {
                result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
                return false;
            }
            time = time.AddTicks((long) Math.Round((double) (num4 * 10000000.0)));
            result.parsedDate = time;
            if (!DetermineTimeZoneAdjustments(ref result, styles, false))
            {
                return false;
            }
            return true;
        }
Пример #10
0
        /*=================================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 TimeSpan ParseTimeZone(__DTString str, char offsetChar) {
            // The hour/minute offset for timezone.
            int hourOffset = 0;
            int minuteOffset = 0;
            
            if (str.GetNextDigit()) {
                // Get the first digit, Try if we can parse timezone in the form of "+8".
                hourOffset = str.GetDigit();
                if (str.GetNextDigit()) {
                    // Parsing "+18"
                    hourOffset *= 10;
                    hourOffset += str.GetDigit();
                    if (str.GetNext()) {
                        char ch;
                        if (Char.IsDigit(ch = str.GetChar())) {
                            // Parsing "+1800"

                            // Put the char back, since we already get the char in the previous GetNext() call.
                            str.Index--;
                            if (ParseDigits(str, 2, true, out minuteOffset)) {
                                // ParseDigits() does not advance the char for us, so do it here.
                                str.Index++;
                            } else {
                                throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                            }
                        } else if (ch == ':') {   
                            // Parsing "+18:00"
                            if (ParseDigits(str, 2, true, out minuteOffset)) {
                                str.Index++;
                            } else {
                                throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                            }
                        } else {
                            // Not a digit, not a colon, put this char back.
                            str.Index--;
                        }
                    }
                }
                // The next char is not a digit, so we get the timezone in the form of "+8".
            } else {
                // Invalid timezone: No numbers after +/-.
                throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
            }
            TimeSpan timezoneOffset = new TimeSpan(hourOffset, minuteOffset, 0);
            if (offsetChar == '-') {
                timezoneOffset = timezoneOffset.Negate();
            }
            return (timezoneOffset);
        }
Пример #11
0
        //
        // This is the lexer. Check the character at the current index, and put the found token in dtok and
        // some raw date/time information in raw.
        //
        private static void Lex(
            int dps, __DTString str, DateTimeToken dtok, DateTimeRawInfo raw, DateTimeResult result, ref DateTimeFormatInfo dtfi) {
            
            int sep;
            dtok.dtt = DTT_Unk;     // Assume the token is unkown.

            //
            // Skip any white spaces.
            //
            if (!str.SkipWhiteSpaceComma()) {
                //
                // SkipWhiteSpaceComma() will return true when end of string is reached.
                //
                dtok.dtt = DTT_End;
                return;
            }

            char ch = str.GetChar();
            if (Char.IsLetter(ch))
            {
                //
                // This is a letter.
                //

                int month, dayOfWeek, era, timeMark;

                //
                // Check if this is a beginning of a month name.
                // And check if this is a day of week name.
                //
                if (raw.month == -1 && (month = GetMonthNumber(str, dtfi)) >= 1)
                {
                    //
                    // This is a month name
                    //
                    switch(sep=GetSeparator(str, raw, dtfi))
                    {
                        case SEP_End:
                            dtok.dtt = DTT_MonthEnd;
                            break;
                        case SEP_Space:
                            dtok.dtt = DTT_MonthSpace;
                            break;
                        case SEP_Date:
                            dtok.dtt = DTT_MonthDatesep;
                            break;
                        default:
                            //Invalid separator after month name
                            throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                    }
                    raw.month = month;
                }
                else if (raw.dayOfWeek == -1 && (dayOfWeek = GetDayOfWeekNumber(str, dtfi)) >= 0)
                {
                    //
                    // This is a day of week name.
                    //
                    raw.dayOfWeek = dayOfWeek;
                    dtok.dtt = DTT_DayOfWeek;
                    //
                    // Discard the separator.
                    //
                    GetSeparator(str, raw, dtfi);
                }
                else if (GetTimeZoneName(str))
                {
                    //
                    // This is a timezone designator
                    //
                    // NOTENOTE                     : for now, we only support "GMT" and "Z" (for Zulu time).
                    //
                    dtok.dtt = DTT_TimeZone;
                    result.timeZoneUsed = true;
                    result.timeZoneOffset = new TimeSpan(0);
                } else if ((raw.era == -1) && ((era = GetEra(str, result, ref dtfi)) != -1)) {
                    raw.era = era;
                    dtok.dtt = DTT_Era;
                } else if (raw.timeMark == -1 && (timeMark = GetTimeMark(str, dtfi)) != -1) {
                    raw.timeMark = timeMark;
                    GetSeparator(str, raw, dtfi);
                } else {
                    //
                    // Not a month name, not a day of week name. Check if this is one of the
                    // known date words. This is used to deal case like Spanish cultures, which
                    // uses 'de' in their Date string.
                    // 
                    //                    
                    if (!str.MatchWords(dtfi.DateWords)) {
                        throw new FormatException(
                            String.Format(Environment.GetResourceString("Format_UnknowDateTimeWord"), str.Index));
                    }                    
                    GetSeparator(str, raw, dtfi);                    
                }
            } else if (Char.IsDigit(ch)) {
                if (raw.numCount == 3) {
                    throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                }
                //
                // This is a digit.
                //
                int number = ch - '0';

                int digitCount = 1;

                //
                // Collect other digits.
                //
                while (str.GetNextDigit())
                {
                    number = number * 10 + str.GetDigit();
                    digitCount++;
                }

                // 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:02).
                //
                // 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 || dps == DS_T_Nt) {
                    char nextCh;
                    if ((str.Index < str.len - 1)) {
                        nextCh = str.Value[str.Index];
                        switch (nextCh) {                        
                            case '.':
                                if (dps == DS_T_NNt) {
                                    // Yes, advance to the next character.
                                    str.Index++;
                                    // Collect the second fraction.
                                    raw.fraction = ParseFraction(str);
                                }
                                break;
                            case '+':
                            case '-':
                                if (result.timeZoneUsed) {
                                    // Should not have two timezone offsets.
                                    throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                                }
                                result.timeZoneUsed = true;
                                result.timeZoneOffset = ParseTimeZone(str, nextCh);
                                break;
                        }
                    }
                }
                
                if (number >= 0)
                {
                    dtok.num = number;
                    if (digitCount >= 3)
                    {
                        if (raw.year == -1)
                        {
                            raw.year = number;
                            //
                            // 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 = GetSeparator(str, raw, dtfi))
                            {
                                case SEP_End:
                                    dtok.dtt     = DTT_YearEnd;
                                    break;
                                case SEP_Am:
                                case SEP_Pm:
                                case SEP_Space:
                                    dtok.dtt    = DTT_YearSpace;
                                    break;
                                case SEP_Date:
                                    dtok.dtt     = DTT_YearDateSep;
                                    break;
                                case SEP_YearSuff:
                                case SEP_MonthSuff:
                                case SEP_DaySuff:
                                    dtok.dtt    = DTT_NumDatesuff;
                                    dtok.suffix = sep;
                                    break;
                                case SEP_HourSuff:
                                case SEP_MinuteSuff:
                                case SEP_SecondSuff:
                                    dtok.dtt    = DTT_NumTimesuff;
                                    dtok.suffix = sep;
                                    break;
                                default:
                                    // Invalid separator after number number.
                                    throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                            }
                            //
                            // Found the token already. Let's bail.
                            //
                            return;
                        }
                        throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                    }
                } else
                {
                    //
                    // number is overflowed.
                    //
                    throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                }

                switch (sep = GetSeparator(str, raw, dtfi))
                {
                    //
                    // 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 SEP_End:
                        dtok.dtt = DTT_NumEnd;
                        raw.num[raw.numCount++] = dtok.num;
                        break;
                    case SEP_Am:
                    case SEP_Pm:
                        dtok.dtt = DTT_NumAmpm;
                        raw.num[raw.numCount++] = dtok.num;
                        break;
                    case SEP_Space:
                        dtok.dtt = DTT_NumSpace;
                        raw.num[raw.numCount++] = dtok.num;
                        break;
                    case SEP_Date:
                        dtok.dtt = DTT_NumDatesep;
                        raw.num[raw.numCount++] = dtok.num;
                        break;
                    case SEP_Time:
                        if (!result.timeZoneUsed) {
                            dtok.dtt = DTT_NumTimesep;
                            raw.num[raw.numCount++] = dtok.num;
                        } else {
                            // If we already got timezone, there should be no
                            // time separator again.
                            throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                        }
                        break;
                    case SEP_YearSuff:
                        dtok.num = dtfi.Calendar.ToFourDigitYear(number);
                        dtok.dtt    = DTT_NumDatesuff;
                        dtok.suffix = sep;
                        break;
                    case SEP_MonthSuff:
                    case SEP_DaySuff:
                        dtok.dtt    = DTT_NumDatesuff;
                        dtok.suffix = sep;
                        break;
                    case SEP_HourSuff:
                    case SEP_MinuteSuff:
                    case SEP_SecondSuff:
                        dtok.dtt    = DTT_NumTimesuff;
                        dtok.suffix = sep;
                        break;
                    case SEP_LocalTimeMark:
                        dtok.dtt = DTT_NumLocalTimeMark;
                        raw.num[raw.numCount++] = dtok.num;
                        break;
                    default:
                        // Invalid separator after number number.
                        throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));
                }
            }
            else
            {
                //
                // Not a letter, not a digit. Just ignore it.
                //
                str.Index++;
            }
            return;
        }
Пример #12
0
        //
        // Starting at str.Index, check the type of the separator.
        //
        private static int GetSeparator(__DTString str, DateTimeRawInfo raw, DateTimeFormatInfo dtfi) {
            int separator = SEP_Space;  // Assume the separator is a space. And try to find a better one.

            //
            // Check if we found any white spaces.
            //
            if (!str.SkipWhiteSpaceComma()) {
                //
                // SkipWhiteSpaceComma() will return true when end of string is reached.
                //

                //
                // Return the separator as SEP_End.
                //
                return (SEP_End);
            }

            if (Char.IsLetter(str.GetChar())) {
                //
                // This is a beginning of a word.
                //
                if (raw.timeMark == -1)
                {
                    //
                    // Check if this is an AM time mark.
                    //
                    int timeMark;
                    if ((timeMark = GetTimeMark(str, dtfi)) != -1)
                    {
                        raw.timeMark = timeMark;;
                        return (timeMark == TM_AM ? SEP_Am: SEP_Pm);
                    }
                }
                if (MatchWord(str, LocalTimeMark, false)) {
                    separator = SEP_LocalTimeMark;
                } else if (MatchWord(str, CJKYearSuff, false) || MatchWord(str, KoreanYearSuff, false)) {
                    separator = SEP_YearSuff;
                }
                else if (MatchWord(str, CJKMonthSuff, false) || MatchWord(str, KoreanMonthSuff, false))
                {
                    separator = SEP_MonthSuff;
                }
                else if (MatchWord(str, CJKDaySuff, false) || MatchWord(str, KoreanDaySuff, false))
                {
                    separator = SEP_DaySuff;
                }
                else if (MatchWord(str, CJKHourSuff, false) || MatchWord(str, ChineseHourSuff, false))
                {
                    separator = SEP_HourSuff;
                }
                else if (MatchWord(str, CJKMinuteSuff, false))
                {
                    separator = SEP_MinuteSuff;
                }
                else if (MatchWord(str, CJKSecondSuff, false))
                {
                    separator = SEP_SecondSuff;
                }
            } else {
                //
                // Not a letter. Check if this is a date separator.
                //
                if ((MatchWord(str, dtfi.DateSeparator, false)) ||
                    (MatchWord(str, invariantInfo.DateSeparator, false)) ||
                    (MatchWord(str, alternativeDateSeparator, false)))
                {
                    //
                    // NOTENOTE                     : alternativeDateSeparator is a special case because some cultures
                    //  (e.g. the invariant culture) use "/". However, in RFC format, we use "-" as the
                    // date separator.  Therefore, we should check for it.
                    //
                    separator = SEP_Date;
                }
                //
                // Check if this is a time separator.
                //
                else if ((MatchWord(str, dtfi.TimeSeparator, false)) ||
                         (MatchWord(str, invariantInfo.TimeSeparator, false)))
                {
                    separator = SEP_Time;
                } else if (dtfi.CultureID == 0x041c) {
                    // Special case for sq-AL (0x041c)
                    // Its time pattern is "h:mm:ss.tt"
                    if (str.GetChar() == '.') {
                        if (raw.timeMark == -1)
                        {
                            //
                            // Check if this is an AM time mark.
                            //
                            int timeMark;
                            str.Index++;
                            if ((timeMark = GetTimeMark(str, dtfi)) != -1)
                            {
                                raw.timeMark = timeMark;;
                                return (timeMark == TM_AM ? SEP_Am: SEP_Pm);
                            }
                            str.Index--;
                        }                        
                    }
                }
            }
                            
            return (separator);
        }
Пример #13
0
        // Given a specified format character, parse and update the parsing result.
        //
        private static bool ParseByFormat(
            __DTString str, 
            __DTString format, 
            ParsingInfo parseInfo, 
            DateTimeFormatInfo dtfi,
            bool isThrowExp,
            DateTimeResult result) {
            
            int tokenLen = 0;
            int tempYear = 0, tempMonth = 0, tempDay = 0, tempDayOfWeek = 0, tempHour = 0, tempMinute = 0, tempSecond = 0;
            double tempFraction = 0;
            int tempTimeMark = 0;
            
            char ch = format.GetChar();
            
            switch (ch) {
                case 'y':
                    tokenLen = format.GetRepeatCount();
                    if (tokenLen <= 2) {
                        parseInfo.fUseTwoDigitYear = true;
                    }
                    if (!ParseDigits(str, tokenLen, isThrowExp, out tempYear)) {
                        return (false);
                    }                    
                    if (!CheckNewValue(ref result.Year, tempYear, ch, isThrowExp)) {
                        return (false);
                    }
                    break;
                case 'M':
                    tokenLen = format.GetRepeatCount();
                    if (tokenLen <= 2) {
                        if (!ParseDigits(str, tokenLen, isThrowExp, out tempMonth)) {
                            return (false);
                        }
                    } else {
                        if (tokenLen == 3) {
                            if (!MatchAbbreviatedMonthName(str, dtfi, isThrowExp, ref tempMonth)) {
                                return (false);
                            }
                        } else {
                            if (!MatchMonthName(str, dtfi, isThrowExp, ref tempMonth)) {
                                return (false);
                            }
                        }
                    }
                    if (!CheckNewValue(ref result.Month, tempMonth, ch, isThrowExp)) {
                        return (false);
                    }
                    break;
                case 'd':
                    // Day & Day of week
                    tokenLen = format.GetRepeatCount();
                    if (tokenLen <= 2) {
                        // "d" & "dd"
                        if (!ParseDigits(str, tokenLen, isThrowExp, out tempDay)) {
                            return (false);
                        }
                        if (!CheckNewValue(ref result.Day, tempDay, ch, isThrowExp)) {
                            return (false);
                        }
                    } else {
                        if (tokenLen == 3) {
                            // "ddd"
                            if (!MatchAbbreviatedDayName(str, dtfi, isThrowExp, ref tempDayOfWeek)) {
                                return (false);
                            }
                        } else {
                            // "dddd*"
                            if (!MatchDayName(str, dtfi, isThrowExp, ref tempDayOfWeek)) {
                                return (false);
                            }
                        }
                        if (!CheckNewValue(ref parseInfo.dayOfWeek, tempDayOfWeek, ch, isThrowExp)) {
                            return (false);
                        }
                    }
                    break;
                case 'g':
                    tokenLen = format.GetRepeatCount();
                    // Put the era value in result.era.
                    if (!MatchEraName(str, dtfi, isThrowExp, ref result.era)) {
                        return (false);
                    }
                    break;
                case 'h':
                    parseInfo.fUseHour12 = true;
                    tokenLen = format.GetRepeatCount();
                    if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempHour)) {
                        return (false);
                    }
                    if (!CheckNewValue(ref result.Hour, tempHour, ch, isThrowExp)) {
                        return (false);
                    }
                    break;
                case 'H':
                    tokenLen = format.GetRepeatCount();
                    if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempHour)) {
                        return (false);
                    }
                    if (!CheckNewValue(ref result.Hour, tempHour, ch, isThrowExp)) {
                        return (false);
                    }
                    break;
                case 'm':
                    tokenLen = format.GetRepeatCount();
                    if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempMinute)) {
                        return (false);
                    }
                    if (!CheckNewValue(ref result.Minute, tempMinute, ch, isThrowExp)) {
                        return (false);
                    }
                    break;
                case 's':
                    tokenLen = format.GetRepeatCount();
                    if (!ParseDigits(str, (tokenLen < 2? 1 : 2), isThrowExp, out tempSecond)) {
                        return (false);
                    }
                    if (!CheckNewValue(ref result.Second, tempSecond, ch, isThrowExp)) {
                        return (false);
                    }
                    break;
                case 'f':
                    tokenLen = format.GetRepeatCount();
                    if (tokenLen <= DateTimeFormat.MaxSecondsFractionDigits) {
                        if (!ParseFractionExact(str, tokenLen, isThrowExp, ref tempFraction)) {
                            return (false);
                        }
                        if (result.fraction < 0) {
                            result.fraction = tempFraction;
                        } else {
                            if (tempFraction != result.fraction) {
                                if (isThrowExp) {
                                    throw new ArgumentException(
                                        String.Format(Environment.GetResourceString("Format_RepeatDateTimePattern"), ch), "str");
                                } else {
                                    return (false);
                                }
                            }                                        
                        }
                    } else {
                        return ParseFormatError(isThrowExp, "Format_BadDateTime");
                    }
                    break;
                case 't':
                    // AM/PM designator
                    tokenLen = format.GetRepeatCount();
                    if (tokenLen == 1) {
                        if (!MatchAbbreviatedTimeMark(str, dtfi, isThrowExp, ref tempTimeMark)) {
                            return (false);
                        }
                    } else {                        
                        if (!MatchTimeMark(str, dtfi, isThrowExp, ref tempTimeMark)) {
                            return (false);
                        }
                    }

                    if (!CheckNewValue(ref parseInfo.timeMark, tempTimeMark, ch, isThrowExp)) {
                        return (false);
                    }
                    break;
                case 'z':
                    // timezone offset
                    if (parseInfo.fUseTimeZone) {
                        throw new ArgumentException(Environment.GetResourceString("Argument_TwoTimeZoneSpecifiers"), "str");
                    }
                    parseInfo.fUseTimeZone = true;
                    tokenLen = format.GetRepeatCount();
                    if (!ParseTimeZoneOffset(str, tokenLen, isThrowExp, ref parseInfo.timeZoneOffset)) {
                        return (false);
                    }                    
                    break;
                case 'Z':
                    if (parseInfo.fUseTimeZone) {
                        throw new ArgumentException(Environment.GetResourceString("Argument_TwoTimeZoneSpecifiers"), "str");
                    }
                    parseInfo.fUseTimeZone = true;
                    parseInfo.timeZoneOffset = new TimeSpan(0);

                    str.Index++;
                    if (!GetTimeZoneName(str)) {
                        BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): 'Z' or 'GMT' are expected");
                        return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
                    }
                    break;
                case ':':
                    if (!str.Match(dtfi.TimeSeparator)) {
                        // A time separator is expected.
                        BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): ':' is expected");
                        return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
                    }
                    break;
                case '/':
                    if (!str.Match(dtfi.DateSeparator)) {
                        // A date separator is expected.
                        BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): date separator is expected");
                        return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
                    }
                    break;
                case '\"':
                case '\'':
                    StringBuilder enquotedString = new StringBuilder();
                    try {
                        // Use ParseQuoteString so that we can handle escape characters within the quoted string.
                        tokenLen = DateTimeFormat.ParseQuoteString(format.Value, format.Index, enquotedString); 
                    } catch (Exception) {
                        if (isThrowExp) { 
                            throw new FormatException(String.Format(Environment.GetResourceString("Format_BadQuote"), ch));
                        } else {
                            return (false);
                        }
                    }
                    format.Index += tokenLen - 1;                    
                    
                    // Some cultures uses space in the quoted string.  E.g. Spanish has long date format as:
                    // "dddd, dd' de 'MMMM' de 'yyyy".  When inner spaces flag is set, we should skip whitespaces if there is space
                    // in the quoted string.
                    String quotedStr = enquotedString.ToString();
                    for (int i = 0; i < quotedStr.Length; i++) {
                        if (quotedStr[i] == ' ' && parseInfo.fAllowInnerWhite) {
                            str.SkipWhiteSpaces();
                        } else if (!str.Match(quotedStr[i])) {
                            // Can not find the matching quoted string.
                            BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse():Quote string doesn't match");
                            return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
                        }
                    }
                    break;
                case '%':
                    // Skip this so we can get to the next pattern character.
                    // Used in case like "%d", "%y"

                    // Make sure the next character is not a '%' again.
                    if (format.Index >= format.Value.Length - 1 || format.Value[format.Index + 1] == '%') {
                        BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse():%% is not permitted");
                        return (ParseFormatError(isThrowExp, "Format_BadFormatSpecifier"));
                    }
                    break;
                case '\\':
                    // Escape character. For example, "\d".
                    // Get the next character in format, and see if we can
                    // find a match in str.
                    if (format.GetNext()) {
                        if (!str.Match(format.GetChar())) {
                            // Can not find a match for the escaped character.
                            BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): Can not find a match for the escaped character");
                            return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
                        }
                    } else {
                        BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): \\ is at the end of the format string");
                        return (ParseFormatError(isThrowExp, "Format_BadFormatSpecifier"));
                    }
                    break;
                default:
                    if (ch == ' ') {
                        if (parseInfo.fAllowInnerWhite) {
                            // Skip whitespaces if AllowInnerWhite.
                            // Do nothing here.
                        } else {
                            if (!str.Match(ch)) {
                                // If the space does not match, and trailing space is allowed, we do
                                // one more step to see if the next format character can lead to
                                // successful parsing.
                                // This is used to deal with special case that a empty string can match
                                // a specific pattern.
                                // The example here is af-ZA, which has a time format like "hh:mm:ss tt".  However,
                                // its AM symbol is "" (empty string).  If fAllowTrailingWhite is used, and time is in 
                                // the AM, we will trim the whitespaces at the end, which will lead to a failure
                                // when we are trying to match the space before "tt".                                
                                if (parseInfo.fAllowTrailingWhite) {
                                    if (format.GetNext()) {
                                        if (ParseByFormat(str, format, parseInfo, dtfi, isThrowExp, result)) {
                                            return (true);
                                        }
                                    }
                                }
                                return (ParseFormatError(isThrowExp, "Format_BadDateTime")); 
                            }
                            // Found a macth.
                        }
                    } else {
                        if (format.MatchSpecifiedWord(GMTName)) {
                            format.Index += (GMTName.Length - 1);
                            // Found GMT string in format.  This means the DateTime string
                            // is in GMT timezone.
                            parseInfo.fUseTimeZone = true;
                            if (!str.Match(GMTName)) {
                                BCLDebug.Trace("NLS", "DateTimeParse.DoStrictParse(): GMT in format, but not in str");
                                return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
                            }
                        } else if (!str.Match(ch)) {
                            // ch is expected.
                            BCLDebug.Trace ("NLS", "DateTimeParse.DoStrictParse(): '", ch, "' is expected");
                            return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
                        }
                    }
                    break;
            } // switch
            return (true);
        }
Пример #14
0
        /*=================================MatchAbbreviatedTimeMark==================================
        **Action: Parse the abbreviated time mark (AM/PM) from string starting at str.Index.
        **Returns: TM_AM or TM_PM.
        **Arguments:    str: a __DTString.  The parsing will start from the
        **              next character after str.Index.
        **Exceptions: FormatException if a abbreviated time mark can not be found.
        ==============================================================================*/

        private static bool MatchAbbreviatedTimeMark(__DTString str, DateTimeFormatInfo dtfi, bool isThrowExp, ref int result) {
            // NOTENOTE                     : the assumption here is that abbreviated time mark is the first
            // character of the AM/PM designator.  If this invariant changes, we have to
            // change the code below.
            if (str.GetNext())
            {
                if (str.GetChar() == dtfi.AMDesignator[0]) {
                    result = TM_AM;
                    return (true);
                }
                if (str.GetChar() == dtfi.PMDesignator[0]) {                
                    result = TM_PM;
                    return (true);
                }
            }
            return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
        }
		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;
		}
Пример #16
0
        private static bool ParseSign(ref __DTString str, ref bool result)
        {
            if (str.GetNext())
            {
                switch (str.GetChar())
                {
                    case '+':
                        result = true;
                        return true;

                    case '-':
                        result = false;
                        return true;
                }
            }
            return false;
        }
		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;
		}
Пример #18
0
        //
        // 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 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;
		}
Пример #20
0
 //
 // Parse the ISO8601 format string found during Parse();
 // 
 //
 private static DateTime ParseISO8601(DateTimeRawInfo raw, __DTString str, DateTimeStyles styles) {
     if (raw.year < 0 || raw.num[0] < 0 || raw.num[1] < 0) {
     }
     str.Index--;
     int hour, minute, second;
     bool timeZoneUsed = false;
     TimeSpan timeZoneOffset = new TimeSpan();
     DateTime time = new DateTime(0);
     double partSecond = 0;
     
     str.SkipWhiteSpaces();            
     ParseDigits(str, 2, true, out hour);
     str.SkipWhiteSpaces();
     if (str.Match(':')) {
         str.SkipWhiteSpaces();
         ParseDigits(str, 2, true, out minute);    
         str.SkipWhiteSpaces();
         if (str.Match(':')) {
             str.SkipWhiteSpaces();
             ParseDigits(str, 2, true, out second);    
             str.SkipWhiteSpaces();
             
             if (str.GetNext()) {
                 char ch = str.GetChar();
                 if (ch == '+' || ch == '-') {
                     timeZoneUsed = true;
                     timeZoneOffset = ParseTimeZone(str, str.GetChar());
                 } else if (ch == '.') {
                     str.Index++;  //ParseFraction requires us to advance to the next character.
                     partSecond = ParseFraction(str); 
                 } else if (ch == 'Z' || ch == 'z') {
                     timeZoneUsed = true;
                 } else {
                     throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));            
                 }
             }
             
             time =new DateTime(raw.year, raw.num[0], raw.num[1], hour, minute, second);
             time = time.AddTicks((long)Math.Round(partSecond * Calendar.TicksPerSecond));
             if (timeZoneUsed) {
                 time = AdjustTimeZone(time, timeZoneOffset, styles, false);
             }
             
             return time;
         }
     }
     throw new FormatException(Environment.GetResourceString("Format_BadDateTime"));            
 }