Esempio n. 1
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);
            }
Esempio n. 2
0
            private ParseResult <LocalDate> DetermineYear(PatternFields usedFields, string text)
            {
                int yearFromEra = 0;

                if (IsFieldUsed(usedFields, PatternFields.YearOfEra))
                {
                    // Odd to have a year-of-era without era, but it's valid...
                    if (!IsFieldUsed(usedFields, PatternFields.Era))
                    {
                        Era = Calendar.GetEra(templateValue.YearMonthDay);
                    }
                    // Find the absolute year from the year-of-era and era
                    if (YearOfEra < Calendar.GetMinYearOfEra(Era) || YearOfEra > Calendar.GetMaxYearOfEra(Era))
                    {
                        return(ParseResult <LocalDate> .YearOfEraOutOfRange(text, YearOfEra, Era, Calendar));
                    }
                    yearFromEra = Calendar.GetAbsoluteYear(YearOfEra, Era);
                }

                // Note: we can't have YearTwoDigits without Year, hence there are only 6 options here rather than 8.
                switch (usedFields & (PatternFields.Year | PatternFields.YearOfEra | PatternFields.YearTwoDigits))
                {
                case PatternFields.Year:
                    // Fine, we'll just use the Year value we've been provided
                    break;

                case PatternFields.Year | PatternFields.YearTwoDigits:
                    Year = GetAbsoluteYearFromTwoDigits(templateValue.Year, Year);
                    break;

                case PatternFields.YearOfEra:
                    Year = yearFromEra;
                    break;

                case PatternFields.YearOfEra | PatternFields.Year | PatternFields.YearTwoDigits:
                    // We've been given a year of era, but only a two digit year. The year of era
                    // takes precedence, so we just check that the two digits are correct.
                    // This is a pretty bizarre situation...
                    if ((Math.Abs(yearFromEra) % 100) != Year)
                    {
                        return(ParseResult <LocalDate> .InconsistentValues(text, 'y', 'Y'));
                    }
                    Year = yearFromEra;
                    break;

                case PatternFields.YearOfEra | PatternFields.Year:
                    if (Year != yearFromEra)
                    {
                        return(ParseResult <LocalDate> .InconsistentValues(text, 'y', 'Y'));
                    }
                    Year = yearFromEra;
                    break;

                case 0:
                    Year = templateValue.Year;
                    break;
                    // No default: it would be impossible.
                }
                if (Year > Calendar.MaxYear || Year < Calendar.MinYear)
                {
                    // The field can't be YearOfEra, as we've already validated that earlier.
                    return(ParseResult <LocalDate> .FieldValueOutOfRangePostParse(text, Year, 'y'));
                }
                return(null);
            }