<commit_before>#region Copyright and license information
// Copyright 2001-2009 <NAME>
// Copyright 2009-2011 <NAME>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion

using System;
using NodaTime.Fields;

namespace NodaTime.Calendars
{
    // TODO: Optimisations of GetLocalInstant etc.
    internal abstract class BasicCalendarSystem : AssembledCalendarSystem
    {
        private static readonly FieldSet preciseFields = CreatePreciseFields();

        private const int YearCacheSize = 1 << 10;
        private const int YearCacheMask = YearCacheSize - 1;
        private static readonly YearInfo[] yearCache = new YearInfo[YearCacheSize];

        private readonly int minDaysInFirstWeek;

        /// <summary>
        /// Returns the number of ticks from the start of the given year to the start of the given month.
        /// TODO: We always add this to the ticks at the start of the year. Why not just do it?
        /// </summary>
        protected abstract long GetTotalTicksByYearMonth(int year, int month);

        internal abstract int MinYear { get; }
        internal abstract int MaxYear { get; }
        internal abstract long AverageTicksPerMonth { get; }
        internal abstract long AverageTicksPerYear { get; }
        internal abstract long AverageTicksPerYearDividedByTwo { get; }
        internal abstract long ApproxTicksAtEpochDividedByTwo { get; }
        protected abstract LocalInstant CalculateStartOfYear(int year);
        protected internal abstract int GetMonthOfYear(LocalInstant localInstant, int year);
        internal abstract int GetDaysInMonthMax(int month);
        internal abstract long GetYearDifference(LocalInstant minuendInstant, LocalInstant subtrahendInstant);
        internal abstract LocalInstant SetYear(LocalInstant localInstant, int year);

        private static FieldSet CreatePreciseFields()
        {
            // First create the simple durations, then fill in date/time fields,
            // which rely on the other properties
            FieldSet.Builder builder = new FieldSet.Builder
                                       {
                                           Ticks = TicksDurationField.Instance,
                                           Milliseconds = PreciseDurationField.Milliseconds,
                                           Seconds = PreciseDurationField.Seconds,
                                           Minutes = PreciseDurationField.Minutes,
                                           Hours = PreciseDurationField.Hours,
                                           HalfDays = PreciseDurationField.HalfDays,
                                           Days = PreciseDurationField.Days,
                                           Weeks = PreciseDurationField.Weeks
                                       };
            builder.TickOfMillisecond = new PreciseDateTimeField(DateTimeFieldType.TickOfMillisecond, builder.Ticks, builder.Milliseconds);
            builder.TickOfDay = new PreciseDateTimeField(DateTimeFieldType.TickOfDay, builder.Ticks, builder.Days);
            builder.MillisecondOfSecond = new PreciseDateTimeField(DateTimeFieldType.MillisecondOfSecond, builder.Milliseconds, builder.Seconds);
            builder.MillisecondOfDay = new PreciseDateTimeField(DateTimeFieldType.MillisecondOfDay, builder.Milliseconds, builder.Days);
            builder.SecondOfMinute = new PreciseDateTimeField(DateTimeFieldType.SecondOfMinute, builder.Seconds, builder.Minutes);
            builder.SecondOfDay = new PreciseDateTimeField(DateTimeFieldType.SecondOfDay, builder.Seconds, builder.Days);
            builder.MinuteOfHour = new PreciseDateTimeField(DateTimeFieldType.MinuteOfHour, builder.Minutes, builder.Hours);
            builder.MinuteOfDay = new PreciseDateTimeField(DateTimeFieldType.MinuteOfDay, builder.Minutes, builder.Days);
            builder.HourOfDay = new PreciseDateTimeField(DateTimeFieldType.HourOfDay, builder.Hours, builder.Days);
            builder.HourOfHalfDay = new PreciseDateTimeField(DateTimeFieldType.HourOfHalfDay, builder.Hours, builder.HalfDays);
            builder.ClockHourOfDay = new ZeroIsMaxDateTimeField(builder.HourOfDay, DateTimeFieldType.ClockHourOfDay);
            builder.ClockHourOfHalfDay = new ZeroIsMaxDateTimeField(builder.HourOfHalfDay, DateTimeFieldType.ClockHourOfHalfDay);
            // TODO: This was a separate subclass in Joda, for i18n purposes
            builder.HalfDayOfDay = new PreciseDateTimeField(DateTimeFieldType.HalfDayOfDay, builder.HalfDays, builder.Days);
            return builder.Build();
        }

        protected BasicCalendarSystem(string name, CalendarSystem baseCalendar, int minDaysInFirstWeek) : base(name, baseCalendar)
        {
            if (minDaysInFirstWeek < 1 || minDaysInFirstWeek > 7)
            {
                throw new ArgumentException("Invalid min days in first week: " + minDaysInFirstWeek);
            }
            this.minDaysInFirstWeek = minDaysInFirstWeek;
            // Effectively invalidate the first cache entry.
            // Every other cache entry will automatically be invalid,
            // by having year 0.
            yearCache[0] = new YearInfo(1, LocalInstant.LocalUnixEpoch.Ticks);
        }

        protected override void AssembleFields(FieldSet.Builder builder)
        {
            // First copy the fields that are the same for all basic
            // calendars
            builder.WithSupportedFieldsFrom(preciseFields);

            // Now create fields that have unique behavior for Gregorian and Julian
            // calendars.

            builder.Year = new BasicYearDateTimeField(this);
            builder.YearOfEra = new GJYearOfEraDateTimeField(builder.Year, this);

            // Define one-based centuryOfEra and yearOfCentury.
            DateTimeField field = new OffsetDateTimeField(builder.YearOfEra, 99);
            builder.CenturyOfEra = new DividedDateTimeField(field, DateTimeFieldType.CenturyOfEra, 100);<commit_msg>Fix exception thrown for invalid minimum days of the week.<commit_after>#region Copyright and license information
// Copyright 2001-2009 <NAME>
// Copyright 2009-2011 <NAME>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion

using System;
using NodaTime.Fields;

namespace NodaTime.Calendars
{
    // TODO: Optimisations of GetLocalInstant etc.
    internal abstract class BasicCalendarSystem : AssembledCalendarSystem
    {
        private static readonly FieldSet preciseFields = CreatePreciseFields();

        private const int YearCacheSize = 1 << 10;
        private const int YearCacheMask = YearCacheSize - 1;
        private static readonly YearInfo[] yearCache = new YearInfo[YearCacheSize];

        private readonly int minDaysInFirstWeek;

        /// <summary>
        /// Returns the number of ticks from the start of the given year to the start of the given month.
        /// TODO: We always add this to the ticks at the start of the year. Why not just do it?
        /// </summary>
        protected abstract long GetTotalTicksByYearMonth(int year, int month);

        internal abstract int MinYear { get; }
        internal abstract int MaxYear { get; }
        internal abstract long AverageTicksPerMonth { get; }
        internal abstract long AverageTicksPerYear { get; }
        internal abstract long AverageTicksPerYearDividedByTwo { get; }
        internal abstract long ApproxTicksAtEpochDividedByTwo { get; }
        protected abstract LocalInstant CalculateStartOfYear(int year);
        protected internal abstract int GetMonthOfYear(LocalInstant localInstant, int year);
        internal abstract int GetDaysInMonthMax(int month);
        internal abstract long GetYearDifference(LocalInstant minuendInstant, LocalInstant subtrahendInstant);
        internal abstract LocalInstant SetYear(LocalInstant localInstant, int year);

        private static FieldSet CreatePreciseFields()
        {
            // First create the simple durations, then fill in date/time fields,
            // which rely on the other properties
            FieldSet.Builder builder = new FieldSet.Builder
                                       {
                                           Ticks = TicksDurationField.Instance,
                                           Milliseconds = PreciseDurationField.Milliseconds,
                                           Seconds = PreciseDurationField.Seconds,
                                           Minutes = PreciseDurationField.Minutes,
                                           Hours = PreciseDurationField.Hours,
                                           HalfDays = PreciseDurationField.HalfDays,
                                           Days = PreciseDurationField.Days,
                                           Weeks = PreciseDurationField.Weeks
                                       };
            builder.TickOfMillisecond = new PreciseDateTimeField(DateTimeFieldType.TickOfMillisecond, builder.Ticks, builder.Milliseconds);
            builder.TickOfDay = new PreciseDateTimeField(DateTimeFieldType.TickOfDay, builder.Ticks, builder.Days);
            builder.MillisecondOfSecond = new PreciseDateTimeField(DateTimeFieldType.MillisecondOfSecond, builder.Milliseconds, builder.Seconds);
            builder.MillisecondOfDay = new PreciseDateTimeField(DateTimeFieldType.MillisecondOfDay, builder.Milliseconds, builder.Days);
            builder.SecondOfMinute = new PreciseDateTimeField(DateTimeFieldType.SecondOfMinute, builder.Seconds, builder.Minutes);
            builder.SecondOfDay = new PreciseDateTimeField(DateTimeFieldType.SecondOfDay, builder.Seconds, builder.Days);
            builder.MinuteOfHour = new PreciseDateTimeField(DateTimeFieldType.MinuteOfHour, builder.Minutes, builder.Hours);
            builder.MinuteOfDay = new PreciseDateTimeField(DateTimeFieldType.MinuteOfDay, builder.Minutes, builder.Days);
            builder.HourOfDay = new PreciseDateTimeField(DateTimeFieldType.HourOfDay, builder.Hours, builder.Days);
            builder.HourOfHalfDay = new PreciseDateTimeField(DateTimeFieldType.HourOfHalfDay, builder.Hours, builder.HalfDays);
            builder.ClockHourOfDay = new ZeroIsMaxDateTimeField(builder.HourOfDay, DateTimeFieldType.ClockHourOfDay);
            builder.ClockHourOfHalfDay = new ZeroIsMaxDateTimeField(builder.HourOfHalfDay, DateTimeFieldType.ClockHourOfHalfDay);
            // TODO: This was a separate subclass in Joda, for i18n purposes
            builder.HalfDayOfDay = new PreciseDateTimeField(DateTimeFieldType.HalfDayOfDay, builder.HalfDays, builder.Days);
            return builder.Build();
        }

        protected BasicCalendarSystem(string name, CalendarSystem baseCalendar, int minDaysInFirstWeek) : base(name, baseCalendar)
        {
            if (minDaysInFirstWeek < 1 || minDaysInFirstWeek > 7)
            {
                throw new ArgumentOutOfRangeException("minDaysInFirstWeek", "Minimum days in first week must be between 1 and 7 inclusive");
            }
            this.minDaysInFirstWeek = minDaysInFirstWeek;
            // Effectively invalidate the first cache entry.
            // Every other cache entry will automatically be invalid,
            // by having year 0.
            yearCache[0] = new YearInfo(1, LocalInstant.LocalUnixEpoch.Ticks);
        }

        protected override void AssembleFields(FieldSet.Builder builder)
        {
            // First copy the fields that are the same for all basic
            // calendars
            builder.WithSupportedFieldsFrom(preciseFields);

            // Now create fields that have unique behavior for Gregorian and Julian
            // calendars.

            builder.Year = new BasicYearDateTimeField(this);
            builder.YearOfEra = new GJYearOfEraDateTimeField(builder.Year, this);

            // Define one-based centuryOfEra and yearOfCentury.
            DateTimeField field = new OffsetDateTimeField(builder.YearOfEra, 99);
            builder.CenturyOfEra = new DividedDateTimeField(field, DateTimeFieldType.CenturyOfEra, 100);
{'fraction_non_alphanumeric': 0.06430426149381396, 'fraction_numerical': 0.005651443409195051, 'mean_word_length': 2.528698464025869, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '244491', 'n_tokens_mistral': 3217, 'n_tokens_neox': 3049, 'n_words': 932}