private ParseResult <LocalDate> DetermineYear(PatternFields usedFields) { 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)) { EraIndex = Calendar.Eras.IndexOf(templateValue.Era); } // Find the absolute year from the year-of-era and era if (YearOfEra < Calendar.GetMinYearOfEra(EraIndex) || YearOfEra > Calendar.GetMaxYearOfEra(EraIndex)) { return(ParseResult <LocalDate> .YearOfEraOutOfRange(YearOfEra, EraIndex, Calendar)); } yearFromEra = Calendar.GetAbsoluteYear(YearOfEra, EraIndex); } // 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('y', 'Y')); } Year = yearFromEra; break; case PatternFields.YearOfEra | PatternFields.Year: if (Year != yearFromEra) { return(ParseResult <LocalDate> .InconsistentValues('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> .FieldValueOutOfRange(Year, 'y')); } return(null); }
public void GetMaxYearOfEra_NullEra() { Assert.Throws <ArgumentNullException>(() => CopticCalendar.GetMaxYearOfEra(null)); }
/// <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); }
public void GetMaxYearOfEra() { Assert.AreEqual(CopticCalendar.MaxYear, CopticCalendar.GetMaxYearOfEra(Era.AnnoMartyrum)); }