Ejemplo n.º 1
0
        /// <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);
            }
        }
Ejemplo n.º 2
0
        /// <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);
            }
        }
Ejemplo n.º 3
0
        /// <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);
            }
        }
Ejemplo n.º 4
0
        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);
            }
        }
Ejemplo n.º 5
0
        /// <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);
            }
        }
Ejemplo n.º 6
0
        /// <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));
                }
            }
        }