Beispiel #1
0
            private ParseResult <LocalTime> DetermineHour(PatternFields usedFields, string text, out int hour)
            {
                hour = 0;
                if (usedFields.HasAny(PatternFields.Hours24))
                {
                    if (usedFields.HasAll(PatternFields.Hours12 | PatternFields.Hours24))
                    {
                        if (Hours12 % 12 != Hours24 % 12)
                        {
                            return(ParseResult <LocalTime> .InconsistentValues(text, 'H', 'h'));
                        }
                    }
                    if (usedFields.HasAny(PatternFields.AmPm))
                    {
                        if (Hours24 / 12 != AmPm)
                        {
                            return(ParseResult <LocalTime> .InconsistentValues(text, 'H', 't'));
                        }
                    }
                    hour = Hours24;
                    return(null);
                }
                // Okay, it's definitely valid - but we've still got 8 possibilities for what's been specified.
                switch (usedFields & (PatternFields.Hours12 | PatternFields.AmPm))
                {
                case PatternFields.Hours12 | PatternFields.AmPm:
                    hour = (Hours12 % 12) + AmPm * 12;
                    break;

                case PatternFields.Hours12:
                    // Preserve AM/PM from template value
                    hour = (Hours12 % 12) + (TemplateValue.Hour / 12) * 12;
                    break;

                case PatternFields.AmPm:
                    // Preserve 12-hour hour of day from template value, use specified AM/PM
                    hour = (TemplateValue.Hour % 12) + AmPm * 12;
                    break;

                case 0:
                    hour = TemplateValue.Hour;
                    break;
                }
                return(null);
            }
Beispiel #2
0
            /// <summary>
            /// Calculates the value from the parsed pieces.
            /// </summary>
            internal override ParseResult <LocalTime> CalculateValue(PatternFields usedFields, string text)
            {
                if (usedFields.HasAny(PatternFields.EmbeddedTime))
                {
                    return(ParseResult <LocalTime> .ForValue(LocalTime.FromHourMinuteSecondNanosecond(Hours24, Minutes, Seconds, FractionalSeconds)));
                }
                if (AmPm == 2)
                {
                    AmPm = TemplateValue.Hour / 12;
                }
                ParseResult <LocalTime> failure = DetermineHour(usedFields, text, out int hour);

                if (failure != null)
                {
                    return(failure);
                }
                int minutes  = usedFields.HasAny(PatternFields.Minutes) ? Minutes : TemplateValue.Minute;
                int seconds  = usedFields.HasAny(PatternFields.Seconds) ? Seconds : TemplateValue.Second;
                int fraction = usedFields.HasAny(PatternFields.FractionalSeconds) ? FractionalSeconds : TemplateValue.NanosecondOfSecond;

                return(ParseResult <LocalTime> .ForValue(LocalTime.FromHourMinuteSecondNanosecond(hour, minutes, seconds, fraction)));
            }
Beispiel #3
0
            internal override ParseResult <LocalDate> CalculateValue(PatternFields usedFields, string text)
            {
                if (usedFields.HasAny(PatternFields.EmbeddedDate))
                {
                    return(ParseResult <LocalDate> .ForValue(new LocalDate(Year, MonthOfYearNumeric, DayOfMonth, Calendar)));
                }
                // This will set Year if necessary
                ParseResult <LocalDate> failure = DetermineYear(usedFields, text);

                if (failure != null)
                {
                    return(failure);
                }
                // This will set MonthOfYearNumeric if necessary
                failure = DetermineMonth(usedFields, text);
                if (failure != null)
                {
                    return(failure);
                }

                int day = usedFields.HasAny(PatternFields.DayOfMonth) ? DayOfMonth : TemplateValue.Day;

                if (day > Calendar.GetDaysInMonth(Year, MonthOfYearNumeric))
                {
                    return(ParseResult <LocalDate> .DayOfMonthOutOfRange(text, day, MonthOfYearNumeric, Year));
                }

                LocalDate value = new LocalDate(Year, MonthOfYearNumeric, day, Calendar);

                if (usedFields.HasAny(PatternFields.DayOfWeek) && DayOfWeek != value.DayOfWeek)
                {
                    return(ParseResult <LocalDate> .InconsistentDayOfWeekTextValue(text));
                }

                // FIXME: If we got an era, check that the resulting date really lies within that era.
                return(ParseResult <LocalDate> .ForValue(value));
            }
Beispiel #4
0
            internal override ParseResult <AnnualDate> CalculateValue(PatternFields usedFields, string text)
            {
                // This will set MonthOfYearNumeric if necessary
                var failure = DetermineMonth(usedFields, text);

                if (failure != null)
                {
                    return(failure);
                }

                int day = usedFields.HasAny(PatternFields.DayOfMonth) ? DayOfMonth : TemplateValue.Day;

                // Validate for the year 2000, just like the AnnualDate constructor does.
                if (day > CalendarSystem.Iso.GetDaysInMonth(2000, MonthOfYearNumeric))
                {
                    return(ParseResult <AnnualDate> .DayOfMonthOutOfRangeNoYear(text, day, MonthOfYearNumeric));
                }

                return(ParseResult <AnnualDate> .ForValue(new AnnualDate(MonthOfYearNumeric, day)));
            }
Beispiel #5
0
            /// <summary>
            /// Work out the year, based on fields of:
            /// - Year
            /// - YearOfEra
            /// - YearTwoDigits (implies YearOfEra)
            /// - Era
            ///
            /// If the year is specified, that trumps everything else - any other fields
            /// are just used for checking.
            ///
            /// If nothing is specified, the year of the template value is used.
            ///
            /// If just the era is specified, the year of the template value is used,
            /// and the specified era is checked against it. (Hopefully no-one will
            /// expect to get useful information from a format string with era but no year...)
            ///
            /// Otherwise, we have the year of era (possibly only two digits) and possibly the
            /// era. If the era isn't specified, take it from the template value.
            /// Finally, if we only have two digits, then use either the century of the template
            /// value or the previous century if the year-of-era is greater than TwoDigitYearMax...
            /// and if the template value isn't in the first century already.
            ///
            /// Phew.
            /// </summary>
            private ParseResult <LocalDate> DetermineYear(PatternFields usedFields, string text)
            {
                if (usedFields.HasAny(PatternFields.Year))
                {
                    if (Year > Calendar.MaxYear || Year < Calendar.MinYear)
                    {
                        return(ParseResult <LocalDate> .FieldValueOutOfRangePostParse(text, Year, 'u'));
                    }

                    if (usedFields.HasAny(PatternFields.Era) && Era != Calendar.GetEra(Year))
                    {
                        return(ParseResult <LocalDate> .InconsistentValues(text, 'g', 'u'));
                    }

                    if (usedFields.HasAny(PatternFields.YearOfEra))
                    {
                        int yearOfEraFromYear = Calendar.GetYearOfEra(Year);
                        if (usedFields.HasAny(PatternFields.YearTwoDigits))
                        {
                            // We're only checking the last two digits
                            yearOfEraFromYear = yearOfEraFromYear % 100;
                        }
                        if (yearOfEraFromYear != YearOfEra)
                        {
                            return(ParseResult <LocalDate> .InconsistentValues(text, 'y', 'u'));
                        }
                    }
                    return(null);
                }

                // Use the year from the template value, possibly checking the era.
                if (!usedFields.HasAny(PatternFields.YearOfEra))
                {
                    Year = TemplateValue.Year;
                    return(usedFields.HasAny(PatternFields.Era) && Era != Calendar.GetEra(Year)
                        ? ParseResult <LocalDate> .InconsistentValues(text, 'g', 'u') : null);
                }

                if (!usedFields.HasAny(PatternFields.Era))
                {
                    Era = TemplateValue.Era;
                }

                if (usedFields.HasAny(PatternFields.YearTwoDigits))
                {
                    int century = TemplateValue.YearOfEra / 100;
                    if (YearOfEra > TwoDigitYearMax && century > 1)
                    {
                        century--;
                    }
                    YearOfEra += century * 100;
                }

                if (YearOfEra < Calendar.GetMinYearOfEra(Era) ||
                    YearOfEra > Calendar.GetMaxYearOfEra(Era))
                {
                    return(ParseResult <LocalDate> .YearOfEraOutOfRange(text, YearOfEra, Era, Calendar));
                }
                Year = Calendar.GetAbsoluteYear(YearOfEra, Era);
                return(null);
            }