/// <summary> /// Returns the days since the Unix epoch at the specified epoch. /// </summary> private static int GetYear1Days(IslamicEpoch epoch) { switch (epoch) { // Epoch 1970-01-01 ISO = 1389-10-22 Islamic (civil) or 1389-10-23 Islamic (astronomical) case IslamicEpoch.Astronomical: return(DaysAtAstronomicalEpoch); case IslamicEpoch.Civil: return(DaysAtCivilEpoch); default: throw new ArgumentOutOfRangeException(nameof(epoch)); } }
internal IslamicYearMonthDayCalculator(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) : base(1, 9665, 12, AverageDaysPer10Years, GetYear1Days(epoch)) { this.leapYearPatternBits = GetLeapYearPatternBits(leapYearPattern); }
/// <summary> /// Returns an Islamic, or Hijri, calendar system. /// </summary> /// <remarks> /// <para> /// This returns a tablular calendar, rather than one based on lunar observation. This calendar is a /// lunar calendar with 12 months, each of 29 or 30 days, resulting in a year of 354 days (or 355 on a leap /// year). /// </para> /// <para> /// Year 1 in the Islamic calendar began on July 15th or 16th, 622 CE (Julian), thus /// Islamic years do not begin at the same time as Julian years. This calendar /// is not proleptic, as it does not allow dates before the first Islamic year. /// </para> /// <para> /// There are two basic forms of the Islamic calendar, the tabular and the /// observed. The observed form cannot easily be used by computers as it /// relies on human observation of the new moon. The tabular calendar, implemented here, is an /// arithmetic approximation of the observed form that follows relatively simple rules. /// </para> /// <para>You should choose an epoch based on which external system you wish /// to be compatible with. The epoch beginning on July 16th is the more common /// one for the tabular calendar, so using <see cref="IslamicEpoch.Civil" /> /// would usually be a logical choice. However, Windows uses July 15th, so /// if you need to be compatible with other Windows systems, you may wish to use /// <see cref="IslamicEpoch.Astronomical" />. The fact that the Islamic calendar /// traditionally starts at dusk, a Julian day traditionally starts at noon, /// and all calendar systems in Noda Time start their days at midnight adds /// somewhat inevitable confusion to the mix, unfortunately.</para> /// <para> /// The tabular form of the calendar defines 12 months of alternately /// 30 and 29 days. The last month is extended to 30 days in a leap year. /// Leap years occur according to a 30 year cycle. There are four recognised /// patterns of leap years in the 30 year cycle: /// </para> /// <list type="table"> /// <listheader><term>Origin</term><description>Leap years</description></listheader> /// <item><term>Kūshyār ibn Labbān</term><description>2, 5, 7, 10, 13, 15, 18, 21, 24, 26, 29</description></item> /// <item><term>al-Fazārī</term><description>2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29</description></item> /// <item><term>Fātimid (also known as Misri or Bohra)</term><description>2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29</description></item> /// <item><term>Habash al-Hasib</term><description>2, 5, 8, 11, 13, 16, 19, 21, 24, 27, 30</description></item> /// </list> /// <para> /// The leap year pattern to use is determined from the first parameter to this factory method. /// The second parameter determines which epoch is used - the "astronomical" or "Thursday" epoch /// (July 15th 622CE) or the "civil" or "Friday" epoch (July 16th 622CE). /// </para> /// <para> /// This implementation defines a day as midnight to midnight exactly as per /// the ISO calendar. This correct start of day is at sunset on the previous /// day, however this cannot readily be modelled and has been ignored. /// </para> /// </remarks> /// <param name="leapYearPattern">The pattern of years in the 30-year cycle to consider as leap years</param> /// <param name="epoch">The kind of epoch to use (astronomical or civil)</param> /// <returns>A suitable Islamic calendar reference; the same reference may be returned by several /// calls as the object is immutable and thread-safe.</returns> public static CalendarSystem GetIslamicCalendar(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { Preconditions.CheckArgumentRange(nameof(leapYearPattern), (int)leapYearPattern, 1, 4); Preconditions.CheckArgumentRange(nameof(epoch), (int)epoch, 1, 2); return(IslamicCalendars.ByLeapYearPatterAndEpoch[(int)leapYearPattern - 1, (int)epoch - 1]); }
// Not part of IslamicCalendars as we want to be able to call it without triggering type initialization. internal static string GetIslamicId(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { return(Invariant($"{IslamicIdBase} {epoch}-{leapYearPattern}")); }
/// <summary> /// Returns the days since the Unix epoch at the specified epoch. /// </summary> private static int GetYear1Days(IslamicEpoch epoch) { switch (epoch) { // Epoch 1970-01-01 ISO = 1389-10-22 Islamic (civil) or 1389-10-23 Islamic (astronomical) case IslamicEpoch.Astronomical: return DaysAtAstronomicalEpoch; case IslamicEpoch.Civil: return DaysAtCivilEpoch; default: throw new ArgumentOutOfRangeException(nameof(epoch)); } }
// TODO: Caching internal static CalendarSystem GetInstance(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { int patternBits = GetLeapYearPatternBits(leapYearPattern); long epochTicks = GetEpochTicks(epoch); return new IslamicCalendar(patternBits, epochTicks); }
// Not part of IslamicCalendars as we want to be able to call it without triggering type initialization. internal static string GetIslamicId(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { return(string.Format(CultureInfo.InvariantCulture, "{0} {1}-{2}", IslamicIdBase, epoch, leapYearPattern)); }
/// <summary> /// Returns an Islamic, or Hijri, calendar system. /// </summary> /// <remarks> /// <para> /// This returns a tablular calendar, rather than one based on lunar observation. This calendar is a /// lunar calendar with 12 months, each of 29 or 30 days, resulting in a year of 354 days (or 355 on a leap /// year). /// </para> /// <para> /// Year 1 in the Islamic calendar began on July 15th or 16th, 622 CE (Julian), thus /// Islamic years do not begin at the same time as Julian years. This calendar /// is not proleptic, as it does not allow dates before the first Islamic year. /// </para> /// <para> /// There are two basic forms of the Islamic calendar, the tabular and the /// observed. The observed form cannot easily be used by computers as it /// relies on human observation of the new moon. The tabular calendar, implemented here, is an /// arithmetic approximation of the observed form that follows relatively simple rules. /// </para> /// <para>You should choose an epoch based on which external system you wish /// to be compatible with. The epoch beginning on July 16th is the more common /// one for the tabular calendar, so using <see cref="IslamicEpoch.Civil" /> /// would usually be a logical choice. However, Windows uses July 15th, so /// if you need to be compatible with other Windows systems, you may wish to use /// <see cref="IslamicEpoch.Astronomical" />. The fact that the Islamic calendar /// traditionally starts at dusk, a Julian day traditionally starts at noon, /// and all calendar systems in Noda Time start their days at midnight adds /// somewhat inevitable confusion to the mix, unfortunately.</para> /// <para> /// The tabular form of the calendar defines 12 months of alternately /// 30 and 29 days. The last month is extended to 30 days in a leap year. /// Leap years occur according to a 30 year cycle. There are four recognised /// patterns of leap years in the 30 year cycle: /// </para> /// <list type="table"> /// <listheader><term>Origin</term><description>Leap years</description></listheader> /// <item><term>Kūshyār ibn Labbān</term><description>2, 5, 7, 10, 13, 15, 18, 21, 24, 26, 29</description></item> /// <item><term>al-Fazārī</term><description>2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29</description></item> /// <item><term>Fātimid (also known as Misri or Bohra)</term><description>2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29</description></item> /// <item><term>Habash al-Hasib</term><description>2, 5, 8, 11, 13, 16, 19, 21, 24, 27, 30</description></item> /// </list> /// <para> /// The leap year pattern to use is determined from the first parameter to this factory method. /// The second parameter determines which epoch is used - the "astronomical" or "Thursday" epoch /// (July 15th 622CE) or the "civil" or "Friday" epoch (July 16th 622CE). /// </para> /// <para> /// This implementation defines a day as midnight to midnight exactly as per /// the ISO calendar. This correct start of day is at sunset on the previous /// day, however this cannot readily be modelled and has been ignored. /// </para> /// </remarks> /// <param name="leapYearPattern">The pattern of years in the 30-year cycle to consider as leap years</param> /// <param name="epoch">The kind of epoch to use (astronomical or civil)</param> /// <returns>A suitable Islamic calendar reference; the same reference may be returned by several /// calls as the object is immutable and thread-safe.</returns> public static CalendarSystem GetIslamicCalendar(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { Preconditions.CheckArgumentRange("leapYearPattern", (int)leapYearPattern, 1, 4); Preconditions.CheckArgumentRange("epoch", (int)epoch, 1, 2); return(IslamicCalendarSystems[(int)leapYearPattern - 1, (int)epoch - 1]); }
/// <summary> /// Returns the LocalInstant ticks at the specified epoch. /// </summary> private static long GetEpochTicks(IslamicEpoch epoch) { switch (epoch) { case IslamicEpoch.Astronomical: return TicksAtAstronomicalEpoch; case IslamicEpoch.Civil: return TicksAtCivilEpoch; default: throw new ArgumentOutOfRangeException("epoch"); } }
// Not part of IslamicCalendars as we want to be able to call it without triggering type initialization. internal static string GetIslamicId(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { return string.Format(CultureInfo.InvariantCulture, "{0} {1}-{2}", IslamicIdBase, epoch, leapYearPattern); }
/// <summary> /// Returns an Islamic, or Hijri, calendar system. /// </summary> /// <remarks> /// <para> /// This returns a tablular calendar, rather than one based on lunar observation. This calendar is a /// lunar calendar with 12 months, each of 29 or 30 days, resulting in a year of 354 days (or 355 on a leap /// year). /// </para> /// <para> /// Year 1 in the Islamic calendar began on July 15th or 16th, 622 CE (Julian), thus /// Islamic years do not begin at the same time as Julian years. This calendar /// is not proleptic, as it does not allow dates before the first Islamic year. /// </para> /// <para> /// There are two basic forms of the Islamic calendar, the tabular and the /// observed. The observed form cannot easily be used by computers as it /// relies on human observation of the new moon. The tabular calendar, implemented here, is an /// arithmetic approximation of the observed form that follows relatively simple rules. /// </para> /// <para>You should choose an epoch based on which external system you wish /// to be compatible with. The epoch beginning on July 16th is the more common /// one for the tabular calendar, so using <see cref="IslamicEpoch.Civil" /> /// would usually be a logical choice. However, Windows uses July 15th, so /// if you need to be compatible with other Windows systems, you may wish to use /// <see cref="IslamicEpoch.Astronomical" />. The fact that the Islamic calendar /// traditionally starts at dusk, a Julian day traditionally starts at noon, /// and all calendar systems in Noda Time start their days at midnight adds /// somewhat inevitable confusion to the mix, unfortunately.</para> /// <para> /// The tabular form of the calendar defines 12 months of alternately /// 30 and 29 days. The last month is extended to 30 days in a leap year. /// Leap years occur according to a 30 year cycle. There are four recognised /// patterns of leap years in the 30 year cycle: /// </para> /// <list type="table"> /// <listheader><term>Origin</term><description>Leap years</description></listheader> /// <item><term>Kūshyār ibn Labbān</term><description>2, 5, 7, 10, 13, 15, 18, 21, 24, 26, 29</description></item> /// <item><term>al-Fazārī</term><description>2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29</description></item> /// <item><term>Fātimid (also known as Misri or Bohra)</term><description>2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29</description></item> /// <item><term>Habash al-Hasib</term><description>2, 5, 8, 11, 13, 16, 19, 21, 24, 27, 30</description></item> /// </list> /// <para> /// The leap year pattern to use is determined from the first parameter to this factory method. /// The second parameter determines which epoch is used - the "astronomical" or "Thursday" epoch /// (July 15th 622CE) or the "civil" or "Friday" epoch (July 16th 622CE). /// </para> /// <para> /// This implementation defines a day as midnight to midnight exactly as per /// the ISO calendar. This correct start of day is at sunset on the previous /// day, however this cannot readily be modelled and has been ignored. /// </para> /// </remarks> /// <param name="leapYearPattern">The pattern of years in the 30-year cycle to consider as leap years</param> /// <param name="epoch">The kind of epoch to use (astronomical or civil)</param> /// <returns>A suitable Islamic calendar reference; the same reference may be returned by several /// calls as the object is immutable and thread-safe.</returns> public static CalendarSystem GetIslamicCalendar(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { Preconditions.CheckArgumentRange(nameof(leapYearPattern), (int) leapYearPattern, 1, 4); Preconditions.CheckArgumentRange(nameof(epoch), (int) epoch, 1, 2); return IslamicCalendars.ByLeapYearPatterAndEpoch[(int) leapYearPattern - 1, (int) epoch - 1]; }
internal IslamicYearMonthDayCalculator(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) : base(1, 31513, 12, TicksPerNonLeapYear, AverageTicksPerYear, GetYear1Ticks(epoch), new[] { Era.AnnoHegirae }) { this.leapYearPatternBits = GetLeapYearPatternBits(leapYearPattern); }
/// <summary> /// Returns an Islamic, or Hijri, calendar system. /// </summary> /// <remarks> /// <para> /// This represents the civil Hijri calendar, rather than the religious one based /// on lunar observation. This calendar is a lunar calendar with a shorter year than ISO. /// Year 1 in the Islamic calendar began on July 15th or 16th, 622 CE (Julian), thus /// Islamic years do not begin at the same time as Julian years. This chronology /// is not proleptic, as it does not allow dates before the first Islamic year. /// </para> /// <para> /// There are two basic forms of the Islamic calendar, the tabular and the /// observed. The observed form cannot easily be used by computers as it /// relies on human observation of the new moon. The tabular calendar, implemented here, is an /// arithmetic approximation of the observed form that follows relatively simple rules. /// </para> /// <para> /// The tabular form of the calendar defines 12 months of alternately /// 30 and 29 days. The last month is extended to 30 days in a leap year. /// Leap years occur according to a 30 year cycle. There are four recognised /// patterns of leap years in the 30 year cycle: /// </para> /// <list type="table"> /// <listheader><term>Origin</term><description>Leap years</description></listheader> /// <item><term>Kūshyār ibn Labbān</term><description>2, 5, 7, 10, 13, 15, 18, 21, 24, 26, 29</description></item> /// <item><term>al-Fazārī</term><description>2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29</description></item> /// <item><term>Fātimid (also known as Misri or Bohra)</term><description>2, 5, 8, 10, 13, 16, 19, 21, 24, 27, 29</description></item> /// <item><term>Habash al-Hasib</term><description>2, 5, 8, 11, 13, 16, 19, 21, 24, 27, 30</description></item> /// </list> /// <para> /// The leap year pattern to use is determined from the first parameter to this factory method. /// The second parameter determines which epoch is used - the "astronomical" or "Thursday" epoch /// (July 15th 622CE) or the "civil" or "Friday" epoch (July 16th 622CE). /// </para> /// <para> /// This implementation defines a day as midnight to midnight exactly as per /// the ISO chronology. This correct start of day is at sunset on the previous /// day, however this cannot readily be modelled and has been ignored. /// </para> /// </remarks> /// <param name="leapYearPattern">The pattern of years in the 30-year cycle to consider as leap years</param> /// <param name="epoch">The kind of epoch to use (astronomical or civil)</param> /// <returns>A suitable Islamic calendar reference; the same reference may be returned by several /// calls as the object is immutable and thread-safe.</returns> public static CalendarSystem GetIslamicCalendar(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) { return IslamicCalendar.GetInstance(leapYearPattern, epoch); }
internal IslamicYearMonthDayCalculator(IslamicLeapYearPattern leapYearPattern, IslamicEpoch epoch) : base(1, 31513, 12, AverageTicksPerYear, GetYear1Ticks(epoch), Era.AnnoHegirae) { this.daysAtStartOfYear1 = (int)(TicksAtStartOfYear1 / NodaConstants.TicksPerStandardDay); this.leapYearPatternBits = GetLeapYearPatternBits(leapYearPattern); }