*Calendar classes
authorUlrich Kunitz <ulrich@mono-cvs.ximian.com>
Thu, 28 Mar 2002 20:00:29 +0000 (20:00 -0000)
committerUlrich Kunitz <ulrich@mono-cvs.ximian.com>
Thu, 28 Mar 2002 20:00:29 +0000 (20:00 -0000)
svn path=/trunk/mcs/; revision=3462

mcs/class/corlib/System.Globalization/Calendar.cs
mcs/class/corlib/System.Globalization/GregorianCalendar.cs
mcs/class/corlib/System.Globalization/HebrewCalendar.cs [new file with mode: 0644]
mcs/class/corlib/System.Globalization/HijriCalendar.cs [new file with mode: 0644]
mcs/class/corlib/System.Globalization/JapaneseCalendar.cs [new file with mode: 0644]
mcs/class/corlib/System.Globalization/JulianCalendar.cs
mcs/class/corlib/System.Globalization/KoreanCalendar.cs [new file with mode: 0644]
mcs/class/corlib/System.Globalization/TaiwanCalendar.cs [new file with mode: 0644]
mcs/class/corlib/System.Globalization/ThaiBuddhistCalendar.cs [new file with mode: 0644]

index f9c6fdfe4d8c21734b00deb86f2900a9fc011a9a..5c8501a43a60dab57765f6872652daead4b24196 100644 (file)
-// ::MONO
-//
-// System.Globalization.Calendar.cs
-//
-// Copyright (C) Wictor Wilén 2001 (wictor@iBizkit.se)
-//
-// Contributors: Marcel Narings, Wictor Wilén
-//
-// Revisions
-// 2001-09-14: First draft
-// 2001-09-15: First release
-//
-//
-// TODO: testing
+// Calendar.cs
 //
+// (C) Ulrich Kunitz 2002
 //
 
+namespace System.Globalization {
+
 using System;
+using System.IO;
+
+/// <remarks>
+/// The class serves as a base class for calendar classes.
+/// </remarks>
+[Serializable]
+public abstract class Calendar {
+       /// <value>An protected integer property that gives the number of
+       /// days in a week. It might be overridden.</value>
+       protected virtual int M_DaysInWeek
+       {
+               get { return 7; }
+       }
 
-namespace System.Globalization
-{
        /// <summary>
-       /// Implmentation of the System.Globalization.Calendar class
+       /// The protected method creates the string used in the
+       /// <see cref="T:System.ArgumentOutOfRangeException"/>
        /// </summary>
-       public abstract class Calendar
+       /// <param name="a">An object that represents the smallest 
+       /// allowable value.</param>
+       /// <param name="b">An object that represents the greatest allowable
+       /// value.</param>
+       /// <returns>The string used in the
+       /// <see cref="T:System.ArgumentOutOfRangeException"/>
+       /// </returns>
+       protected string M_ValidValues(object a, object b)
        {
-               /// <summary>
-               /// The Calendar Constructor
-               /// </summary>
-               protected Calendar () 
-               {
-                       _MaxDateTime = DateTime.MaxValue;
-                       _MinDateTime = DateTime.MinValue;
-               }
-               [CLSCompliant(false)]
-               protected int _TwoDigitYearMax;
-
-               [CLSCompliant(false)]
-               protected static int[] _DaysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-               [CLSCompliant(false)]
-               protected static int[] _DaysInMonthLeap = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-               
-
-               // these can be overridden, for example using "new protected const int _MinYear = 1;"
-               [CLSCompliant(false)]
-               protected const int _MinYear = 1;
-               [CLSCompliant(false)]
-               protected const int _MaxYear = 9999;
-               [CLSCompliant(false)]
-               protected const int _MinDay = 0;
-               [CLSCompliant(false)]
-               protected const int _MinMonth = 1;
-               [CLSCompliant(false)]
-               protected const int _MaxMonth = 12;
-               [CLSCompliant(false)]
-               protected const int _MinHour = 0;
-               [CLSCompliant(false)]
-               protected const int _MaxHour = 23;
-               [CLSCompliant(false)]
-               protected const int _MinMinute = 0;
-               [CLSCompliant(false)]
-               protected const int _MaxMinute = 59;
-               [CLSCompliant(false)]
-               protected const int _MinSecond = 0;
-               [CLSCompliant(false)]
-               protected const int _MaxSecond = 59;
-               [CLSCompliant(false)]
-               protected const int _MinMillisecond = 0;
-               [CLSCompliant(false)]
-               protected const int _MaxMillisecond = 999;
-
-               [CLSCompliant(false)]
-               private const long _TicksPerMillisecond = 10000;
-               [CLSCompliant(false)]
-               private const long _TicksPerSecond = 10000000;
-               [CLSCompliant(false)]
-               private const long _TicksPerMinute = 600000000;
-               [CLSCompliant(false)]
-               private const long _TicksPerHour = 36000000000;
-               [CLSCompliant(false)]
-               private const long _TicksPerDay = 864000000000;
-               [CLSCompliant(false)]
-               private const long _TicksPerWeek = 6048000000000;
-
-               [CLSCompliant(false)]
-               protected DateTime _MaxDateTime;
-               [CLSCompliant(false)]
-               protected DateTime _MinDateTime;
-
-               
-               /// <summary>
-               /// The Currentera constant
-               /// </summary>
-               public const int CurrentEra = 0;
-               
-               /// <summary>
-               /// Returns an array of the available eras
-               /// </summary>
-               public abstract int[] Eras {get;}
-
-               // DONE!
-               /// <summary>
-               /// The Two digit max
-               /// </summary>
-               public virtual int TwoDigitYearMax 
-               {
-                       get
-                       {
-                               return _TwoDigitYearMax;
-                       } 
-                       set
-                       {
-                               _TwoDigitYearMax = value;
+               StringWriter sw = new StringWriter();
+               sw.Write("Valid values are between {0} and {1}, inclusive.",
+                       a, b);
+               return sw.ToString();
+       }
+
+       /// <summary>
+       /// The protected method checks wether the parameter
+       /// <paramref name="arg"/> is in the allowed range.
+       /// </summary>
+       /// <param name="param">A string that gives the name of the
+       /// parameter to check.</param>
+       /// <param name="arg">An integer that gives the value to check.
+       /// </param>
+       /// <param name="a">An integer that represents the smallest allowed
+       /// value.</param>
+       /// <param name="b">An integer that represents the greatest allowed
+       /// value.</param>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the <paramref name="arg"/> is outside
+       /// the allowed range.
+       /// </exception>
+       protected void M_ArgumentInRange(string param, int arg, int a, int b)
+       {
+               if (a <= arg && arg <= b)
+                       return;
+               throw new ArgumentOutOfRangeException(param, M_ValidValues(a, b));
+       }
+
+       /// <summary>
+       /// The protected method, that checks whether
+       /// <paramref name="hour"/>, <paramref name="minute"/>,
+       /// <paramref name="second"/>, and <parameref name="millisecond"/>
+       /// are in their valid ranges
+       /// </summary>
+       /// <param name="hour">An integer that represents a hour, 
+       /// should be between 0 and 23.</param>
+       /// <param name="minute">An integer that represents a minute,
+       /// should be between 0 and 59.</param>
+       /// <param name="second">An integer that represents a second,
+       /// should be between 0 and 59.</param>
+       /// <param name="milliseconds">An integer that represents a number
+       /// of milliseconds, should be between 0 and 999999.</param>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The Exception is thrown, if one of the parameter is outside the
+       /// allowed the range.
+       /// </exception>
+       protected void M_CheckHMSM(int hour, int minute, int second,
+               int milliseconds)
+       {
+               M_ArgumentInRange("hour", hour, 0, 23);
+               M_ArgumentInRange("minute", minute, 0, 59);
+               M_ArgumentInRange("second", second, 0, 59);
+               M_ArgumentInRange("milliseconds", milliseconds, 0, 999999);
+       }
+
+       /// <value>
+       /// A represantation of the CurrentEra.
+       /// </value>
+       public const int CurrentEra = 0;
+
+       /// <value>When overridden gives the eras supported by the
+       /// calendar as an array of integers.
+       /// </value>
+       public abstract int[] Eras { get; }
+
+       /// <summary>
+       /// The protected member stores the value for the
+       /// <see cref="P:TwoDigitYearMax"/>
+       /// property.
+       /// </summary>
+       protected int M_TwoDigitYearMax;
+       
+
+       /// <summary>
+       /// Private field containing the maximum year for the calendar.
+       /// </summary>
+       private int M_MaxYearValue = 0;
+
+       /// <value>
+       /// Get-only property returing the maximum allowed year for this
+       /// class.
+       /// </value>
+       protected virtual int M_MaxYear {
+               get {
+                       if (M_MaxYearValue == 0) {
+                               M_MaxYearValue = GetYear(DateTime.MaxValue);
                        }
+                       return M_MaxYearValue;
                }
+       }
 
-               // DONE!
-               public virtual DateTime AddDays ( DateTime time, int days )
-               {
-                       return new DateTime(time.Ticks).AddTicks(_TicksPerDay*days);
+       /// <summary>
+       /// Checks whether the year is the era is valid, if era = CurrentEra
+       /// the right value is set.
+       /// </summary>
+       /// <param name="year">The year to check.</param>
+       /// <param name="era">The era to check.</Param>
+       /// <exception cref="T:ArgumentOutOfRangeException">
+       /// The exception will be thrown, if the year is not valid.
+       /// </exception>
+       protected abstract void M_CheckYE(int year, ref int era);
+
+       /// <value>
+       /// <para>The property gives the maximum value for years with two
+       /// digits. If the property has the value 2029, than the two-digit
+       /// integer 29 results in the year 2029 and 30 in the 
+       /// year 1930.</para>
+       /// <para>It might be overridden.</para>
+       /// </value>
+       public virtual int TwoDigitYearMax {
+               get { return M_TwoDigitYearMax; }
+               set {
+                       M_ArgumentInRange("year", value, 100, M_MaxYear);
+                       int era = CurrentEra;
+                       M_CheckYE(value, ref era);
+                       M_TwoDigitYearMax = value;
                }
+       }
 
-               // DONE!
-               public virtual DateTime AddHours ( DateTime time, int hours )
-               {
-                       return new DateTime(time.Ticks).AddTicks(_TicksPerHour*hours);
-               }
+       /// <summary>
+       /// The virtual method adds days to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// days.
+       /// </param>
+       /// <param name="days">The number of days to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="days"/> to the specified
+       /// DateTime.</returns>
+       public virtual DateTime AddDays(DateTime time, int days) {
+               return time.Add(TimeSpan.FromDays(days));
+       }
 
-               // DONE!
-               public virtual DateTime AddMilliseconds ( DateTime time, double milliseconds )
-               {
-                       DateTime t = new DateTime(time.Ticks);
-                       return t.AddMilliseconds(milliseconds);
-               }
+       /// <summary>
+       /// The virtual method adds hours to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// hours.
+       /// </param>
+       /// <param name="hours">The number of hours to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="hours"/> to the specified
+       /// DateTime.</returns>
+       public virtual DateTime AddHours(DateTime time, int hours) {
+               return time.Add(TimeSpan.FromHours(hours));
+       }
 
-               // DONE!
-               public virtual DateTime AddMinutes ( DateTime time, int minutes )
-               {
-                       return new DateTime(time.Ticks).AddTicks(_TicksPerMinute * minutes);
-               }
+       /// <summary>
+       /// The virtual method adds milliseconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// milliseconds.
+       /// </param>
+       /// <param name="milliseconds">The number of milliseconds given as
+       /// double to add. Keep in mind the 100 nanosecond resolution of 
+       /// <see cref="T:System.DateTime"/>.
+       /// </param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="milliseconds"/> to the specified
+       /// DateTime.</returns>
+       public virtual DateTime AddMilliseconds(DateTime time,
+               double milliseconds)
+       {
+               return time.Add(TimeSpan.FromMilliseconds(milliseconds));
+       }
 
-               // DONE!
-               /// <summary>
-               /// Returns a DateTime that is the specified number of months away from the specified DateTime
-               /// </summary>
-               /// <param name="time"></param>
-               /// <param name="months"></param>
-               /// <returns></returns>
-               /// <remarks>Calculates correct comapared to .NET Beta 2</remarks>
-               public virtual DateTime AddMonths ( DateTime time, int months )         
-               {
-                       DateTime t = new DateTime(time.Ticks);
-                       return t.AddMonths(months);
-               }
+       /// <summary>
+       /// The virtual method adds minutes to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// minutes.
+       /// </param>
+       /// <param name="minutes">The number of minutes to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="minutes"/> to the specified
+       /// DateTime.</returns>
+       public virtual DateTime AddMinutes(DateTime time, int minutes) {
+               return time.Add(TimeSpan.FromMinutes(minutes));
+       }
 
-               // DONE!
-               public virtual DateTime AddSeconds ( DateTime time, int seconds )               
-               {
-                       return new DateTime(time.Ticks).AddTicks(_TicksPerSecond * seconds);
-               }
+       /// <summary>
+       /// When overrideden adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       public abstract DateTime AddMonths(DateTime time, int months);
 
-               // DONE!
-               public virtual DateTime AddWeeks ( DateTime time, int weeks )           
-               {
-                       return new DateTime(time.Ticks).AddTicks(_TicksPerWeek * weeks);
-               }
+       /// <summary>
+       /// The virtual method adds seconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// seconds.
+       /// </param>
+       /// <param name="seconds">The number of seconds to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="seconds"/> to the specified
+       /// DateTime.</returns>
+       public virtual DateTime AddSeconds(DateTime time, int seconds) {
+               return time.Add(TimeSpan.FromSeconds(seconds));
+       }
 
-               // DONE!
-               public virtual DateTime AddYears ( DateTime time, int years )           
-               {
-                       DateTime t = new DateTime(time.Ticks);
-                       return t.AddYears(years);
-               }
+       /// <summary>
+       /// A wirtual method that adds weeks to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// weeks.
+       /// </param>
+       /// <param name="weeks">The number of weeks to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="weeks"/> to the specified
+       /// DateTime.</returns>
+       public virtual DateTime AddWeeks(DateTime time, int weeks) {
+               return time.AddDays(weeks * M_DaysInWeek);
+       }
 
-               
+       /// <summary>
+       /// When overrideden adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       public abstract DateTime AddYears(DateTime time, int years);
 
-               // DONE!
-               public abstract int GetDayOfMonth ( DateTime time );
+       /// <summary>
+       /// When overriden gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public abstract int GetDayOfMonth(DateTime time);
 
-               // DONE!
-               public abstract DayOfWeek GetDayOfWeek ( DateTime time );
+       /// <summary>
+       /// When overriden gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public abstract DayOfWeek GetDayOfWeek(DateTime time);
 
-               // DONE!
-               public abstract int GetDayOfYear ( DateTime time );
+       /// <summary>
+       /// When overridden gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       public abstract int GetDayOfYear(DateTime time);
 
-               // DONE!
-               public virtual int GetDaysInMonth ( int year, int month )
-               {
-                       if(year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// A virtual method that gives the number of days of the specified
+       /// month of the <paramref name="year"/> and the
+       /// <see cref="P:CurrentEra"/>.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the current
+       /// era.</param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/> or
+       /// <paramref name="year"/> is outside the allowed range.
+       /// </exception>
+       public virtual int GetDaysInMonth(int year, int month) {
+               return GetDaysInMonth(year, month, CurrentEra);
+       }
 
-                       if(this.IsLeapYear(year))
-                               return _DaysInMonthLeap[month];
-                       else
-                               return _DaysInMonth[month];
-               }
+       /// <summary>
+       /// When overridden gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An intger that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public abstract int GetDaysInMonth(int year, int month, int era);
 
-               // DONE!
-               public abstract int GetDaysInMonth ( int year, int month, int era );
+       /// <summary>
+       /// A virtual method that gives the number of days of the specified
+       /// year of the <see cref="P:CurrentEra"/>.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the current
+       /// era.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> is outside the allowed range.
+       /// </exception>
+       public virtual int GetDaysInYear(int year) {
+               return GetDaysInYear(year, CurrentEra);
+       }
 
-               // DONE!
-               public virtual int GetDaysInYear ( int year)
-               {
-                       if( year < _MinYear || year > _MaxYear)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// When overridden gives the number of days of the specified
+       /// year of the given era.. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> is outside the allowed range.
+       /// </exception>
+       public abstract int GetDaysInYear(int year, int era);
 
-                       if(this.IsLeapYear(year))
-                               return 366;
-                       else
-                               return 365;
-               }
+       /// <summary>
+       /// When overridden gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       public abstract int GetEra(DateTime time);
 
-               // DONE!
-               public abstract int GetDaysInYear ( int year, int era );
-               
-               // DONE!
-               public abstract int GetEra ( DateTime time );
-               
-               // DONE!
-               public virtual int GetHour ( DateTime time )
-               {
-                       return time.Hour;
-               }
-               // DONE!
-               public virtual double GetMilliseconds ( DateTime time )
-               {
-                       return time.Millisecond;
-               }
-               // DONE!
-               public virtual int GetMinute ( DateTime time )
-               {
-                       return time.Minute;
+       /// <summary>
+       /// Virtual method that gives the hour of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the hour of the specified time,
+       /// starting with 0.</returns>
+       public virtual int GetHour(DateTime time) {
+               return time.TimeOfDay.Hours;
+       }
+
+       /// <summary>
+       /// Virtual method that gives the milliseconds in the current second
+       /// of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the milliseconds in the seconds
+       /// of the specified time, starting with 0.</returns>
+       public virtual double GetMilliseconds(DateTime time) {
+               return time.TimeOfDay.Milliseconds;
+       }
+
+       /// <summary>
+       /// Virtual method that gives the minute of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the minute of the specified time,
+       /// starting with 0.</returns>
+       public virtual int GetMinute(DateTime time) {
+               return time.TimeOfDay.Minutes;
+       }
+
+       /// <summary>
+       /// When overridden gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       public abstract int GetMonth(DateTime time);
+
+       /// <summary>
+       /// Virtual method that gives the number of months of the specified
+       /// year of the <see cref="M:CurrentEra"/>.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// current era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year is not allowed in the
+       /// current era.
+       /// </exception>
+       public virtual int GetMonthsInYear(int year) {
+               return GetMonthsInYear(year, CurrentEra);
+       }
+
+       /// <summary>
+       /// When overridden gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public abstract int GetMonthsInYear(int year, int era);
+
+       /// <summary>
+       /// Virtual method that gives the second of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the second of the specified time,
+       /// starting with 0.</returns>
+       public virtual int GetSecond(DateTime time) {
+               return time.TimeOfDay.Seconds;
+       }
+
+       /// <summary>
+       /// A protected method to calculate the number of days between two
+       /// dates.
+       /// </summary>
+       /// <param name="timeA">A <see cref="T:System.DateTime"/>
+       /// representing the first date.
+       /// </param>
+       /// <param name="timeB">A <see cref="T:System.DateTime"/>
+       /// representing the second date.
+       /// </param>
+       /// <returns>An integer that represents the difference of days
+       /// between <paramref name="timeA"/> and <paramref name="timeB"/>.
+       /// </returns>
+       protected int M_DiffDays(DateTime timeA, DateTime timeB) {
+               long diff = timeA.Ticks - timeB.Ticks;
+
+               if (diff >= 0) {
+                       return (int)(diff/TimeSpan.TicksPerDay);
                }
 
-               // DONE!
-               public abstract int GetMonth ( DateTime time );
-               
-               // DONE!
-               public virtual int GetMonthsInYear ( int year )
-               {
-                       if( year < _MinYear || year > _MaxYear)
-                               throw new System.ArgumentException();
+               diff += 1;
+               return -1 + (int)(diff/TimeSpan.TicksPerDay);
+       }
+
+       /// <summary>
+       /// A protected method that gives the first day of the second week of
+       /// the year.
+       /// </summary>
+       /// <param name="year">An integer that represents the year.</param>
+       /// <param name="rule">The
+       /// <see cref="T:System.Globalization.CalendarWeekRule"/>
+       /// to be used for the calculation.
+       /// </param>
+       /// <param name="firstDayOfWeek">
+       /// The <see cref="T:System.Globalization.DayOfWeek"/>
+       /// specifying the first day in a week.
+       /// </param>
+       /// <returns>The <see cref="T:System.DateTime"/> representing 
+       /// the first day of the second week of the year.
+       /// </returns>
+       protected DateTime M_GetFirstDayOfSecondWeekOfYear(
+               int year, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
+       {
+               DateTime d1 = ToDateTime(year, 1, 1, 0, 0, 0, 0);
+               int dow1 = (int)GetDayOfWeek(d1);
+               int fdow = (int)firstDayOfWeek;
+               int d = 0;
+
+               switch (rule) {
+               case CalendarWeekRule.FirstDay:
+                       if (fdow > dow1) {
+                               d += fdow - dow1;
+                       }
+                       else {
+                               d += fdow + M_DaysInWeek - dow1;
+                       }
+                       break;
+               case CalendarWeekRule.FirstFullWeek:
+                       d = M_DaysInWeek;
+                       if (fdow >= dow1) {
+                               d += fdow - dow1;
+                       }
+                       else {
+                               d += fdow + M_DaysInWeek - dow1;
+                       }
+                       break;
+               case CalendarWeekRule.FirstFourDayWeek:
+                       int dow4 = (dow1 + 3)%M_DaysInWeek;
 
-                       return _MaxMonth;
+                       d = 3;
+                       if (fdow > dow4) {
+                               d += fdow - dow4;
+                       }
+                       else {
+                               d += fdow + M_DaysInWeek - dow4;
+                       }
+                       break;
                }
 
-               // DONE!
-               public abstract int GetMonthsInYear ( int year, int era );
+               return AddDays(d1, d);
+       }
 
-               // DONE!
-               public virtual int GetSecond ( DateTime time )
+       /// <summary>
+       /// A virtual method that gives the number of the week in the year.
+       /// </summary>
+       /// <param name="time">A 
+       /// <see cref="T:System.DateTime"/> representing the date.
+       /// </param>
+       /// <param name="rule">The
+       /// <see cref="T:System.Globalization.CalendarWeekRule"/>
+       /// to be used for the calculation.
+       /// </param>
+       /// <param name="firstDayOfWeek">
+       /// The <see cref="T:System.Globalization.DayOfWeek"/>
+       /// specifying the first day in a week.
+       /// </param>
+       /// <returns>An integer representing the number of the week in the
+       /// year, starting with 1.
+       /// </returns>
+       public virtual int GetWeekOfYear(DateTime time,
+               CalendarWeekRule rule, 
+               DayOfWeek firstDayOfWeek)
+       {
+               if (firstDayOfWeek < DayOfWeek.Sunday ||
+                   DayOfWeek.Saturday < firstDayOfWeek)
                {
-                       return time.Second;
+                       throw new ArgumentOutOfRangeException("firstDayOfWeek",
+                               "Value is not a valid day of week.");
                }
+               int year = GetYear(time);
 
-               // DONE!
-               /// <summary>
-               /// Gets the week of the year that includes the date in the specified DateTime
-               /// </summary>
-               /// <param name="time"></param>
-               /// <param name="rule"></param>
-               /// <param name="firstDayOfWeek"></param>
-               /// <returns></returns>
-               /// <remarks>.NET beta 2 calculates this erroneous, but this one is ok(? I think...)</remarks>
-               public virtual int GetWeekOfYear ( DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek )
-               {
-                       if( firstDayOfWeek < DayOfWeek.Sunday || firstDayOfWeek > DayOfWeek.Saturday)
-                               throw new System.ArgumentOutOfRangeException();
-                       
-                       int week;
-                       int days = 0;
-                       
-                       int[] dim;
-                       if(this.IsLeapYear(time.Year))
-                               dim = _DaysInMonthLeap;
-                       else
-                               dim = _DaysInMonth;
-
-                       DateTime jan1 = new DateTime(time.Year, 1, 1);
-
-                       for( int i = 0; i < time.Month-1; i++)
-                               days += dim[i];
-                       days += time.Day;
-
-                       switch(rule)
-                       {
-                               case CalendarWeekRule.FirstDay:
-                                       while(jan1.DayOfWeek != firstDayOfWeek)
-                                       {
-                                               days--;
-                                               jan1 = jan1.AddTicks(_TicksPerDay);
-                                       }
-                                       break;
-                               case CalendarWeekRule.FirstFourDayWeek:
-                                       while(jan1.DayOfWeek < firstDayOfWeek)
-                                       {
-                                               days--;
-                                               jan1 = jan1.AddTicks(_TicksPerDay);
-                                       }
-                                       break;
-                               case CalendarWeekRule.FirstFullWeek:
-                                       if(jan1.DayOfWeek != firstDayOfWeek)
-                                       {
-                                               do
-                                               {
-                                                       days--;
-                                                       jan1 = jan1.AddTicks(_TicksPerDay);
-                                               }
-                                               while(jan1.DayOfWeek != firstDayOfWeek);
-                                       }
-                                       break;
-                               default:
-                                       throw new System.ArgumentOutOfRangeException();
-                       }
+               int days;
 
-                       if(days <= 0)
-                               week = GetWeekOfYear(new DateTime(time.Year-1,12,31), rule, firstDayOfWeek);
-                       else
-                               week = (--days / 7) + 1;
-                       
-                       return week;
+               while (true) {
+                       DateTime secondWeek = M_GetFirstDayOfSecondWeekOfYear(
+                               year, rule, firstDayOfWeek);
+                       days = M_DiffDays(time, secondWeek) + M_DaysInWeek;
+                       if (days >= 0)
+                               break;
+                       year -= 1;
                }
 
-               // DONE!
-               public abstract int GetYear ( DateTime time );
-               
-               // DONE!
-               // TODO: verify this for the Calendar Class
-               public virtual bool IsLeapDay ( int year, int month, int day )
-               {
-                       int dim;
+               return 1 + days/M_DaysInWeek;
+       }
 
-                       if(day < _MinDay || month < _MinMonth || month > _MaxMonth)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// When overridden gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       public abstract int GetYear(DateTime time);
 
-                       if(this.IsLeapYear(year))
-                               dim = _DaysInMonthLeap[month-1];
-                       else
-                               dim = _DaysInMonth[month-1];
+       /// <summary>
+       /// A virtual method that tells whether the given day in the
+       /// <see cref="M:CurrentEra"/> is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// current era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month or day is not valid
+       /// the current era.
+       /// </exception>
+       public virtual bool IsLeapDay(int year, int month, int day) {
+               return IsLeapDay(year, month, day, CurrentEra);
+       }
 
-                       if( day > dim)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// Tells when overridden whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       public abstract bool IsLeapDay(int year, int month, int day, int era);
 
-                       if( month == 2 && day == 29)
-                               return true;
-                       
-                       return false;
-               }
+       /// <summary>
+       /// A virtual method that tells whether the given month of the
+       /// specified year in the
+       /// <see cref="M:CurrentEra"/> is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// current era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or month is not valid
+       /// the current era.
+       /// </exception>
+       public virtual bool IsLeapMonth(int year, int month) {
+               return IsLeapMonth(year, month, CurrentEra);
+       }
 
-               // DONE!
-               public abstract bool IsLeapDay ( int year, int month, int day, int era );
+       /// <summary>
+       /// Tells when overridden whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public abstract bool IsLeapMonth(int year, int month, int era);
 
-               // DONE!
-               public virtual bool IsLeapMonth ( int year, int month )
-               {
-                       if( year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// A virtual method that tells whether the given year
+       /// in the
+       /// <see cref="M:CurrentEra"/> is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// current era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year is not valid
+       /// the current era.
+       /// </exception>
+       public virtual bool IsLeapYear(int year) {
+               return IsLeapYear(year, CurrentEra);
+       }
 
-                       if(this.IsLeapYear(year))
-                       {
-                               return true;
-                       }
-                       else
-                               return false;
-               }
-               
-               // DONE!
-               public abstract bool IsLeapMonth ( int year, int month, int era );
+       /// <summary>
+       /// Tells when overridden whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public abstract bool IsLeapYear(int year, int era);
 
-               public virtual bool IsLeapYear ( int year )
-               {
-                       if(year < _MinYear || year > _MaxYear )
-                               throw new System.ArgumentOutOfRangeException();
-                       if(year % 4 == 0) // TODO: verify this for the Calendar class!
-                               return true;
-                       return false;
-               }
+       /// <summary>
+       /// A virtual method that creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <see cref="M:CurrentEra"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       public virtual DateTime ToDateTime(int year, int month, int day,
+               int hour, int minute, int second, int milliseconds)
+       {
+               return ToDateTime(year, month, day, hour, minute, second, 
+                       milliseconds, CurrentEra);
+       }
 
-               // DONE!
-               public abstract bool IsLeapYear ( int year, int era );
 
-               // DONE!
-               public virtual DateTime ToDateTime ( int year, int month, int day, int hour, int minute, int second, int millisecond )
-               {
-                       int dim;
-                       dim = GetDaysInMonth(year,month);
-                       if( day < _MinDay || day > dim || 
-                               hour < _MinHour || hour > _MaxHour ||
-                               minute < _MinMinute || minute > _MaxMinute ||
-                               second < _MinSecond || second > _MaxSecond ||
-                               millisecond < _MinMillisecond || millisecond > _MaxMillisecond)
-                               throw new System.ArgumentOutOfRangeException();
-
-                       return new DateTime(year,month,day,hour,minute,second,millisecond,this);
+       /// <summary>
+       /// When overridden creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       public abstract DateTime ToDateTime(int year, int month, int day,
+               int hour, int minute, int second, int milliseconds,
+               int era);
+
+       /// <summary>
+       /// A virtual method that converts a two-digit year to a four-digit
+       /// year. It uses the <see cref="M:TwoDigitYearMax"/> property.
+       /// </summary>
+       /// <param name="year">An integer that gives the two-digit year.
+       /// </param>
+       /// <returns>An integer giving the four digit year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the year is negative or the resulting 
+       /// year is invalid.
+       /// </exception>
+       public virtual int ToFourDigitYear(int year) {
+               if (year < 0)
+                       throw new ArgumentOutOfRangeException(
+                               "year", "Non-negative number required.");
+               /* seems not to be the right thing to do, but .NET is
+                * doing it this way.
+                */
+               if (year <= 99) {
+                       int year2 = TwoDigitYearMax%100;
+                       int d = year - year2;
+                       year = TwoDigitYearMax + d + (d <= 0 ? 0 : -100); 
                }
+               int era = CurrentEra;
+               M_CheckYE(year, ref era);
+               return year;
+       }
+
+       // TwoDigitYearMax: Windows reads it from the Registry, we
+       // should have an XML file with the defaults
+       /// <summary>
+       /// The default constructor, is sets the TwoDigitYearMax to 2029.
+       /// </summary>
+       /// <remarks>
+       /// The .NET framework reads the value from the registry.
+       /// We should implement it here. Currently I set the default values
+       /// in the ctors of the derived classes, if it is 99.
+       /// </remarks>
+       protected Calendar() {
+               M_TwoDigitYearMax = 99;
+       }
 
-               // DONE!
-               public abstract DateTime ToDateTime ( int year, int month, int date, int hour, int minute, int second, int millisecond, int era );
+       /// <summary>Protected field storing the abbreviated era names.
+       /// </summary>
+       protected string[] M_AbbrEraNames;
+       /// <summary>Protected field storing the era names.
+       /// </summary>
+       protected string[] M_EraNames;
+
+       /// <value>
+       /// The property stores the era names. It might be overwritten by
+       /// CultureInfo.
+       /// </value>
+       internal string[] AbbreviatedEraNames {
+               get {
+                       if (M_AbbrEraNames == null ||
+                           M_AbbrEraNames.Length != Eras.Length)
+                               throw new Exception(
+                                       "Internal: M_AbbrEraNames " +
+                                       "wrong initialized!");
+                       return (string[])M_AbbrEraNames.Clone();
+               }
+               set {
+                       if (value.Length != Eras.Length) {
+                               StringWriter sw = new StringWriter();
+                               sw.Write("Array length must be equal Eras " +
+                                       "length {0}.", Eras.Length);
+                               throw new ArgumentException(
+                                       sw.ToString());
+                       } 
+                       M_AbbrEraNames = (string[])value.Clone();
+               }
+       }
 
-               // DONE!
-               public virtual int ToFourDigitYear ( int year )
-               {
-                       int i = year - ( _TwoDigitYearMax % 100 );
-                       if( year > 0 )
-                               return _TwoDigitYearMax - 100 + year;
-                       else
-                               return _TwoDigitYearMax + year;
+       /// <value>
+       /// The property stores the era names. It might be overwritten by
+       /// CultureInfo.
+       /// </value>
+       internal string[] EraNames {
+               get {
+                       if (M_EraNames == null ||
+                           M_EraNames.Length != Eras.Length)
+                               throw new Exception(
+                                       "Internal: M_EraNames " +
+                                       "not initialized!");
+                       return (string[])M_EraNames.Clone();
+               }
+               set {
+                       if (value.Length != Eras.Length) {
+                               StringWriter sw = new StringWriter();
+                               sw.Write("Array length must be equal Eras " +
+                                       "length {0}.", Eras.Length);
+                               throw new ArgumentException(
+                                       sw.ToString());
+                       } 
+                       M_EraNames = (string[])value.Clone();
                }
        }
-}
+} // class Calendar
+       
+} // namespace System.Globalization
index 1bdf99bf62b842f268a4a48a5f7567ca7dfc7252..d9ece2c6238a27d89ebdf0d094018df1599a9cea 100644 (file)
-// ::MONO
-//
-// System.Globalization.GregorianCalendar.cs
-//
-// Copyright (C) Wictor Wilén 2001 (wictor@iBizkit.se)
-//
-// Contributors: Wictor Wilén
-//
-// Revisions
-// 2001-09-15: First draft
-//
-//
-// TODO: testing
+// GregorianCalendar.cs
 //
+// (C) Ulrich Kunitz 2002
 //
 
-using System;
+namespace System.Globalization {
 
-namespace System.Globalization
-{
+using System;
 
-       
+/// <summary>
+/// This is the Gregorian calendar.
+/// </summary>
+/// <remarks>
+/// <para>The Gregorian calendar supports only the Common Era from
+/// the Gregorian year 1 to the Gregorian year 9999.
+/// </para>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class GregorianCalendar : Calendar {
        /// <summary>
-       /// Represents the Gregorian calendar.
+       /// The era number for the Common Era (C.E.) or Anno Domini (A.D.)
+       /// respective.
        /// </summary>
-       /// <remarks>The Gregorian calendar recognizes two eras: B.C. (before Christ) or B.C.E. (before common era), and A.D. (Latin "Anno Domini", which means "in the year of the Lord") or C.E. (common era). This implementation of the GregorianCalendar class recognizes only the current era (A.D. or C.E.).</remarks>
-       // TODO: implement the BC era
-       [MonoTODO]
-       public class GregorianCalendar : Calendar
-       {
-               // private members
-               private GregorianCalendarTypes _CalendarType;
-
+       public const int ADEra = 1;
 
-               // Public Constants
-               public const int ADEra = 1;
-               
-               // Public Instance Constructors
-               // DONE!
-               public GregorianCalendar()
-               {
-                       _CalendarType = GregorianCalendarTypes.Localized;
+       /// <value>Overridden. Gives the eras supported by the Gregorian
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return new int[] { ADEra }; 
                }
+       }
 
-               // DONE!
-               public GregorianCalendar(GregorianCalendarTypes type)
-               {
-                       _CalendarType = type;
-               }
-               
-               // DONE!
-               public GregorianCalendarTypes CalendarType 
-               {
-                       get
-                       {
-                               return _CalendarType;
-                       } 
-                       set
-                       {
-                               _CalendarType = value;
-                       }
-               }
+       /// <summary>
+       /// A protected member storing the
+       /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>.
+       /// </summary>
+       protected GregorianCalendarTypes M_CalendarType;
 
-               // Public Instance Properties
-               // DONE!
-               public override int[] Eras 
-               {
-                       get
-                       {
-                               return new int[] {1};
-                       }
-               }
-               // DONE!
-               public override int TwoDigitYearMax 
-               {
-                       get
-                       {
-                               return _TwoDigitYearMax;
-                       } 
-                       set
-                       {
-                               _TwoDigitYearMax = value;
-                       }
+       /// <value>
+       /// The property stores the 
+       /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>.
+       /// </value>
+       public virtual GregorianCalendarTypes CalendarType {
+               get { return M_CalendarType; }
+               set { 
+                       // mscorlib 1:0:33000:0 doesn't check anything here
+                       M_CalendarType = value;
                }
+       }
 
-               // Public Instance Methods
-               // DONE!
-               public override DateTime AddMonths ( DateTime time, int months )
-               {
-                       if(months < -120000 || months > 120000)
-                               throw new System.ArgumentOutOfRangeException();
-                       DateTime dt = new DateTime(time.Ticks);                 
-                       dt =  dt.AddMonths(months);
-                       return dt;
-                       
-               }
-               // DONE!
-               public override DateTime AddYears ( DateTime time, int years )
-               {
-                       DateTime dt = new DateTime(time.Ticks);
-                       return dt.AddYears(years);
-               }
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:ADEra"/>.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = ADEra;
+               if (era != ADEra)
+                       throw new ArgumentException("Era value was not valid.");
+       }
 
-               // DONE!
-               public override int GetDayOfMonth ( DateTime time )
-               {
-                       return time.Day;
-               }
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:ADEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the allowed range.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckEra(ref era);
+               M_ArgumentInRange("year", year, 1, 9999);
+       }
 
-               // DONE!
-               public override DayOfWeek GetDayOfWeek ( DateTime time )
-               {
-                       return time.DayOfWeek;
-               }
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:ADEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the allowed range.
+       /// </exception>
+       protected 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.");
+       }
 
-               // DONE!
-               public override int GetDayOfYear ( DateTime time )
-               {
-                       return time.DayOfYear;
-               }
-               
-               // DONE!
-               public override int GetDaysInMonth ( int year, int month, int era )
-               {
-                       if(     year < _MinYear || year > _MaxYear || 
-                               month < _MinMonth || month > _MaxMonth )                                
-                               throw new System.ArgumentOutOfRangeException();
-
-                       if( era != ADEra)
-                               throw new System.ArgumentException();
-
-                       if(this.IsLeapYear(year))
-                               return _DaysInMonthLeap[month];
-                       else
-                               return _DaysInMonth[month];
-               }
-               
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:ADEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the allowed range.
+       /// </exception>
+       protected 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, era));
+       }
 
-               // DONE!                
-               public override int GetDaysInYear ( int year, int era )
-               {
-                       if(year < _MinYear || year > _MaxYear)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// Overridden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddMonths(DateTime time, int months) {
+               return CCGregorianCalendar.AddMonths(time, months);
+       }
 
-                       if( era != ADEra)
-                               throw new System.ArgumentException();
+       /// <summary>
+       /// Overridden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddYears(DateTime time, int years) {
+               return CCGregorianCalendar.AddYears(time, years);
+       }
+               
+       /// <summary>
+       /// Overridden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override int GetDayOfMonth(DateTime time) {
+               return CCGregorianCalendar.GetDayOfMonth(time);
+       }
 
-                       return this.GetDaysInYear(year);
-               }
+       /// <summary>
+       /// Overridden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
 
-               // DONE!
-               public override int GetEra ( DateTime time )
-               {
-                       return ADEra;
-               }
-               // DONE!
-               public override int GetMonth ( DateTime time )
-               {
-                       return time.Month;
-               }
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       public override int GetDayOfYear(DateTime time) {
+               return CCGregorianCalendar.GetDayOfYear(time);
+       }
 
-               // DONE!                
-               public override int GetMonthsInYear ( int year, int era )
-               {
-                       if(year < _MinYear || year > _MaxYear || era != ADEra )
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An intger that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public override int GetDaysInMonth(int year, int month, int era) {
+               // mscorlib doesn't check year, probably a bug; we do
+               M_CheckYME(year, month, ref era);
+               return CCGregorianCalendar.GetDaysInMonth(year, month);
+       }
 
-                       return _MaxMonth;
-               }
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> is outside the allowed range.
+       /// </exception>
+       public override int GetDaysInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return CCGregorianCalendar.GetDaysInYear(year);
+       }
                
-               // DONE!
-               public override int GetYear ( DateTime time )
-               {                       
-                       return time.Year;
-               }
 
-               // DONE!
-               public override bool IsLeapDay ( int year, int month, int day, int era )
-               {                       
-                       int dim;
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       public override int GetEra(DateTime time) {
+               return ADEra;
+       }
 
-                       if(day < _MinDay || month < _MinMonth || month > _MaxMonth)
-                               throw new System.ArgumentException();
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       public override int GetMonth(DateTime time) {
+               return CCGregorianCalendar.GetMonth(time);
+       }
 
-                       if(this.IsLeapYear(year,era))
-                               dim = _DaysInMonthLeap[month-1];
-                       else
-                               dim = _DaysInMonth[month-1];
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return 12;
+       }
 
-                       if( day > dim)
-                               throw new System.ArgumentException();
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       public override int GetYear(DateTime time) {
+               return CCGregorianCalendar.GetYear(time);
+       }
 
-                       if( month == 2 && day == 29)
-                               return true;
-                       
-                       return false;
-               }
-               // DONE!
-               public override bool IsLeapMonth ( int year, int month )
-               {
-                       if( year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
-                               throw new System.ArgumentException();
-                       return false;   
-               }
-               // DONE!
-               public override bool IsLeapMonth ( int year, int month, int era )
-               {
-                       if( year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth || era != ADEra)
-                               throw new System.ArgumentException();
-                       return false;
-               }
-               
-               // DONE!
-               public override bool IsLeapYear ( int year, int era )
-               {
-                       if(year < _MinYear || year > _MaxYear || era != ADEra)
-                               throw new System.ArgumentOutOfRangeException();
-                       if( ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0) )
-                               return true;
-                       return false;
-               }
-               
-               // DONE!
-               public override DateTime ToDateTime ( int year, int month, int day, int hour, int minute, int second, int millisecond, int era )
-               {
-                       // INFO: year, era and month is checked by GetDaysInMonth()
-                       int dim;
-                       dim = GetDaysInMonth(year,month);
-                       if( day < _MinDay || day > dim || 
-                               hour < _MinHour || hour > _MaxHour ||
-                               minute < _MinMinute || minute > _MaxMinute ||
-                               second < _MinSecond || second > _MaxSecond ||
-                               millisecond < _MinMillisecond || millisecond > _MaxMillisecond)
-                               throw new System.ArgumentException();
-
-                       return new DateTime(year,month,day,hour,minute,second,millisecond,this);
-               }
-               
-               // DONE!
-               public override int ToFourDigitYear ( int year )
-               {
-                       int y = _TwoDigitYearMax % 100;
-                       if( year > y )
-                               y = _TwoDigitYearMax - y - 100 + year;
-                       else
-                               y = _TwoDigitYearMax - y + year;
-
-                       if( y < _MinYear || y > _MaxYear)
-                               throw new System.ArgumentException();
-                       return y;
-               }
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapDay(int year, int month, int day, int era)
+       {
+               M_CheckYMDE(year, month, day, ref era);
+               return CCGregorianCalendar.IsLeapDay(year, month, day);
+       }
+
+
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYME(year, month, ref era);
+               return false;
+       }
 
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return CCGregorianCalendar.is_leap_year(year);
+       }
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       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);
+               return CCGregorianCalendar.ToDateTime(
+                       year, month, day,
+                       hour, minute, second, milliseconds);
        }
-}
+                                       
+       /// <summary>
+       /// Constructor that sets the
+       /// Gregorian calendar type (
+       /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>).
+       /// </summary>
+       /// <param name="type">The parameter specifies the Gregorian 
+       /// calendar type.
+       /// </param>
+       public GregorianCalendar(GregorianCalendarTypes type) {
+               CalendarType = type;
+               M_AbbrEraNames = new string[] {"C.E."};
+               M_EraNames = new string[] {"Common Era"};
+               if (M_TwoDigitYearMax == 99)
+                       M_TwoDigitYearMax = 2029;
+       }
+       
+       /// <summary>
+       /// Default constructor. Sets the Gregorian calendar type to 
+       /// <see
+       /// cref="F:System.Globalization.GregorianCalendarTypes.Localized"/>.
+       /// </summary>
+       public GregorianCalendar() : this(GregorianCalendarTypes.Localized) {}
+} // class GregorianCalendar
+       
+} // namespace System.Globalization
diff --git a/mcs/class/corlib/System.Globalization/HebrewCalendar.cs b/mcs/class/corlib/System.Globalization/HebrewCalendar.cs
new file mode 100644 (file)
index 0000000..62932fd
--- /dev/null
@@ -0,0 +1,861 @@
+// HebrewCalendar.cs
+//
+// (C) Ulrich Kunitz 2002
+//
+
+namespace System.Globalization {
+
+using System;
+using System.IO;
+
+/// <summary>
+/// This is the Hebrew calendar.
+/// </summary>
+/// <remarks>
+/// <para>The Hebrew calendar supports only years between 5343 A.M. and
+/// 6000 A.M. This has been done to be compatible with .NET.
+/// </para>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class HebrewCalendar : Calendar {
+       /// <summary>
+       /// Constructor.
+       /// </summary>
+       public HebrewCalendar() {
+               M_AbbrEraNames = new string[] {"A.M."};
+               M_EraNames = new string[] {"Anno Mundi"};
+               if (M_TwoDigitYearMax == 99)
+                       M_TwoDigitYearMax = 5790;
+       }
+
+       /// <summary>
+       /// The era number for the Anno Mundi (A.M.) era, called
+       /// plain HebrewEra.
+       /// </summary>
+       public const int HebrewEra = 1;
+
+       /// <summary>
+       /// The
+       /// <see cref="T:System.DateTime"/> ticks for first day of year
+       /// 5343 A.M.
+       /// </summary>
+       protected const long M_MinTicks = 499147488000000000L;
+       /// <summary>
+       /// The number of
+       /// <see cref="T:System.DateTime"/> ticks for the last day of year
+       /// 6000 A.M.
+       /// </summary>
+       protected const long M_MaxTicks = 706783967999999999L;
+       /// <summary>
+       /// The minimum year in the A.M. era supported.
+       /// </summary>
+       protected const int M_MinYear = 5343;
+       /// <summary>
+       /// The maximum year supported in the A.M. era.
+       /// </summary>
+       protected override int M_MaxYear {
+               get { return 6000; }
+       }
+
+       /// <value>Overridden. Gives the eras supported by the Gregorian
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return new int[] { HebrewEra }; 
+               }
+       }
+
+       /// <summary>
+       /// A protected member checking a
+       /// <see cref="T:System.DateTime"/> value.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/>
+       /// to check.
+       /// </param>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       protected void M_CheckDateTime(DateTime time) {
+               if (time.Ticks < M_MinTicks || time.Ticks > M_MaxTicks)
+                       throw new ArgumentOutOfRangeException(
+                               "time",
+                               "Only hebrew years between 5343 and 6000," +
+                               " inclusive, are supported.");
+       }
+
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HebrewEra"/>.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = HebrewEra;
+               if (era != HebrewEra)
+                       throw new ArgumentException("Era value was not valid.");
+       }
+
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HebrewEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the allowed range.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckEra(ref era);
+               if (year < M_MinYear || year > M_MaxYear)
+                       throw new ArgumentOutOfRangeException(
+                               "year",
+                               "Only hebrew years between 5343 and 6000," +
+                               " inclusive, are supported.");
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HebrewEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the allowed range.
+       /// </exception>
+       protected void M_CheckYME(int year, int month, ref int era) {
+               M_CheckYE(year, ref era);
+               int l = CCHebrewCalendar.last_month_of_year(year);
+               if (month < 1 || month > l) {
+                       StringWriter sw = new StringWriter();
+                       sw.Write("Month must be between 1 and {0}.", l);
+                       throw new ArgumentOutOfRangeException("month",
+                               sw.ToString());
+               }
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HebrewEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the allowed range.
+       /// </exception>
+       protected 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,
+                       era));
+       }
+
+       /// <summary>
+       /// Overridden. Adds days to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// days.
+       /// </param>
+       /// <param name="days">The number of days to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="days"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddDays(DateTime time, int days) {
+               DateTime t = base.AddDays(time, days);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds hours to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// hours.
+       /// </param>
+       /// <param name="hours">The number of hours to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="hours"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddHours(DateTime time, int hours) {
+               DateTime t = base.AddHours(time, hours);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds milliseconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// milliseconds.
+       /// </param>
+       /// <param name="milliseconds">The number of milliseconds given as
+       /// double to add. Keep in mind the 100 nanosecond resolution of 
+       /// <see cref="T:System.DateTime"/>.
+       /// </param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="milliseconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddMilliseconds(DateTime time,
+               double milliseconds)
+       {
+               DateTime t = base.AddMilliseconds(time, milliseconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds minutes to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// minutes.
+       /// </param>
+       /// <param name="minutes">The number of minutes to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="minutes"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddMinutes(DateTime time, int minutes) {
+               DateTime t = base.AddMinutes(time, minutes);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds seconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// seconds.
+       /// </param>
+       /// <param name="seconds">The number of seconds to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="seconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddSeconds(DateTime time, int seconds) {
+               DateTime t = base.AddSeconds(time, seconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds weeks to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// weeks.
+       /// </param>
+       /// <param name="weeks">The number of weeks to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="weeks"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddWeeks(DateTime time, int weeks) {
+               DateTime t = base.AddWeeks(time, weeks);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the hour of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the hour of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetHour(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetHour(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the milliseconds in the current second
+       /// of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the milliseconds in the seconds
+       /// of the specified time, starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override double GetMilliseconds(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMilliseconds(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the minute of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the minute of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetMinute(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the second of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the second of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetSecond(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overrideden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddMonths(DateTime time, int months) {
+               int y, m, d;
+               DateTime t;
+
+               if (months == 0) {
+                       t = time;
+               } else {
+                       int rd = CCFixed.FromDateTime(time);
+                       CCHebrewCalendar.dmy_from_fixed(
+                               out d, out m, out y, rd);
+                       m = M_Month(m, y);
+                       if (months < 0) {
+                               while (months < 0) {
+                                       if (m+months > 0) {
+                                               m += months;
+                                               months = 0;
+                                       } else {
+                                               months += m;
+                                               y -= 1;
+                                               m = GetMonthsInYear(y);
+                                       }
+                               }
+                       }
+                       else {
+                               while (months > 0) {
+                                       int my = GetMonthsInYear(y);
+                                       if (m+months <= my) {
+                                               m += months;
+                                               months = 0;
+                                       } else {
+                                               months -= my-m+1;
+                                               m = 1;
+                                               y += 1;
+                                       }
+                               }
+                       }
+                       t = ToDateTime(y, m, d, 0, 0, 0, 0);
+                       t = t.Add(time.TimeOfDay);
+               }
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DateTime AddYears(DateTime time, int years) {
+               int rd = CCFixed.FromDateTime(time);
+               int day, month, year;
+               CCHebrewCalendar.dmy_from_fixed(
+                       out day, out month, out year, rd);
+               year += years;
+               rd = CCHebrewCalendar.fixed_from_dmy(day, month, year);
+               DateTime t = CCFixed.ToDateTime(rd);
+               t = t.Add(time.TimeOfDay);
+               M_CheckDateTime(t);
+               return t;
+       }
+               
+       /// <summary>
+       /// Overriden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetDayOfMonth(DateTime time) {
+               M_CheckDateTime(time);
+               int rd = CCFixed.FromDateTime(time);
+               return CCHebrewCalendar.day_from_fixed(rd);
+       }
+
+       /// <summary>
+       /// Overriden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               M_CheckDateTime(time);
+               int rd = CCFixed.FromDateTime(time);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetDayOfYear(DateTime time) {
+               M_CheckDateTime(time);
+               int rd = CCFixed.FromDateTime(time);
+               int year = CCHebrewCalendar.year_from_fixed(rd);
+               int rd1_7 = CCHebrewCalendar.fixed_from_dmy(1, 7, year);
+               return rd - rd1_7 + 1;
+       }
+
+       /// <summary>
+       /// The method maps a .NET Hebrew month to a Calencdrical
+       /// Calculations Hebrew month. 
+       /// </summary>
+       /// <param name="month">An integer representing a month in .NET
+       /// counting (starting with Tishri).
+       /// </param>
+       /// <param name="year">An integer representing the Hebrew year.
+       /// </param>
+       /// <returns>The Hebrew month in Calendrical Calculations counting,
+       /// staring with the Hebrew month Nisan.
+       /// </returns>
+       /// <remarks>
+       /// <para>
+       /// In .NET the month counting starts with the Hebrew month Tishri.
+       /// Calendrical Calculations starts with the month Tisan. So we must
+       /// map here.
+       /// </para>
+       /// </remarks>
+       protected int M_CCMonth(int month, int year) {
+               if (month <= 6) {
+                       return 6+month;
+               }
+               else {
+                       int l = CCHebrewCalendar.last_month_of_year(year);
+                       if (l == 12) {
+                               return month-6;
+                       }
+                       else {
+                               return month <= 7 ? 6+month : month-7;  
+                       }
+               }
+       }
+
+       /// <summary>
+       /// The method maps a Calendrical Calculations Hebrew month
+       /// to a .NET Hebrew month. 
+       /// </summary>
+       /// <param name="ccmonth">An integer representing a month in
+       /// Calendrical Calculations counting, starting with Nisan.
+       /// </param>
+       /// <param name="year">An integer representing the Hebrew year.
+       /// </param>
+       /// <returns>The Hebrew month in .NET counting,
+       /// staring with the Hebrew month Tishri.
+       /// </returns>
+       /// <remarks>
+       /// <para>
+       /// In .NET the month counting starts with the Hebrew month Tishri.
+       /// Calendrical Calculations starts with the month Tisan. So we must
+       /// map here.
+       /// </para>
+       /// </remarks>
+       protected int M_Month(int ccmonth, int year) {
+               if (ccmonth >= 7) {
+                       return ccmonth - 6;
+               } else {
+                       int l = CCHebrewCalendar.last_month_of_year(year);
+                       return ccmonth + (l == 12 ? 6 : 7);
+               }
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An integer that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public override int GetDaysInMonth(int year, int month, int era) {
+               M_CheckYME(year, month, ref era);
+               int ccmonth = M_CCMonth(month, year); 
+               int rd1 = CCHebrewCalendar.fixed_from_dmy(1, ccmonth, year);
+               int rd2 = CCHebrewCalendar.fixed_from_dmy(1, ccmonth+1, year);
+               return rd2 - rd1;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> or <paramref name="era"/> are outside the
+       /// allowed range.
+       /// </exception>
+       public override int GetDaysInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               int rd1 = CCHebrewCalendar.fixed_from_dmy(1, 7, year);
+               int rd2 = CCHebrewCalendar.fixed_from_dmy(1, 7, year+1);
+               return rd2 - rd1;
+       }
+               
+
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetEra(DateTime time) {
+               M_CheckDateTime(time);
+               return HebrewEra;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetMonth(DateTime time) {
+               M_CheckDateTime(time);
+               int rd = CCFixed.FromDateTime(time);
+               int ccmonth, year;
+               CCHebrewCalendar.my_from_fixed(out ccmonth, out year, rd);
+               return M_Month(ccmonth, year);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return CCHebrewCalendar.last_month_of_year(year);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the years
+       /// between 5343 A.M. and 6000 A.M., inclusive.
+       /// </exception>
+       public override int GetYear(DateTime time) {
+               M_CheckDateTime(time);
+               int rd = CCFixed.FromDateTime(time);
+               return CCHebrewCalendar.year_from_fixed(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       /// <remarks>All days in Adar II are viewed as leap days and the
+       /// last day of Adar I.
+       /// </remarks>
+       public override bool IsLeapDay(int year, int month, int day, int era)
+       {
+               M_CheckYMDE(year, month, day, ref era);
+               return IsLeapYear(year) &&
+                       (month == 7 || (month == 6 && day == 30)); 
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       /// <remarks>
+       /// Adar II is viewed as leap month.
+       /// </remarks>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYME(year, month, ref era);
+               return IsLeapYear(year) && month == 7; 
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return CCHebrewCalendar.is_leap_year(year);
+       }
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       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 ccm = M_CCMonth(month, year);
+               int rd = CCHebrewCalendar.fixed_from_dmy(day, ccm, year);
+               return CCFixed.ToDateTime(rd,
+                       hour, minute, second, milliseconds);
+       }
+} // class HebrewCalendar
+       
+} // namespace System.Globalization
diff --git a/mcs/class/corlib/System.Globalization/HijriCalendar.cs b/mcs/class/corlib/System.Globalization/HijriCalendar.cs
new file mode 100644 (file)
index 0000000..3df7881
--- /dev/null
@@ -0,0 +1,870 @@
+// HijriCalendar.cs
+//
+// (C) Ulrich Kunitz 2002
+//
+
+namespace System.Globalization {
+
+using System;
+using System.IO;
+
+/// <summary>
+/// This is the Hijri calendar which might be called Islamic calendar. 
+/// </summary>
+/// <remarks>
+/// <para>The calendar supports only dates in the HijriEra starting with the 
+/// epoch.
+/// </para>
+/// <para>
+/// The epoch of the Hijri Calendar might be adjusted by the 
+/// <see cref="F:System.Globalization.HijriCalendar.AddHijriDate"/>
+/// property. See the discussion of the
+/// <see cref="F:CalendricalCalculations.HijriCalendar.epoch">
+/// epoch
+/// </see>
+/// of the Hijri calendar.
+/// </para>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class HijriCalendar : Calendar {
+       /// <summary>
+       /// Constructor.
+       /// </summary>
+       public HijriCalendar() {
+               M_AbbrEraNames = new string[] {"A.H."};
+               M_EraNames = new string[] {"Anno Hegirae"};
+               if (M_TwoDigitYearMax == 99)
+                       M_TwoDigitYearMax = 1451;
+       }
+
+       /// <summary>
+       /// The era number for the Anno Hegirae (A.H.) era.
+       /// </summary>
+       public const int HijriEra = 1;
+
+       /// <summary>
+       /// The minimum fixed day number supported by the Hijri calendar.
+       /// </summary>
+       protected static readonly int M_MinFixed =
+               CCHijriCalendar.fixed_from_dmy(1, 1, 1);
+       /// <summary>
+       /// The maximum fixed day number supported by the Hijri calendar.
+       /// </summary>
+       protected static readonly int M_MaxFixed =
+               CCGregorianCalendar.fixed_from_dmy(31, 12, 9999);
+
+       /// <value>Overridden. Gives the eras supported by the Gregorian
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return new int[] { HijriEra }; 
+               }
+       }
+
+       /// <summary>
+       /// Protected field storing the
+       /// <see cref="F:AddHijriDate"/>.
+       /// </summary>
+       protected int M_AddHijriDate = 0;
+
+       // TODO: I don't know currently, which sign to use with the parameter.
+       /// <value>An integer property representing the adjustment to the epoch
+       /// of the Hijri calendar. Not supported by .NET.
+       /// </value>
+       public 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;
+               }
+       }
+       
+       /// <summary>
+       /// A protected method checking an
+       /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
+       /// </summary>
+       /// <param name="param">A string giving the name of the parameter
+       /// to check.</param>
+       /// <param name="rdHijri">An integer giving the AddHijriDate adjusted
+       /// fixed day number.
+       /// </param>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// Exception is thrown, if the AddHijriDate adjusted fixed day
+       /// number is outside the supported range.
+       /// </exception>
+       protected 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());
+               }
+       }
+
+       /// <summary>
+       /// A protected member checking a
+       /// <see cref="T:System.DateTime"/> value.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/>
+       /// to check.
+       /// </param>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the supported 
+       /// range of the Hijri calendar.
+       /// </exception>
+       protected void M_CheckDateTime(DateTime time) {
+               int rd = CCFixed.FromDateTime(time) - AddHijriDate;
+               M_CheckFixedHijri("time", rd);
+       }
+
+       /// <summary>
+       /// Protected member which computes the
+       /// <see cref="F:AddHijriDate"/>
+       /// adjusted fixed day number from a
+       /// <see cref="T:System.DateTime"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/>
+       /// to convert.
+       /// </param>
+       /// <returns>The
+       /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
+       /// </returns>
+       protected int M_FromDateTime(DateTime time) {
+               return CCFixed.FromDateTime(time) - AddHijriDate;
+       }
+
+       /// <summary>
+       /// Protected member which converts the
+       /// <see cref="F:AddHijriDate"/>
+       /// adjusted fixed day number the a
+       /// <see cref="T:System.DateTime"/> value.
+       /// </summary>
+       /// <param name="rd">The
+       /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
+       /// </param>
+       /// <returns>The converted
+       /// <see cref="T:System.DateTime"/> value.
+       /// </returns>
+       protected DateTime M_ToDateTime(int rd) {
+               return CCFixed.ToDateTime(rd+AddHijriDate);
+       }
+
+       /// <summary>
+       /// Protected member which converts the
+       /// <see cref="F:AddHijriDate"/>
+       /// adjusted fixed day number the a
+       /// <see cref="T:System.DateTime"/> value using a number
+       /// of time parameters.
+       /// </summary>
+       /// <param name="date">The
+       /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <returns>The converted
+       /// <see cref="T:System.DateTime"/> value.
+       /// </returns>
+       protected DateTime M_ToDateTime(int date,
+               int hour, int minute, int second, int milliseconds)
+       {
+               return CCFixed.ToDateTime(date+AddHijriDate,
+                       hour, minute, second, milliseconds);
+       }
+
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HijriEra"/>.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = HijriEra;
+               if (era != HijriEra)
+                       throw new ArgumentException("Era value was not valid.");
+       }
+
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HijriEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the allowed range.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckEra(ref era);
+               M_ArgumentInRange("year", year, 1, 9666);
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HijriEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the allowed range.
+       /// </exception>
+       protected 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);
+               }
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="F:HijriEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the allowed range.
+       /// </exception>
+       protected 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);
+               }
+       }
+
+       /// <summary>
+       /// Overridden. Adds days to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// days.
+       /// </param>
+       /// <param name="days">The number of days to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="days"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override DateTime AddDays(DateTime time, int days) {
+               DateTime t = base.AddDays(time, days);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds hours to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// hours.
+       /// </param>
+       /// <param name="hours">The number of hours to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="hours"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override DateTime AddHours(DateTime time, int hours) {
+               DateTime t = base.AddHours(time, hours);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds milliseconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// milliseconds.
+       /// </param>
+       /// <param name="milliseconds">The number of milliseconds given as
+       /// double to add. Keep in mind the 100 nanosecond resolution of 
+       /// <see cref="T:System.DateTime"/>.
+       /// </param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="milliseconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override DateTime AddMilliseconds(DateTime time,
+               double milliseconds)
+       {
+               DateTime t = base.AddMilliseconds(time, milliseconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds minutes to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// minutes.
+       /// </param>
+       /// <param name="minutes">The number of minutes to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="minutes"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override DateTime AddMinutes(DateTime time, int minutes) {
+               DateTime t = base.AddMinutes(time, minutes);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds seconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// seconds.
+       /// </param>
+       /// <param name="seconds">The number of seconds to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="seconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override DateTime AddSeconds(DateTime time, int seconds) {
+               DateTime t = base.AddSeconds(time, seconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds weeks to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// weeks.
+       /// </param>
+       /// <param name="weeks">The number of weeks to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="weeks"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override DateTime AddWeeks(DateTime time, int weeks) {
+               DateTime t = base.AddWeeks(time, weeks);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the hour of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the hour of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override int GetHour(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetHour(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the milliseconds in the current second
+       /// of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the milliseconds in the seconds
+       /// of the specified time, starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override double GetMilliseconds(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMilliseconds(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the minute of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the minute of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override int GetMinute(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the second of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the second of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override int GetSecond(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overrideden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       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);
+       }
+
+       /// <summary>
+       /// Overrideden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       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);
+       }
+               
+       /// <summary>
+       /// Overriden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override int GetDayOfMonth(DateTime time) {
+               int rd = M_FromDateTime(time);
+               M_CheckFixedHijri("time", rd);
+               return CCHijriCalendar.day_from_fixed(rd);
+       }
+
+       /// <summary>
+       /// Overriden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               int rd = M_FromDateTime(time);
+               M_CheckFixedHijri("time", rd);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       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;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An intger that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       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;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> is outside the allowed range.
+       /// </exception>
+       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;
+       }
+               
+
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override int GetEra(DateTime time) {
+               M_CheckDateTime(time);
+               return HijriEra;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override int GetMonth(DateTime time) {
+               int rd = M_FromDateTime(time);
+               M_CheckFixedHijri("time", rd);
+               return CCHijriCalendar.month_from_fixed(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return 12;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is not in the
+       /// supported range of the Hijri calendar.
+       /// </exception>
+       public override int GetYear(DateTime time) {
+               int rd = M_FromDateTime(time);
+               M_CheckFixedHijri("time", rd);
+               return CCHijriCalendar.year_from_fixed(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       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;
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYME(year, month, ref era);
+               return false;
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return CCHijriCalendar.is_leap_year(year);
+       }
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       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);
+       }
+} // class HijriCalendar
+       
+} // namespace System.Globalization
diff --git a/mcs/class/corlib/System.Globalization/JapaneseCalendar.cs b/mcs/class/corlib/System.Globalization/JapaneseCalendar.cs
new file mode 100644 (file)
index 0000000..4dcd952
--- /dev/null
@@ -0,0 +1,783 @@
+// JapaneseCalendar.cs
+//
+// (C) Ulrich Kunitz 2002
+//
+
+namespace System.Globalization {
+
+using System;
+
+/// <summary>
+/// This is the Japanese calendar. It differs from the Gregorian calendar
+/// only in the years.
+/// </summary>
+/// <remarks>
+/// <para>The Japanese calendar support four eras.</para>
+/// <list type="table">
+/// <listheader>
+/// <term>era number</term>
+/// <term>Gregorian start date</term>
+/// <term>Gregorian end date</term>
+/// </listheader>
+/// <item>
+/// <term>1</term>
+/// <term>September 8, 1868</term>
+/// <term>July 29, 1912</term>
+/// </item>
+/// <item>
+/// <term>2</term>
+/// <term>July 30, 1912</term>
+/// <term>December 24, 1926</term>
+/// </item>
+/// <item>
+/// <term>3</term>
+/// <term>December 25, 1926</term>
+/// <term>January 7, 1989</term>
+/// </item>
+/// <item>
+/// <term>4</term>
+/// <term>January 8, 1989</term>
+/// <term>present</term>
+/// </item>
+/// </list>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class JapaneseCalendar : Calendar {
+       /// <summary>
+       /// Static protected field storing the
+       /// <see cref="T:CalendricalCalculations.GregorianEraHandler"/>.
+       /// </summary>
+       protected static readonly CCGregorianEraHandler M_EraHandler;
+
+       /// <summary>
+       /// Static constructor, who creates and initializes
+       /// <see cref="F:M_EraHandler"/>.
+       /// </summary>
+       static JapaneseCalendar() {
+               M_EraHandler = new CCGregorianEraHandler();
+               M_EraHandler.appendEra(1,
+                       CCGregorianCalendar.fixed_from_dmy(8, 9, 1868),
+                       CCGregorianCalendar.fixed_from_dmy(29, 7, 1912));
+               M_EraHandler.appendEra(2,
+                       CCGregorianCalendar.fixed_from_dmy(30, 7, 1912),
+                       CCGregorianCalendar.fixed_from_dmy(24, 12, 1926));
+               M_EraHandler.appendEra(3,
+                       CCGregorianCalendar.fixed_from_dmy(25, 12, 1926),
+                       CCGregorianCalendar.fixed_from_dmy(7, 1, 1989));
+               M_EraHandler.appendEra(4,
+                       CCGregorianCalendar.fixed_from_dmy(8, 1, 1989));
+       }
+
+       /// <summary>
+       /// Default constructor.
+       /// </summary>
+       public JapaneseCalendar() {
+               M_AbbrEraNames = new string[] { "M", "T", "S", "H" };
+               M_EraNames = new string[] { "Meiji", "Taisho", "Showa",
+                       "Heisei" };
+       }
+               
+
+       /// <value>Overridden. Gives the eras supported by the
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return (int[])M_EraHandler.Eras.Clone();
+               }
+       }
+
+       /// <summary>
+       /// A protected member checking a
+       /// <see cref="T:System.DateTime"/> value.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/>
+       /// to check.
+       /// </param>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       protected void M_CheckDateTime(DateTime time) {
+               M_EraHandler.CheckDateTime(time);
+       }
+
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number as reference. It is set
+       /// to <see cref="F:CurrentEra"/>, if the input value is 0.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = 4;
+               if (!M_EraHandler.ValidEra(era))
+                       throw new ArgumentException("Era value was not valid.");
+       }
+
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the supported range.
+       /// </exception>
+       protected int M_CheckYEG(int year, ref int era) {
+               M_CheckEra(ref era);
+               return M_EraHandler.GregorianYear(year, era);
+       }
+
+       /// <summary>
+       /// Checks whether the year is the era is valid, if era = CurrentEra
+       /// the right value is set.
+       /// </summary>
+       /// <param name="year">The year to check.</param>
+       /// <param name="era">The era to check.</Param>
+       /// <exception cref="T:ArgumentOutOfRangeException">
+       /// The exception will be thrown, if the year is not valid.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckYEG(year, ref era);
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMEG(int year, int month, ref int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               if (month < 1 || month > 12)
+                       throw new ArgumentOutOfRangeException("month",
+                               "Month must be between one and twelve.");
+               return gregorianYear;
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMDEG(int year, int month, int day, ref int era)
+       {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               M_ArgumentInRange("day", day, 1, GetDaysInMonth(year, month, era));
+               return gregorianYear;
+       }
+
+
+       /// <summary>
+       /// Overridden. Adds days to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// days.
+       /// </param>
+       /// <param name="days">The number of days to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="days"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddDays(DateTime time, int days) {
+               DateTime t = base.AddDays(time, days);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds hours to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// hours.
+       /// </param>
+       /// <param name="hours">The number of hours to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="hours"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddHours(DateTime time, int hours) {
+               DateTime t = base.AddHours(time, hours);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds milliseconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// milliseconds.
+       /// </param>
+       /// <param name="milliseconds">The number of milliseconds given as
+       /// double to add. Keep in mind the 100 nanosecond resolution of 
+       /// <see cref="T:System.DateTime"/>.
+       /// </param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="milliseconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddMilliseconds(DateTime time,
+               double milliseconds)
+       {
+               DateTime t = base.AddMilliseconds(time, milliseconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds minutes to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// minutes.
+       /// </param>
+       /// <param name="minutes">The number of minutes to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="minutes"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddMinutes(DateTime time, int minutes) {
+               DateTime t = base.AddMinutes(time, minutes);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds seconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// seconds.
+       /// </param>
+       /// <param name="seconds">The number of seconds to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="seconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddSeconds(DateTime time, int seconds) {
+               DateTime t = base.AddSeconds(time, seconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+
+       /// <summary>
+       /// Overridden. Adds weeks to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// weeks.
+       /// </param>
+       /// <param name="weeks">The number of weeks to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="weeks"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddWeeks(DateTime time, int weeks) {
+               DateTime t = base.AddWeeks(time, weeks);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the hour of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the hour of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetHour(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetHour(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the milliseconds in the current second
+       /// of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the milliseconds in the seconds
+       /// of the specified time, starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override double GetMilliseconds(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMilliseconds(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the minute of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the minute of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetMinute(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the second of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the second of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetSecond(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overrideden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddMonths(DateTime time, int months) {
+               DateTime t = CCGregorianCalendar.AddMonths(time, months);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddYears(DateTime time, int years) {
+               DateTime t = CCGregorianCalendar.AddYears(time, years);
+               M_CheckDateTime(t);
+               return t;
+       }
+               
+       /// <summary>
+       /// Overriden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetDayOfMonth(DateTime time) {
+               M_CheckDateTime(time);
+               return CCGregorianCalendar.GetDayOfMonth(time);
+       }
+
+       /// <summary>
+       /// Overriden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               M_CheckDateTime(time);
+               int rd = CCFixed.FromDateTime(time);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetDayOfYear(DateTime time) {
+               M_CheckDateTime(time);
+               return CCGregorianCalendar.GetDayOfYear(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An integer that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public override int GetDaysInMonth(int year, int month, int era) {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               return CCGregorianCalendar.GetDaysInMonth(gregorianYear, month);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> or <paramref name="era"/> are outside the
+       /// allowed range.
+       /// </exception>
+       public override int GetDaysInYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.GetDaysInYear(gregorianYear);
+       }
+               
+
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetEra(DateTime time) {
+               // M_CheckDateTime not needed, because EraYear does the
+               // right thing.
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               M_EraHandler.EraYear(out era, rd);
+               return era;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetMonth(DateTime time) {
+               M_CheckDateTime(time);
+               return CCGregorianCalendar.GetMonth(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return 12;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetYear(DateTime time) {
+               // M_CheckDateTime not needed, because EraYeat does the
+               // right thing.
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               return M_EraHandler.EraYear(out era, rd);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapDay(int year, int month, int day, int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               return CCGregorianCalendar.IsLeapDay(gregorianYear, month, day);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYMEG(year, month, ref era);
+               return false;
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.is_leap_year(gregorianYear);
+       }
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       public override DateTime ToDateTime(int year, int month, int day,
+               int hour, int minute, int second, int milliseconds,
+               int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               M_CheckHMSM(hour, minute, second, milliseconds);
+               return CCGregorianCalendar.ToDateTime(
+                       gregorianYear, month, day,
+                       hour, minute, second, milliseconds);
+       }
+
+
+       /// <summary>
+       /// This functions returns simply the year for the Japanese calendar.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <returns>The same argument as the year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the year is negative or the resulting 
+       /// year is invalid.
+       /// </exception>
+       public override int ToFourDigitYear(int year) {
+               if (year < 0)
+                       throw new ArgumentOutOfRangeException(
+                               "year", "Non-negative number required.");
+               int era = CurrentEra;
+               M_CheckYE(year, ref era);
+               return year;
+       }
+} // class JapaneseCalendar
+       
+} // namespace System.Globalization
index 1f1145af0aa4604307eda5e8847726115696a037..1eee95c590cf6efb5e7cf32196d800617d1bc976 100644 (file)
-// ::MONO
-//
-// System.Globalization.JulianCalendar.cs
-//
-// Copyright (C) Wictor Wilén 2001 (wictor@iBizkit.se)
-//
-// Contributors: 
-//
-// Revisions
-// 2001-09-14: First draft
-// 2001-09-15: First release
-//
-//
-// TODO: testing
+// JulianCalendar.cs
 //
+// (C) Ulrich Kunitz 2002
 //
 
-using System;
+namespace System.Globalization {
 
-namespace System.Globalization
-{
+using System;
 
-       
+/// <summary>
+/// This is the Julian calendar.
+/// </summary>
+/// <remarks>
+/// <para>The Julian calendar supports only the Common Era from
+/// January 1, 1 (Gregorian) to December 31, 9999 (Gregorian).
+/// </para>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class JulianCalendar : Calendar {
        /// <summary>
-       /// Summary description for JulianCalendar.
+       /// Default constructor.
        /// </summary>
-       public class JulianCalendar : System.Globalization.Calendar
-       {
-               
+       public JulianCalendar() {
+               M_AbbrEraNames = new string[] {"C.E."};
+               M_EraNames = new string[] {"Common Era"};
+               if (M_TwoDigitYearMax == 99)
+                       M_TwoDigitYearMax = 2029;
+       }
                
-               // Public Static (Shared) Fields
-               // DONE!
-               public static readonly int JulianEra = 1;
-
-               // Public Instance Constructors
-               // DONE!
-               public JulianCalendar()
-               {
-               }
+       /// <summary>
+       /// The era number for the Common Era (C.E.) or Anno Domini (A.D.)
+       /// respective.
+       /// </summary>
+       public const int JulianEra = 1;
 
-               // Public Instance Properties
-               // DONE!
-               public override int[] Eras 
-               {
-                       get
-                       {
-                               return new int[] {1};
-                       }
-               }
-               // DONE!
-               public override int TwoDigitYearMax 
-               {
-                       get
-                       {
-                               return _TwoDigitYearMax;
-                       } 
-                       set
-                       {
-                               _TwoDigitYearMax = value;
-                       }
+       /// <value>Overridden. Gives the eras supported by the Julian
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return new int[] { JulianEra }; 
                }
+       }
 
-               // Public Instance Methods
-               // DONE!
-               public override DateTime AddMonths ( DateTime time, int months )
-               {
-                       if(months < -120000 || months > 120000)
-                               throw new System.ArgumentOutOfRangeException();
-                       DateTime dt = new DateTime(time.Ticks);                 
-                       dt =  dt.AddMonths(months);
-                       return dt;
-                       
-               }
-               // DONE!
-               public override DateTime AddYears ( DateTime time, int years )
-               {
-                       DateTime dt = new DateTime(time.Ticks);
-                       return dt.AddYears(years);
-               }
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:JulianEra"/>.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = JulianEra;
+               if (era != JulianEra)
+                       throw new ArgumentException("Era value was not valid.");
+       }
 
-               // DONE!
-               public override int GetDayOfMonth ( DateTime time )
-               {
-                       return time.Day;
-               }
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:JulianEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the allowed range.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckEra(ref era);
+               M_ArgumentInRange("year", year, 1, 9999);
+       }
 
-               // DONE!
-               public override DayOfWeek GetDayOfWeek ( DateTime time )
-               {
-                       return time.DayOfWeek;
-               }
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:JulianEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the allowed range.
+       /// </exception>
+       protected 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.");
+       }
 
-               // DONE!
-               public override int GetDayOfYear ( DateTime time )
-               {
-                       return time.DayOfYear;
-               }
-               
-               // DONE!
-               public override int GetDaysInMonth ( int year, int month, int era )
-               {
-                       if(     year < _MinYear || year > _MaxYear || 
-                               month < _MinMonth || month > _MaxMonth || 
-                               era != JulianEra)
-                               throw new System.ArgumentOutOfRangeException();
-
-                       if(this.IsLeapYear(year))
-                               return _DaysInMonthLeap[month];
-                       else
-                               return _DaysInMonth[month];
-               }
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number.</param>
+       /// <exception cref="T:System.ArgumentException">
+       /// The exception is thrown if the era is not equal
+       /// <see cref="M:JulianEra"/>.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the allowed range.
+       /// </exception>
+       protected 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, era));
+               if (year == 9999 && ((month == 10 && day > 19) || month > 10))
+                       throw new ArgumentOutOfRangeException(
+                               "The maximum Julian date is 19. 10. 9999.");
+       }
+
+       /// <summary>
+       /// Overridden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddMonths(DateTime time, int months) {
+               int rd = CCFixed.FromDateTime(time);
+               int day, month, year;
+               CCJulianCalendar.dmy_from_fixed(
+                       out day, out month, out year, rd);
+               month += months;
+               rd = CCJulianCalendar.fixed_from_dmy(day, month, year);
+               DateTime t = CCFixed.ToDateTime(rd);
+               return t.Add(time.TimeOfDay);
+       }
+
+       /// <summary>
+       /// Overridden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddYears(DateTime time, int years) {
+               int rd = CCFixed.FromDateTime(time);
+               int day, month, year;
+               CCJulianCalendar.dmy_from_fixed(
+                       out day, out month, out year, rd);
+               year += years;
+               rd = CCJulianCalendar.fixed_from_dmy(day, month, year);
+               DateTime t = CCFixed.ToDateTime(rd);
+               return t.Add(time.TimeOfDay);
+       }
                
+       /// <summary>
+       /// Overridden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override int GetDayOfMonth(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               return CCJulianCalendar.day_from_fixed(rd);
+       }
 
-               // DONE!                
-               public override int GetDaysInYear ( int year, int era )
-               {
-                       if(year < _MinYear || year > _MaxYear || era != JulianEra)
-                               throw new System.ArgumentOutOfRangeException();
-                       return this.GetDaysInYear(year);
-               }
+       /// <summary>
+       /// Overridden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
 
-               // DONE!
-               public override int GetEra ( DateTime time )
-               {
-                       return JulianEra;
-               }
-               // DONE!
-               public override int GetMonth ( DateTime time )
-               {
-                       return time.Month;
-               }
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       public override int GetDayOfYear(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               int year = CCJulianCalendar.year_from_fixed(rd);
+               int rd1_1 = CCJulianCalendar.fixed_from_dmy(1, 1, year);
+               return rd - rd1_1 + 1;
+       }
 
-               // DONE!                
-               public override int GetMonthsInYear ( int year, int era )
-               {
-                       if(year < _MinYear || year > _MaxYear || era != JulianEra)
-                               throw new System.ArgumentOutOfRangeException();
-                       return _MaxMonth;
-               }
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An intger that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public override int GetDaysInMonth(int year, int month, int era) {
+               M_CheckYME(year, month, ref era);
+               int rd1 = CCJulianCalendar.fixed_from_dmy(1, month, year);
+               int rd2 = CCJulianCalendar.fixed_from_dmy(1, month+1, year);
+               return rd2 - rd1;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> is outside the allowed range.
+       /// </exception>
+       public override int GetDaysInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               int rd1 = CCJulianCalendar.fixed_from_dmy(1, 1, year);
+               int rd2 = CCJulianCalendar.fixed_from_dmy(1, 1, year+1);
+               return rd2 - rd1;
+       }
                
-               // DONE!
-               public override int GetYear ( DateTime time )
-               {                       
-                       return time.Year;
-               }
 
-               // DONE!
-               public override bool IsLeapDay ( int year, int month, int day, int era )
-               {                       
-                       int dim;
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       public override int GetEra(DateTime time) {
+               // should change, if more than one era is supported
+               return JulianEra;
+       }
 
-                       if(day < _MinDay || month < _MinMonth || month > _MaxMonth)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       public override int GetMonth(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               return CCJulianCalendar.month_from_fixed(rd);
+       }
 
-                       if(this.IsLeapYear(year,era))
-                               dim = _DaysInMonthLeap[month-1];
-                       else
-                               dim = _DaysInMonth[month-1];
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return 12;
+       }
 
-                       if( day > dim)
-                               throw new System.ArgumentOutOfRangeException();
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       public override int GetYear(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               return CCJulianCalendar.year_from_fixed(rd);
+       }
 
-                       if( month == 2 && day == 29)
-                               return true;
-                       
-                       return false;
-               }
-               // DONE!
-               public override bool IsLeapMonth ( int year, int month )
-               {
-                       if( year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
-                               throw new System.ArgumentException();
-                       return false;   
-               }
-               // DONE!
-               public override bool IsLeapMonth ( int year, int month, int era )
-               {
-                       if( year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth || era != JulianEra)
-                               throw new System.ArgumentException();
-                       return false;
-               }
-               
-               // DONE!
-               public override bool IsLeapYear ( int year, int era )
-               {
-                       if(year < _MinYear || year > _MaxYear || era != JulianEra)
-                               throw new System.ArgumentOutOfRangeException();
-                       if(year % 4 == 0)
-                               return true;
-                       return false;
-               }
-               
-               // DONE!
-               public override DateTime ToDateTime ( int year, int month, int day, int hour, int minute, int second, int millisecond, int era )
-               {
-                       // INFO: year, era and month is checked by GetDaysInMonth()
-                       int dim;
-                       dim = GetDaysInMonth(year,month);
-                       if( day < _MinDay || day > dim || 
-                               hour < _MinHour || hour > _MaxHour ||
-                               minute < _MinMinute || minute > _MaxMinute ||
-                               second < _MinSecond || second > _MaxSecond ||
-                               millisecond < _MinMillisecond || millisecond > _MaxMillisecond)
-                               throw new System.ArgumentOutOfRangeException();
-
-                       return new DateTime(year,month,day,hour,minute,second,millisecond,this);
-               }
-               
-               // DONE!
-               public override int ToFourDigitYear ( int year )
-               {
-                       int y = _TwoDigitYearMax % 100;
-                       if( year > y )
-                               y = _TwoDigitYearMax - y - 100 + year;
-                       else
-                               y = _TwoDigitYearMax - y + year;
-
-                       if( y < _MinYear || y > _MaxYear)
-                               throw new System.ArgumentException();
-                       return y;
-               }
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapDay(int year, int month, int day, int era)
+       {
+               M_CheckYMDE(year, month, day, ref era);
+               return IsLeapYear(year) && month == 2 && day == 29;
+       }
 
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYME(year, month, ref era);
+               return false;
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return CCJulianCalendar.is_leap_year(year);
        }
-}
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       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 = CCJulianCalendar.fixed_from_dmy(day, month, year);
+               return CCFixed.ToDateTime(rd,
+                       hour, minute, second, milliseconds);
+       }
+} // class JulianCalendar
+       
+} // namespace System.Globalization
diff --git a/mcs/class/corlib/System.Globalization/KoreanCalendar.cs b/mcs/class/corlib/System.Globalization/KoreanCalendar.cs
new file mode 100644 (file)
index 0000000..51103d1
--- /dev/null
@@ -0,0 +1,444 @@
+// KoreanCalendar.cs
+//
+// (C) Ulrich Kunitz 2002
+//
+
+namespace System.Globalization {
+
+using System;
+
+/// <summary>
+/// This is the Korean calendar. It differs from the Gegorian calendar only
+/// in the year counting.
+/// </summary>
+/// <remarks>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class KoreanCalendar : Calendar {
+       /// <summary>
+       /// Static protected field storing the
+       /// <see cref="T:CalendricalCalculations.GregorianEraHandler"/>.
+       /// </summary>
+       protected static readonly CCGregorianEraHandler M_EraHandler;
+
+       /// <variable>
+       /// The standard era for the <see cref="T:KoreanCalendar"/>.
+       /// </variable>
+       public const int KoreanEra = 1;
+
+       /// <summary>
+       /// Static constructor, who creates and initializes
+       /// <see cref="F:M_EraHandler"/>.
+       /// </summary>
+       static KoreanCalendar() {
+               M_EraHandler = new CCGregorianEraHandler();
+               M_EraHandler.appendEra(KoreanEra,
+                       CCGregorianCalendar.fixed_from_dmy(1, 1, -2332));
+       }
+
+       /// <summary>
+       /// Default constructor.
+       /// </summary>
+       public KoreanCalendar() {
+               M_AbbrEraNames = new string[] {"K.C.E."};
+               M_EraNames = new string[] {"Korean Current Era"};
+               if (M_TwoDigitYearMax == 99)
+                       M_TwoDigitYearMax = 4362;
+       }
+
+       /// <value>Overridden. Gives the eras supported by the
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return (int[])M_EraHandler.Eras.Clone();
+               }
+       }
+
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number as reference. It is set
+       /// to <see cref="F:CurrentEra"/>, if the input value is 0.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = KoreanEra;
+               if (!M_EraHandler.ValidEra(era))
+                       throw new ArgumentException("Era value was not valid.");
+       }
+
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the supported range.
+       /// </exception>
+       protected int M_CheckYEG(int year, ref int era) {
+               M_CheckEra(ref era);
+               return M_EraHandler.GregorianYear(year, era);
+       }
+
+       /// <summary>
+       /// Checks whether the year is the era is valid, if era = CurrentEra
+       /// the right value is set.
+       /// </summary>
+       /// <param name="year">The year to check.</param>
+       /// <param name="era">The era to check.</Param>
+       /// <exception cref="T:ArgumentOutOfRangeException">
+       /// The exception will be thrown, if the year is not valid.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckYEG(year, ref era);
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMEG(int year, int month, ref int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               if (month < 1 || month > 12)
+                       throw new ArgumentOutOfRangeException("month",
+                               "Month must be between one and twelve.");
+               return gregorianYear;
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMDEG(int year, int month, int day, ref int era)
+       {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               M_ArgumentInRange("day", day, 1,
+                       GetDaysInMonth(year, month, era));
+               return gregorianYear;
+       }
+
+       /// <summary>
+       /// Overrideden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddMonths(DateTime time, int months) {
+               return CCGregorianCalendar.AddMonths(time, months);
+       }
+
+       /// <summary>
+       /// Overridden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddYears(DateTime time, int years) {
+               return CCGregorianCalendar.AddYears(time, years);
+       }
+               
+       /// <summary>
+       /// Overriden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override int GetDayOfMonth(DateTime time) {
+               return CCGregorianCalendar.GetDayOfMonth(time);
+       }
+
+       /// <summary>
+       /// Overriden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       public override int GetDayOfYear(DateTime time) {
+               return CCGregorianCalendar.GetDayOfYear(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An integer that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public override int GetDaysInMonth(int year, int month, int era) {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               return CCGregorianCalendar.GetDaysInMonth(gregorianYear, month);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> or <paramref name="era"/> are outside the
+       /// allowed range.
+       /// </exception>
+       public override int GetDaysInYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.GetDaysInYear(gregorianYear);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       public override int GetEra(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               M_EraHandler.EraYear(out era, rd);
+               return era;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       public override int GetMonth(DateTime time) {
+               return CCGregorianCalendar.GetMonth(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYEG(year, ref era);
+               return 12;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       public override int GetYear(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               return M_EraHandler.EraYear(out era, rd);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapDay(int year, int month, int day, int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               return CCGregorianCalendar.IsLeapDay(gregorianYear, month, day);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYMEG(year, month, ref era);
+               return false;
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.is_leap_year(gregorianYear);
+       }
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       public override DateTime ToDateTime(int year, int month, int day,
+               int hour, int minute, int second, int milliseconds,
+               int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               M_CheckHMSM(hour, minute, second, milliseconds);
+               return CCGregorianCalendar.ToDateTime(gregorianYear,
+                       month, day, hour, minute, second, milliseconds);
+       }
+} // class KoreanCalendar
+       
+} // namespace System.Globalization
diff --git a/mcs/class/corlib/System.Globalization/TaiwanCalendar.cs b/mcs/class/corlib/System.Globalization/TaiwanCalendar.cs
new file mode 100644 (file)
index 0000000..16728c6
--- /dev/null
@@ -0,0 +1,745 @@
+// TaiwanCalendar.cs
+//
+// (C) Ulrich Kunitz 2002
+//
+
+namespace System.Globalization {
+
+using System;
+
+/// <summary>
+/// This is the Japanese calendar. It differs from the Gregorian calendar
+/// only in the years.
+/// </summary>
+/// <remarks>
+/// <para>The Japanese calendar support a single era starting at January 1,
+/// 1912</para>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class TaiwanCalendar : Calendar {
+       /// <summary>
+       /// Static protected field storing the
+       /// <see cref="T:CalendricalCalculations.GregorianEraHandler"/>.
+       /// </summary>
+       protected static readonly CCGregorianEraHandler M_EraHandler;
+
+       /// <summary>
+       /// Static constructor, who creates and initializes
+       /// <see cref="F:M_EraHandler"/>.
+       /// </summary>
+       static TaiwanCalendar() {
+               M_EraHandler = new CCGregorianEraHandler();
+               M_EraHandler.appendEra(1,
+                       CCGregorianCalendar.fixed_from_dmy(1, 1, 1912));
+       }
+
+       /// <summary>
+       /// Default constructor.
+       /// </summary>
+       public TaiwanCalendar() {
+               M_AbbrEraNames = new string[] {"T.C.E."};
+               M_EraNames =  new string[] {"Taiwan current era"};
+       }
+
+       /// <value>Overridden. Gives the eras supported by the
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return (int[])M_EraHandler.Eras.Clone();
+               }
+       }
+
+       /// <summary>
+       /// A protected member checking a
+       /// <see cref="T:System.DateTime"/> value.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/>
+       /// to check.
+       /// </param>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       protected void M_CheckDateTime(DateTime time) {
+               M_EraHandler.CheckDateTime(time);
+       }
+
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number as reference. It is set
+       /// to <see cref="F:CurrentEra"/>, if the input value is 0.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = 1;
+               if (!M_EraHandler.ValidEra(era))
+                       throw new ArgumentException("Era value was not valid.");
+       }
+
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the supported range.
+       /// </exception>
+       protected int M_CheckYEG(int year, ref int era) {
+               M_CheckEra(ref era);
+               return M_EraHandler.GregorianYear(year, era);
+       }
+
+       /// <summary>
+       /// Checks whether the year is the era is valid, if era = CurrentEra
+       /// the right value is set.
+       /// </summary>
+       /// <param name="year">The year to check.</param>
+       /// <param name="era">The era to check.</Param>
+       /// <exception cref="T:ArgumentOutOfRangeException">
+       /// The exception will be thrown, if the year is not valid.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckYEG(year, ref era);
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMEG(int year, int month, ref int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               if (month < 1 || month > 12)
+                       throw new ArgumentOutOfRangeException("month",
+                               "Month must be between one and twelve.");
+               return gregorianYear;
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMDEG(int year, int month, int day, ref int era)
+       {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               M_ArgumentInRange("day", day, 1,
+                       GetDaysInMonth(year, month, era));
+               return gregorianYear;
+       }
+
+       /// <summary>
+       /// Overridden. Adds days to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// days.
+       /// </param>
+       /// <param name="days">The number of days to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="days"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddDays(DateTime time, int days) {
+               DateTime t = base.AddDays(time, days);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds hours to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// hours.
+       /// </param>
+       /// <param name="hours">The number of hours to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="hours"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddHours(DateTime time, int hours) {
+               DateTime t = base.AddHours(time, hours);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds milliseconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// milliseconds.
+       /// </param>
+       /// <param name="milliseconds">The number of milliseconds given as
+       /// double to add. Keep in mind the 100 nanosecond resolution of 
+       /// <see cref="T:System.DateTime"/>.
+       /// </param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="milliseconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddMilliseconds(DateTime time,
+               double milliseconds)
+       {
+               DateTime t = base.AddMilliseconds(time, milliseconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds minutes to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// minutes.
+       /// </param>
+       /// <param name="minutes">The number of minutes to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="minutes"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddMinutes(DateTime time, int minutes) {
+               DateTime t = base.AddMinutes(time, minutes);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds seconds to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// seconds.
+       /// </param>
+       /// <param name="seconds">The number of seconds to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="seconds"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddSeconds(DateTime time, int seconds) {
+               DateTime t = base.AddSeconds(time, seconds);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+
+       /// <summary>
+       /// Overridden. Adds weeks to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// weeks.
+       /// </param>
+       /// <param name="weeks">The number of weeks to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="weeks"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddWeeks(DateTime time, int weeks) {
+               DateTime t = base.AddWeeks(time, weeks);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the hour of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the hour of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetHour(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetHour(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the milliseconds in the current second
+       /// of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the milliseconds in the seconds
+       /// of the specified time, starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override double GetMilliseconds(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMilliseconds(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the minute of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the minute of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetMinute(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the second of the specified time.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies the
+       /// time.
+       /// </param>
+       /// <returns>An integer that gives the second of the specified time,
+       /// starting with 0.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetSecond(DateTime time) {
+               M_CheckDateTime(time);
+               return base.GetMinute(time);
+       }
+
+       /// <summary>
+       /// Overrideden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddMonths(DateTime time, int months) {
+               DateTime t = CCGregorianCalendar.AddMonths(time, months);
+               M_CheckDateTime(t);
+               return t;
+       }
+
+       /// <summary>
+       /// Overridden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if
+       /// <see cref="T:System.DateTime"/> return value is outside all
+       /// supported eras.
+       /// </exception>
+       public override DateTime AddYears(DateTime time, int years) {
+               DateTime t = CCGregorianCalendar.AddYears(time, years);
+               M_CheckDateTime(t);
+               return t;
+       }
+               
+       /// <summary>
+       /// Overriden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetDayOfMonth(DateTime time) {
+               M_CheckDateTime(time);
+               return CCGregorianCalendar.GetDayOfMonth(time);
+       }
+
+       /// <summary>
+       /// Overriden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               M_CheckDateTime(time);
+               int rd = CCFixed.FromDateTime(time);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetDayOfYear(DateTime time) {
+               M_CheckDateTime(time);
+               return CCGregorianCalendar.GetDayOfYear(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An integer that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public override int GetDaysInMonth(int year, int month, int era) {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               return CCGregorianCalendar.GetDaysInMonth(gregorianYear, month);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> or <paramref name="era"/> are outside the
+       /// allowed range.
+       /// </exception>
+       public override int GetDaysInYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.GetDaysInYear(gregorianYear);
+       }
+               
+
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetEra(DateTime time) {
+               // M_CheckDateTime not needed, because EraYear does the
+               // right thing.
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               M_EraHandler.EraYear(out era, rd);
+               return era;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetMonth(DateTime time) {
+               M_CheckDateTime(time);
+               return CCGregorianCalendar.GetMonth(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYEG(year, ref era);
+               return 12;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the
+       /// <see cref="T:System.DateTime"/> parameter is outside all
+       /// supported eras.
+       /// </exception>
+       public override int GetYear(DateTime time) {
+               // M_CheckDateTime not needed, because EraYeat does the
+               // right thing.
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               return M_EraHandler.EraYear(out era, rd);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapDay(int year, int month, int day, int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               return CCGregorianCalendar.IsLeapDay(gregorianYear, month, day);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYMEG(year, month, ref era);
+               return false;
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.is_leap_year(gregorianYear);
+       }
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       public override DateTime ToDateTime(int year, int month, int day,
+               int hour, int minute, int second, int milliseconds,
+               int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               M_CheckHMSM(hour, minute, second, milliseconds);
+               return CCGregorianCalendar.ToDateTime(
+                       gregorianYear, month, day,
+                       hour, minute, second, milliseconds);
+       }
+
+       /// <summary>
+       /// This functions returns simply the year for the Taiwan calendar.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <returns>The same argument as the year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the year is negative or the resulting 
+       /// year is invalid.
+       /// </exception>
+       public override int ToFourDigitYear(int year) {
+               if (year < 0)
+                       throw new ArgumentOutOfRangeException(
+                               "year", "Non-negative number required.");
+               int era = CurrentEra;
+               M_CheckYE(year, ref era);
+               return year;
+       }
+} // class TaiwanCalendar
+       
+} // namespace System.Globalization
diff --git a/mcs/class/corlib/System.Globalization/ThaiBuddhistCalendar.cs b/mcs/class/corlib/System.Globalization/ThaiBuddhistCalendar.cs
new file mode 100644 (file)
index 0000000..7e3396a
--- /dev/null
@@ -0,0 +1,445 @@
+// ThaiBuddhistCalendar.cs
+//
+// (C) Ulrich Kunitz 2002
+//
+
+namespace System.Globalization {
+
+using System;
+
+/// <summary>
+/// This is the ThaiBudhist calendar. It differs from the Gegorian calendar
+/// only in the year counting.
+/// </summary>
+/// <remarks>
+/// <para>The implementation uses the
+/// <see cref="N:CalendricalCalculations"/> namespace.
+/// </para>
+/// </remarks>
+[Serializable]
+public class ThaiBuddhistCalendar : Calendar {
+       /// <summary>
+       /// Static protected field storing the
+       /// <see cref="T:CalendricalCalculations.GregorianEraHandler"/>.
+       /// </summary>
+       protected static readonly CCGregorianEraHandler M_EraHandler;
+
+       /// <value>
+       /// The standard era for this calendar.
+       /// </value>
+       public const int ThaiBuddhistEra = 1;
+       
+       /// <summary>
+       /// Static constructor, who creates and initializes
+       /// <see cref="F:M_EraHandler"/>.
+       /// </summary>
+       static ThaiBuddhistCalendar() {
+               M_EraHandler = new CCGregorianEraHandler();
+               M_EraHandler.appendEra(ThaiBuddhistEra,
+                       CCGregorianCalendar.fixed_from_dmy(1, 1, -542));
+       }
+
+       /// <summary>
+       /// Default constructor.
+       /// </summary>
+       public ThaiBuddhistCalendar() {
+               M_AbbrEraNames = new string[] {"T.B.C.E."};
+               M_EraNames = new string[] {"ThaiBuddhist current era"};
+               if (M_TwoDigitYearMax == 99)
+                       M_TwoDigitYearMax = 2572;
+       }
+
+       /// <value>Overridden. Gives the eras supported by the
+       /// calendar as an array of integers.
+       /// </value>
+       public override int[] Eras {
+               get {
+                       return (int[])M_EraHandler.Eras.Clone();
+               }
+       }
+
+       /// <summary>
+       /// A protected method checking the era number.
+       /// </summary>
+       /// <param name="era">The era number as reference. It is set
+       /// to <see cref="F:CurrentEra"/>, if the input value is 0.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       protected void M_CheckEra(ref int era) {
+               if (era == CurrentEra)
+                       era = ThaiBuddhistEra;
+               if (!M_EraHandler.ValidEra(era))
+                       throw new ArgumentException("Era value was not valid.");
+       }
+
+       /// <summary>
+       /// A protected method checking calendar year and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year is outside of
+       /// the supported range.
+       /// </exception>
+       protected int M_CheckYEG(int year, ref int era) {
+               M_CheckEra(ref era);
+               return M_EraHandler.GregorianYear(year, era);
+       }
+
+       /// <summary>
+       /// Checks whether the year is the era is valid, if era = CurrentEra
+       /// the right value is set.
+       /// </summary>
+       /// <param name="year">The year to check.</param>
+       /// <param name="era">The era to check.</Param>
+       /// <exception cref="T:ArgumentOutOfRangeException">
+       /// The exception will be thrown, if the year is not valid.
+       /// </exception>
+       protected override void M_CheckYE(int year, ref int era) {
+               M_CheckYEG(year, ref era);
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar year, month, and
+       /// era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year or month is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMEG(int year, int month, ref int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               if (month < 1 || month > 12)
+                       throw new ArgumentOutOfRangeException("month",
+                               "Month must be between one and twelve.");
+               return gregorianYear;
+       }
+
+       /// <summary>
+       /// A protected method checking the calendar day, month, and year
+       /// and the era number.
+       /// </summary>
+       /// <param name="year">An integer representing the calendar year.
+       /// </param>
+       /// <param name="month">An integer giving the calendar month.
+       /// </param>
+       /// <param name="day">An integer giving the calendar day.
+       /// </param>
+       /// <param name="era">The era number as reference.</param>
+       /// <exception name="T:System.ArgumentException">
+       /// The exception is thrown if the era is not supported by the class.
+       /// </exception>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown if the calendar year, month, or day is
+       /// outside of the supported range.
+       /// </exception>
+       protected int M_CheckYMDEG(int year, int month, int day, ref int era)
+       {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               M_ArgumentInRange("day", day, 1,
+                       GetDaysInMonth(year, month, era));
+               return gregorianYear;
+       }
+
+       /// <summary>
+       /// Overrideden. Adds months to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// months.
+       /// </param>
+       /// <param name="months">The number of months to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="months"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddMonths(DateTime time, int months) {
+               return CCGregorianCalendar.AddMonths(time, months);
+       }
+
+       /// <summary>
+       /// Overridden. Adds years to a given date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> to which to add
+       /// years.
+       /// </param>
+       /// <param name="years">The number of years to add.</param>
+       /// <returns>A new <see cref="T:System.DateTime"/> value, that
+       /// results from adding <paramref name="years"/> to the specified
+       /// DateTime.</returns>
+       public override DateTime AddYears(DateTime time, int years) {
+               return CCGregorianCalendar.AddYears(time, years);
+       }
+               
+       /// <summary>
+       /// Overriden. Gets the day of the month from
+       /// <paramref name="time"/>.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override int GetDayOfMonth(DateTime time) {
+               return CCGregorianCalendar.GetDayOfMonth(time);
+       }
+
+       /// <summary>
+       /// Overriden. Gets the day of the week from the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer giving the day of months, starting with 1.
+       /// </returns>
+       public override DayOfWeek GetDayOfWeek(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               return (DayOfWeek)CCFixed.day_of_week(rd);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the day in the year.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the day of the year,
+       /// starting with 1.</returns>
+       public override int GetDayOfYear(DateTime time) {
+               return CCGregorianCalendar.GetDayOfYear(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days in the specified month
+       /// of the given year and era.
+       /// </summary>
+       /// <param name="year">An integer that gives the year.
+       /// </param>
+       /// <param name="month">An integer that gives the month, starting
+       /// with 1.</param>
+       /// <param name="era">An integer that gives the era of the specified
+       /// year.</param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified month.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if <paramref name="month"/>,
+       /// <paramref name="year"/> ,or <paramref name="era"/> is outside
+       /// the allowed range.
+       /// </exception>
+       public override int GetDaysInMonth(int year, int month, int era) {
+               int gregorianYear = M_CheckYMEG(year, month, ref era);
+               return CCGregorianCalendar.GetDaysInMonth(gregorianYear, month);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of days of the specified
+       /// year of the given era. 
+       /// </summary>
+       /// <param name="year">An integer that specifies the year. 
+       /// </param>
+       /// <param name="era">An ineger that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of days of the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
+       /// The exception is thrown, if
+       /// <paramref name="year"/> or <paramref name="era"/> are outside the
+       /// allowed range.
+       /// </exception>
+       public override int GetDaysInYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.GetDaysInYear(gregorianYear);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the era of the specified date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the era of the calendar.
+       /// </returns>
+       public override int GetEra(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               M_EraHandler.EraYear(out era, rd);
+               return era;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the month of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the month, 
+       /// starting with 1.</returns>
+       public override int GetMonth(DateTime time) {
+               return CCGregorianCalendar.GetMonth(time);
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of months in the specified year 
+       /// and era.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>An integer that gives the number of the months in the
+       /// specified year.</returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or the era are not valid.
+       /// </exception>
+       public override int GetMonthsInYear(int year, int era) {
+               M_CheckYE(year, ref era);
+               return 12;
+       }
+
+       /// <summary>
+       /// Overridden. Gives the number of the year of the specified
+       /// date.
+       /// </summary>
+       /// <param name="time">The
+       /// <see cref="T:System.DateTime"/> that specifies a
+       /// date.
+       /// </param>
+       /// <returns>An integer representing the year, 
+       /// starting with 1.</returns>
+       public override int GetYear(DateTime time) {
+               int rd = CCFixed.FromDateTime(time);
+               int era;
+               return M_EraHandler.EraYear(out era, rd);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given day 
+       /// is a leap day.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given day is a leap
+       /// day.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, day, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapDay(int year, int month, int day, int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               return CCGregorianCalendar.IsLeapDay(gregorianYear, month, day);
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given month 
+       /// is a leap month.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given month is a leap
+       /// month.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year, month, or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapMonth(int year, int month, int era) {
+               M_CheckYMEG(year, month, ref era);
+               return false;
+       }
+
+       /// <summary>
+       /// Overridden. Tells whether the given year
+       /// is a leap year.
+       /// </summary>
+       /// <param name="year">An integer that specifies the year in the
+       /// given era.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A boolean that tells whether the given year is a leap
+       /// year.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if the year or era is not
+       /// valid.
+       /// </exception>
+       public override bool IsLeapYear(int year, int era) {
+               int gregorianYear = M_CheckYEG(year, ref era);
+               return CCGregorianCalendar.is_leap_year(gregorianYear);
+       }
+
+       /// <summary>
+       /// Overridden. Creates the
+       /// <see cref="T:System.DateTime"/> from the parameters.
+       /// </summary>
+       /// <param name="year">An integer that gives the year in the
+       /// <paramref name="era"/>.
+       /// </param>
+       /// <param name="month">An integer that specifies the month.
+       /// </param>
+       /// <param name="day">An integer that specifies the day.
+       /// </param>
+       /// <param name="hour">An integer that specifies the hour.
+       /// </param>
+       /// <param name="minute">An integer that specifies the minute.
+       /// </param>
+       /// <param name="second">An integer that gives the second.
+       /// </param>
+       /// <param name="milliseconds">An integer that gives the
+       /// milliseconds.
+       /// </param>
+       /// <param name="era">An integer that specifies the era.
+       /// </param>
+       /// <returns>A
+       /// <see cref="T:system.DateTime"/> representig the date and time.
+       /// </returns>
+       /// <exception cref="T:System.ArgumentOutOfRangeException">
+       /// The exception is thrown, if at least one of the parameters
+       /// is out of range.
+       /// </exception>
+       public override DateTime ToDateTime(int year, int month, int day,
+               int hour, int minute, int second, int milliseconds,
+               int era)
+       {
+               int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
+               M_CheckHMSM(hour, minute, second, milliseconds);
+               return CCGregorianCalendar.ToDateTime(
+                       gregorianYear, month, day,
+                       hour, minute, second, milliseconds);
+       }
+} // class ThaiBuddhistCalendar
+       
+} // namespace System.Globalization