/// <summary> /// Returns the days at the start of the given week-year. The week-year may be /// 1 higher or lower than the max/min calendar year. For non-regular rules (i.e. where some weeks /// can be short) it returns the day when the week-year *would* have started if it were regular. /// So this *always* returns a date on firstDayOfWeek. /// </summary> private int GetWeekYearDaysSinceEpoch(YearMonthDayCalculator yearMonthDayCalculator, [Trusted] int weekYear) { unchecked { // Need to be slightly careful here, as the week-year can reasonably be (just) outside the calendar year range. // However, YearMonthDayCalculator.GetStartOfYearInDays already handles min/max -/+ 1. int startOfCalendarYear = yearMonthDayCalculator.GetStartOfYearInDays(weekYear); int startOfYearDayOfWeek = unchecked (startOfCalendarYear >= -3 ? 1 + ((startOfCalendarYear + 3) % 7) : 7 + ((startOfCalendarYear + 4) % 7)); // How many days have there been from the start of the week containing // the first day of the year, until the first day of the year? To put it another // way, how many days in the week *containing* the start of the calendar year were // in the previous calendar year. // (For example, if the start of the calendar year is Friday and the first day of the week is Monday, // this will be 4.) int daysIntoWeek = ((startOfYearDayOfWeek - (int)firstDayOfWeek) + 7) % 7; int startOfWeekContainingStartOfCalendarYear = startOfCalendarYear - daysIntoWeek; bool startOfYearIsInWeek1 = (7 - daysIntoWeek >= minDaysInFirstWeek); return(startOfYearIsInWeek1 ? startOfWeekContainingStartOfCalendarYear : startOfWeekContainingStartOfCalendarYear + 7); } }
/// <inheritdoc /> public int GetWeeksInWeekYear(int weekYear, CalendarSystem calendar) { Preconditions.CheckNotNull(calendar, nameof(calendar)); YearMonthDayCalculator yearMonthDayCalculator = calendar.YearMonthDayCalculator; ValidateWeekYear(weekYear, calendar); unchecked { int startOfWeekYear = GetWeekYearDaysSinceEpoch(yearMonthDayCalculator, weekYear); int startOfCalendarYear = yearMonthDayCalculator.GetStartOfYearInDays(weekYear); // The number of days gained or lost in the week year compared with the calendar year. // So if the week year starts on December 31st of the previous calendar year, this will be +1. // If the week year starts on January 2nd of this calendar year, this will be -1. int extraDaysAtStart = startOfCalendarYear - startOfWeekYear; // At the end of the year, we may have some extra days too. // In a non-regular rule, we just round up, so assume we effectively have 6 extra days. // In a regular rule, there can be at most minDaysInFirstWeek - 1 days "borrowed" // from the following year - because if there were any more, those days would be in the // the following year instead. int extraDaysAtEnd = irregularWeeks ? 6 : minDaysInFirstWeek - 1; int daysInThisYear = yearMonthDayCalculator.GetDaysInYear(weekYear); // We can have up to "minDaysInFirstWeek - 1" days of the next year, too. return((daysInThisYear + extraDaysAtStart + extraDaysAtEnd) / 7); } }
/// <inheritdoc /> public int GetWeeksInWeekYear(int weekYear, [NotNull] CalendarSystem calendar) { Preconditions.CheckNotNull(calendar, nameof(calendar)); YearMonthDayCalculator yearMonthDayCalculator = calendar.YearMonthDayCalculator; ValidateWeekYear(weekYear, calendar); unchecked { int startOfWeekYear = GetWeekYearDaysSinceEpoch(yearMonthDayCalculator, weekYear); int startOfCalendarYear = yearMonthDayCalculator.GetStartOfYearInDays(weekYear); // The number of days gained or lost in the week year compared with the calendar year. // So if the week year starts on December 31st of the previous calendar year, this will be +1. // If the week year starts on January 2nd of this calendar year, this will be -1. int extraDaysAtStart = startOfCalendarYear - startOfWeekYear; // At the end of the year, we may have some extra days too. // In a non-regular rule, we just round up, so assume we effectively have 6 extra days. // TODO: Explain the reasoning for the regular rule part. I know it works, I just // don't know why. int extraDaysAtEnd = irregularWeeks ? 6: minDaysInFirstWeek - 1; int daysInThisYear = yearMonthDayCalculator.GetDaysInYear(weekYear); // We can have up to "minDaysInFirstWeek - 1" days of the next year, too. return((daysInThisYear + extraDaysAtStart + extraDaysAtEnd) / 7); } }
private int GetWeeksInWeekYear([Trusted] int weekYear) { unchecked { int startOfWeekYear = GetWeekYearDaysSinceEpoch(weekYear); int startOfCalendarYear = yearMonthDayCalculator.GetStartOfYearInDays(weekYear); // The number of days gained or lost in the week year compared with the calendar year. // So if the week year starts on December 31st of the previous calendar year, this will be +1. // If the week year starts on January 2nd of this calendar year, this will be -1. int extraDays = startOfCalendarYear - startOfWeekYear; int daysInThisYear = yearMonthDayCalculator.GetDaysInYear(weekYear); // We can have up to "minDaysInFirstWeek - 1" days of the next year, too. return((daysInThisYear + extraDays + (minDaysInFirstWeek - 1)) / 7); } }
/// <inheritdoc /> public int GetWeeksInWeekYear(int weekYear, [NotNull] CalendarSystem calendar) { Preconditions.CheckNotNull(calendar, nameof(calendar)); YearMonthDayCalculator yearMonthDayCalculator = calendar.YearMonthDayCalculator; ValidateWeekYear(weekYear, calendar); unchecked { int startOfWeekYear = GetWeekYearDaysSinceEpoch(yearMonthDayCalculator, weekYear); int startOfCalendarYear = yearMonthDayCalculator.GetStartOfYearInDays(weekYear); // The number of days gained or lost in the week year compared with the calendar year. // So if the week year starts on December 31st of the previous calendar year, this will be +1. // If the week year starts on January 2nd of this calendar year, this will be -1. int extraDays = startOfCalendarYear - startOfWeekYear; int daysInThisYear = yearMonthDayCalculator.GetDaysInYear(weekYear); // We can have up to "minDaysInFirstWeek - 1" days of the next year, too. return((daysInThisYear + extraDays + (minDaysInFirstWeek - 1)) / 7); } }
/// <summary> /// Returns the days at the start of the given week-year. The week-year may be /// 1 higher or lower than the max/min calendar year. /// </summary> private int GetWeekYearDaysSinceEpoch(YearMonthDayCalculator yearMonthDayCalculator, [Trusted] int weekYear) { unchecked { // Need to be slightly careful here, as the week-year can reasonably be (just) outside the calendar year range. // However, YearMonthDayCalculator.GetStartOfYearInDays already handles min/max -/+ 1. int startOfCalendarYear = yearMonthDayCalculator.GetStartOfYearInDays(weekYear); int startOfYearDayOfWeek = unchecked (startOfCalendarYear >= -3 ? 1 + ((startOfCalendarYear + 3) % 7) : 7 + ((startOfCalendarYear + 4) % 7)); if (startOfYearDayOfWeek > (8 - minDaysInFirstWeek)) { // First week is end of previous year because it doesn't have enough days. return(startOfCalendarYear + (8 - startOfYearDayOfWeek)); } else { // First week is start of this year because it has enough days. return(startOfCalendarYear - (startOfYearDayOfWeek - 1)); } } }