// HijriCalendar.cs // // (C) Ulrich Kunitz 2002 // namespace System.Globalization { using System; using System.IO; /// /// This is the Hijri calendar which might be called Islamic calendar. /// /// /// The calendar supports only dates in the HijriEra starting with the /// epoch. /// /// /// The epoch of the Hijri Calendar might be adjusted by the /// /// property. See the discussion of the /// /// epoch /// /// of the Hijri calendar. /// /// The implementation uses the /// namespace. /// /// [Serializable] public class HijriCalendar : Calendar { /// /// Constructor. /// public HijriCalendar() { M_AbbrEraNames = new string[] {"A.H."}; M_EraNames = new string[] {"Anno Hegirae"}; if (M_TwoDigitYearMax == 99) M_TwoDigitYearMax = 1451; } /// /// The era number for the Anno Hegirae (A.H.) era. /// public static readonly int HijriEra = 1; /// /// The minimum fixed day number supported by the Hijri calendar. /// internal static readonly int M_MinFixed = CCHijriCalendar.fixed_from_dmy(1, 1, 1); /// /// The maximum fixed day number supported by the Hijri calendar. /// internal static readonly int M_MaxFixed = CCGregorianCalendar.fixed_from_dmy(31, 12, 9999); /// Overridden. Gives the eras supported by the Gregorian /// calendar as an array of integers. /// public override int[] Eras { get { return new int[] { HijriEra }; } } #if NET_1_1 [MonoTODO] public int HijriAdjustment { get { throw new NotImplementedException (); } set { throw new NotImplementedException (); } } #endif int twoDigitYearMax = 1451; [MonoTODO ("Add call into operating system")] public override int TwoDigitYearMax { get { return twoDigitYearMax; } set { M_ArgumentInRange ("value", value, 100, M_MaxYear); twoDigitYearMax = value; } } /// /// Protected field storing the /// . /// internal int M_AddHijriDate = 0; // TODO: I don't know currently, which sign to use with the parameter. /// An integer property representing the adjustment to the epoch /// of the Hijri calendar. Not supported by .NET. /// internal virtual int AddHijriDate { get { return M_AddHijriDate; } set { if (value < -3 && value > 3) throw new ArgumentOutOfRangeException( "AddHijriDate", "Value should be between -3 and 3."); M_AddHijriDate = value; } } /// /// A protected method checking an /// adjusted fixed day number. /// /// A string giving the name of the parameter /// to check. /// An integer giving the AddHijriDate adjusted /// fixed day number. /// /// /// Exception is thrown, if the AddHijriDate adjusted fixed day /// number is outside the supported range. /// internal void M_CheckFixedHijri(string param, int rdHijri) { if (rdHijri < M_MinFixed || rdHijri > M_MaxFixed-AddHijriDate) { StringWriter sw = new StringWriter(); int day, month, year; CCHijriCalendar.dmy_from_fixed(out day, out month, out year, M_MaxFixed-AddHijriDate); if (AddHijriDate != 0) { sw.Write("This HijriCalendar " + "(AddHijriDate {0})" + " allows dates from 1. 1. 1 to " + "{1}. {2}. {3}.", AddHijriDate, day, month, year); } else { sw.Write("HijriCalendar allows dates from " + "1.1.1 to {0}.{1}.{2}.", day, month, year); } throw new ArgumentOutOfRangeException(param, sw.ToString()); } } /// /// A protected member checking a /// value. /// /// The /// /// to check. /// /// /// The exception is thrown if the /// parameter is not in the supported /// range of the Hijri calendar. /// internal void M_CheckDateTime(DateTime time) { int rd = CCFixed.FromDateTime(time) - AddHijriDate; M_CheckFixedHijri("time", rd); } /// /// Protected member which computes the /// /// adjusted fixed day number from a /// . /// /// The /// /// to convert. /// /// The /// adjusted fixed day number. /// internal int M_FromDateTime(DateTime time) { return CCFixed.FromDateTime(time) - AddHijriDate; } /// /// Protected member which converts the /// /// adjusted fixed day number the a /// value. /// /// The /// adjusted fixed day number. /// /// The converted /// value. /// internal DateTime M_ToDateTime(int rd) { return CCFixed.ToDateTime(rd+AddHijriDate); } /// /// Protected member which converts the /// /// adjusted fixed day number the a /// value using a number /// of time parameters. /// /// The /// adjusted fixed day number. /// /// An integer that specifies the hour. /// /// An integer that specifies the minute. /// /// An integer that gives the second. /// /// An integer that gives the /// milliseconds. /// /// The converted /// value. /// internal DateTime M_ToDateTime(int date, int hour, int minute, int second, int milliseconds) { return CCFixed.ToDateTime(date+AddHijriDate, hour, minute, second, milliseconds); } /// /// A protected method checking the era number. /// /// The era number. /// /// The exception is thrown if the era is not equal /// . /// internal void M_CheckEra(ref int era) { if (era == CurrentEra) era = HijriEra; if (era != HijriEra) throw new ArgumentException("Era value was not valid."); } /// /// A protected method checking calendar year and the era number. /// /// An integer representing the calendar year. /// /// The era number. /// /// The exception is thrown if the era is not equal /// . /// /// /// The exception is thrown if the calendar year is outside of /// the allowed range. /// internal override void M_CheckYE(int year, ref int era) { M_CheckEra(ref era); M_ArgumentInRange("year", year, 1, 9666); } /// /// A protected method checking the calendar year, month, and /// era number. /// /// An integer representing the calendar year. /// /// An integer giving the calendar month. /// /// The era number. /// /// The exception is thrown if the era is not equal /// . /// /// /// The exception is thrown if the calendar year or month is /// outside of the allowed range. /// internal void M_CheckYME(int year, int month, ref int era) { M_CheckYE(year, ref era); if (month < 1 || month > 12) throw new ArgumentOutOfRangeException("month", "Month must be between one and twelve."); if (year == 9666) { int rd = CCHijriCalendar.fixed_from_dmy(1, month, year); M_CheckFixedHijri("month", rd); } } /// /// A protected method checking the calendar day, month, and year /// and the era number. /// /// An integer representing the calendar year. /// /// An integer giving the calendar month. /// /// An integer giving the calendar day. /// /// The era number. /// /// The exception is thrown if the era is not equal /// . /// /// /// The exception is thrown if the calendar year, month, or day is /// outside of the allowed range. /// internal void M_CheckYMDE(int year, int month, int day, ref int era) { M_CheckYME(year, month, ref era); M_ArgumentInRange("day", day, 1, GetDaysInMonth(year, month, HijriEra)); if (year == 9666) { int rd = CCHijriCalendar.fixed_from_dmy(day, month, year); M_CheckFixedHijri("day", rd); } } #if false // // The following routines are commented out as they do not appear on the .NET Framework 1.1 // /// /// Overridden. Adds days to a given date. /// /// The /// to which to add /// days. /// /// The number of days to add. /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddDays(DateTime time, int days) { DateTime t = base.AddDays(time, days); M_CheckDateTime(t); return t; } /// /// Overridden. Adds hours to a given date. /// /// The /// to which to add /// hours. /// /// The number of hours to add. /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddHours(DateTime time, int hours) { DateTime t = base.AddHours(time, hours); M_CheckDateTime(t); return t; } /// /// Overridden. Adds milliseconds to a given date. /// /// The /// to which to add /// milliseconds. /// /// The number of milliseconds given as /// double to add. Keep in mind the 100 nanosecond resolution of /// . /// /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddMilliseconds(DateTime time, double milliseconds) { DateTime t = base.AddMilliseconds(time, milliseconds); M_CheckDateTime(t); return t; } /// /// Overridden. Adds minutes to a given date. /// /// The /// to which to add /// minutes. /// /// The number of minutes to add. /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddMinutes(DateTime time, int minutes) { DateTime t = base.AddMinutes(time, minutes); M_CheckDateTime(t); return t; } /// /// Overridden. Adds seconds to a given date. /// /// The /// to which to add /// seconds. /// /// The number of seconds to add. /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddSeconds(DateTime time, int seconds) { DateTime t = base.AddSeconds(time, seconds); M_CheckDateTime(t); return t; } /// /// Overridden. Adds weeks to a given date. /// /// The /// to which to add /// weeks. /// /// The number of weeks to add. /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddWeeks(DateTime time, int weeks) { DateTime t = base.AddWeeks(time, weeks); M_CheckDateTime(t); return t; } /// /// Overridden. Gives the hour of the specified time. /// /// The /// that specifies the /// time. /// /// An integer that gives the hour of the specified time, /// starting with 0. /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetHour(DateTime time) { M_CheckDateTime(time); return base.GetHour(time); } /// /// Overridden. Gives the milliseconds in the current second /// of the specified time. /// /// The /// that specifies the /// time. /// /// An integer that gives the milliseconds in the seconds /// of the specified time, starting with 0. /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override double GetMilliseconds(DateTime time) { M_CheckDateTime(time); return base.GetMilliseconds(time); } /// /// Overridden. Gives the minute of the specified time. /// /// The /// that specifies the /// time. /// /// An integer that gives the minute of the specified time, /// starting with 0. /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetMinute(DateTime time) { M_CheckDateTime(time); return base.GetMinute(time); } /// /// Overridden. Gives the second of the specified time. /// /// The /// that specifies the /// time. /// /// An integer that gives the second of the specified time, /// starting with 0. /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetSecond(DateTime time) { M_CheckDateTime(time); return base.GetMinute(time); } #endif /// /// Overrideden. Adds months to a given date. /// /// The /// to which to add /// months. /// /// The number of months to add. /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddMonths(DateTime time, int months) { int rd = M_FromDateTime(time); int day, month, year; CCHijriCalendar.dmy_from_fixed( out day, out month, out year, rd); month += months; year += CCMath.div_mod(out month, month, 12); rd = CCHijriCalendar.fixed_from_dmy(day, month, year); M_CheckFixedHijri("time", rd); DateTime t = M_ToDateTime(rd); return t.Add(time.TimeOfDay); } /// /// Overrideden. Adds years to a given date. /// /// The /// to which to add /// years. /// /// The number of years to add. /// A new value, that /// results from adding to the specified /// DateTime. /// /// The exception is thrown if the /// return value is not in the /// supported range of the Hijri calendar. /// public override DateTime AddYears(DateTime time, int years) { int rd = M_FromDateTime(time); int day, month, year; CCHijriCalendar.dmy_from_fixed( out day, out month, out year, rd); year += years; rd = CCHijriCalendar.fixed_from_dmy(day, month, year); M_CheckFixedHijri("time", rd); DateTime t = M_ToDateTime(rd); return t.Add(time.TimeOfDay); } /// /// Overriden. Gets the day of the month from /// . /// /// The /// that specifies a /// date. /// /// An integer giving the day of months, starting with 1. /// /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetDayOfMonth(DateTime time) { int rd = M_FromDateTime(time); M_CheckFixedHijri("time", rd); return CCHijriCalendar.day_from_fixed(rd); } /// /// Overriden. Gets the day of the week from the specified date. /// /// The /// that specifies a /// date. /// /// An integer giving the day of months, starting with 1. /// /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override DayOfWeek GetDayOfWeek(DateTime time) { int rd = M_FromDateTime(time); M_CheckFixedHijri("time", rd); return (DayOfWeek)CCFixed.day_of_week(rd); } /// /// Overridden. Gives the number of the day in the year. /// /// The /// that specifies a /// date. /// /// An integer representing the day of the year, /// starting with 1. /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetDayOfYear(DateTime time) { int rd = M_FromDateTime(time); M_CheckFixedHijri("time", rd); int year = CCHijriCalendar.year_from_fixed(rd); int rd1_1 = CCHijriCalendar.fixed_from_dmy(1, 1, year); return rd - rd1_1 + 1; } /// /// Overridden. Gives the number of days in the specified month /// of the given year and era. /// /// An integer that gives the year. /// /// An integer that gives the month, starting /// with 1. /// An intger that gives the era of the specified /// year. /// An integer that gives the number of days of the /// specified month. /// /// The exception is thrown, if , /// ,or is outside /// the allowed range. /// public override int GetDaysInMonth(int year, int month, int era) { M_CheckYME(year, month, ref era); int rd1 = CCHijriCalendar.fixed_from_dmy(1, month, year); int rd2 = CCHijriCalendar.fixed_from_dmy(1, month+1, year); return rd2 - rd1; } /// /// Overridden. Gives the number of days of the specified /// year of the given era. /// /// An integer that specifies the year. /// /// An ineger that specifies the era. /// /// An integer that gives the number of days of the /// specified year. /// /// The exception is thrown, if /// is outside the allowed range. /// public override int GetDaysInYear(int year, int era) { M_CheckYE(year, ref era); int rd1 = CCHijriCalendar.fixed_from_dmy(1, 1, year); int rd2 = CCHijriCalendar.fixed_from_dmy(1, 1, year+1); return rd2 - rd1; } /// /// Overridden. Gives the era of the specified date. /// /// The /// that specifies a /// date. /// /// An integer representing the era of the calendar. /// /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetEra(DateTime time) { M_CheckDateTime(time); return HijriEra; } /// /// Overridden. Gives the number of the month of the specified /// date. /// /// The /// that specifies a /// date. /// /// An integer representing the month, /// starting with 1. /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetMonth(DateTime time) { int rd = M_FromDateTime(time); M_CheckFixedHijri("time", rd); return CCHijriCalendar.month_from_fixed(rd); } /// /// Overridden. Gives the number of months in the specified year /// and era. /// /// An integer that specifies the year. /// /// An integer that specifies the era. /// /// An integer that gives the number of the months in the /// specified year. /// /// The exception is thrown, if the year or the era are not valid. /// public override int GetMonthsInYear(int year, int era) { M_CheckYE(year, ref era); return 12; } /// /// Overridden. Gives the number of the year of the specified /// date. /// /// The /// that specifies a /// date. /// /// An integer representing the year, /// starting with 1. /// /// The exception is thrown if the /// parameter is not in the /// supported range of the Hijri calendar. /// public override int GetYear(DateTime time) { int rd = M_FromDateTime(time); M_CheckFixedHijri("time", rd); return CCHijriCalendar.year_from_fixed(rd); } /// /// Overridden. Tells whether the given day /// is a leap day. /// /// An integer that specifies the year in the /// given era. /// /// An integer that specifies the month. /// /// An integer that specifies the day. /// /// An integer that specifies the era. /// /// A boolean that tells whether the given day is a leap /// day. /// /// /// The exception is thrown, if the year, month, day, or era is not /// valid. /// public override bool IsLeapDay(int year, int month, int day, int era) { M_CheckYMDE(year, month, day, ref era); return IsLeapYear(year) && month == 12 && day == 30; } /// /// Overridden. Tells whether the given month /// is a leap month. /// /// An integer that specifies the year in the /// given era. /// /// An integer that specifies the month. /// /// An integer that specifies the era. /// /// A boolean that tells whether the given month is a leap /// month. /// /// /// The exception is thrown, if the year, month, or era is not /// valid. /// public override bool IsLeapMonth(int year, int month, int era) { M_CheckYME(year, month, ref era); return false; } /// /// Overridden. Tells whether the given year /// is a leap year. /// /// An integer that specifies the year in the /// given era. /// /// An integer that specifies the era. /// /// A boolean that tells whether the given year is a leap /// year. /// /// /// The exception is thrown, if the year or era is not /// valid. /// public override bool IsLeapYear(int year, int era) { M_CheckYE(year, ref era); return CCHijriCalendar.is_leap_year(year); } /// /// Overridden. Creates the /// from the parameters. /// /// An integer that gives the year in the /// . /// /// An integer that specifies the month. /// /// An integer that specifies the day. /// /// An integer that specifies the hour. /// /// An integer that specifies the minute. /// /// An integer that gives the second. /// /// An integer that gives the /// milliseconds. /// /// An integer that specifies the era. /// /// A /// representig the date and time. /// /// /// The exception is thrown, if at least one of the parameters /// is out of range. /// public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int milliseconds, int era) { M_CheckYMDE(year, month, day, ref era); M_CheckHMSM(hour, minute, second, milliseconds); int rd = CCHijriCalendar.fixed_from_dmy(day, month, year); return M_ToDateTime(rd, hour, minute, second, milliseconds); } [MonoTODO] public override int ToFourDigitYear(int year) { throw new NotImplementedException(); } } // class HijriCalendar } // namespace System.Globalization