2004-04-30 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / corlib / System.Globalization / HijriCalendar.cs
1 // HijriCalendar.cs
2 //
3 // (C) Ulrich Kunitz 2002
4 //
5
6 namespace System.Globalization {
7
8 using System;
9 using System.IO;
10
11
12 /// <summary>
13 /// This is the Hijri calendar which might be called Islamic calendar. 
14 /// </summary>
15 /// <remarks>
16 /// <para>The calendar supports only dates in the HijriEra starting with the 
17 /// epoch.
18 /// </para>
19 /// <para>
20 /// The epoch of the Hijri Calendar might be adjusted by the 
21 /// <see cref="F:System.Globalization.HijriCalendar.AddHijriDate"/>
22 /// property. See the discussion of the
23 /// <see cref="F:CalendricalCalculations.HijriCalendar.epoch">
24 /// epoch
25 /// </see>
26 /// of the Hijri calendar.
27 /// </para>
28 /// <para>The implementation uses the
29 /// <see cref="N:CalendricalCalculations"/> namespace.
30 /// </para>
31 /// </remarks>
32 [Serializable]
33 public class HijriCalendar : Calendar {
34         /// <summary>
35         /// Constructor.
36         /// </summary>
37         public HijriCalendar() {
38                 M_AbbrEraNames = new string[] {"A.H."};
39                 M_EraNames = new string[] {"Anno Hegirae"};
40                 if (M_TwoDigitYearMax == 99)
41                         M_TwoDigitYearMax = 1451;
42         }
43
44         /// <summary>
45         /// The era number for the Anno Hegirae (A.H.) era.
46         /// </summary>
47         public static readonly int HijriEra = 1;
48
49         /// <summary>
50         /// The minimum fixed day number supported by the Hijri calendar.
51         /// </summary>
52         internal static readonly int M_MinFixed =
53                 CCHijriCalendar.fixed_from_dmy(1, 1, 1);
54         /// <summary>
55         /// The maximum fixed day number supported by the Hijri calendar.
56         /// </summary>
57         internal static readonly int M_MaxFixed =
58                 CCGregorianCalendar.fixed_from_dmy(31, 12, 9999);
59
60         /// <value>Overridden. Gives the eras supported by the Gregorian
61         /// calendar as an array of integers.
62         /// </value>
63         public override int[] Eras {
64                 get {
65                         return new int[] { HijriEra }; 
66                 }
67         }
68
69         int twoDigitYearMax = 1451;
70         
71         [MonoTODO ("Add call into operating system")]
72         public override int TwoDigitYearMax 
73         {
74                 get {
75                         return twoDigitYearMax;
76                 }
77                 set {
78                         M_ArgumentInRange ("value", value, 100, M_MaxYear);
79
80                         twoDigitYearMax = value;
81                 }
82         }
83
84         /// <summary>
85         /// Protected field storing the
86         /// <see cref="F:AddHijriDate"/>.
87         /// </summary>
88         internal int M_AddHijriDate = 0;
89
90         // TODO: I don't know currently, which sign to use with the parameter.
91         /// <value>An integer property representing the adjustment to the epoch
92         /// of the Hijri calendar. Not supported by .NET.
93         /// </value>
94         internal virtual int AddHijriDate {
95                 get {
96                         return M_AddHijriDate;
97                 }
98                 set {
99                         if (value < -3 && value > 3)
100                                 throw new ArgumentOutOfRangeException(
101                                         "AddHijriDate",
102                                         "Value should be between -3 and 3.");
103                         M_AddHijriDate = value;
104                 }
105         }
106         
107         /// <summary>
108         /// A protected method checking an
109         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
110         /// </summary>
111         /// <param name="param">A string giving the name of the parameter
112         /// to check.</param>
113         /// <param name="rdHijri">An integer giving the AddHijriDate adjusted
114         /// fixed day number.
115         /// </param>
116         /// <exception cref="T:System.ArgumentOutOfRangeException">
117         /// Exception is thrown, if the AddHijriDate adjusted fixed day
118         /// number is outside the supported range.
119         /// </exception>
120         internal void M_CheckFixedHijri(string param, int rdHijri) {
121                 if (rdHijri < M_MinFixed || rdHijri > M_MaxFixed-AddHijriDate) {
122                         StringWriter sw = new StringWriter();
123                         int day, month, year;
124                         CCHijriCalendar.dmy_from_fixed(out day, out month,
125                                 out year, M_MaxFixed-AddHijriDate);
126                         if (AddHijriDate != 0) {
127                                 sw.Write("This HijriCalendar " +
128                                         "(AddHijriDate {0})" +
129                                         " allows dates from 1. 1. 1 to " +
130                                         "{1}. {2}. {3}.",
131                                         AddHijriDate,
132                                         day, month, year);
133                         } else {
134                                 sw.Write("HijriCalendar allows dates from " +
135                                         "1.1.1 to {0}.{1}.{2}.",
136                                         day, month, year);
137                         }
138                         throw new ArgumentOutOfRangeException(param,
139                                 sw.ToString());
140                 }
141         }
142
143         /// <summary>
144         /// A protected member checking a
145         /// <see cref="T:System.DateTime"/> value.
146         /// </summary>
147         /// <param name="time">The
148         /// <see cref="T:System.DateTime"/>
149         /// to check.
150         /// </param>
151         /// <exception cref="T:System.ArgumentOutOfRangeException">
152         /// The exception is thrown if the
153         /// <see cref="T:System.DateTime"/> parameter is not in the supported 
154         /// range of the Hijri calendar.
155         /// </exception>
156         internal void M_CheckDateTime(DateTime time) {
157                 int rd = CCFixed.FromDateTime(time) - AddHijriDate;
158                 M_CheckFixedHijri("time", rd);
159         }
160
161         /// <summary>
162         /// Protected member which computes the
163         /// <see cref="F:AddHijriDate"/>
164         /// adjusted fixed day number from a
165         /// <see cref="T:System.DateTime"/>.
166         /// </summary>
167         /// <param name="time">The
168         /// <see cref="T:System.DateTime"/>
169         /// to convert.
170         /// </param>
171         /// <returns>The
172         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
173         /// </returns>
174         internal int M_FromDateTime(DateTime time) {
175                 return CCFixed.FromDateTime(time) - AddHijriDate;
176         }
177
178         /// <summary>
179         /// Protected member which converts the
180         /// <see cref="F:AddHijriDate"/>
181         /// adjusted fixed day number the a
182         /// <see cref="T:System.DateTime"/> value.
183         /// </summary>
184         /// <param name="rd">The
185         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
186         /// </param>
187         /// <returns>The converted
188         /// <see cref="T:System.DateTime"/> value.
189         /// </returns>
190         internal DateTime M_ToDateTime(int rd) {
191                 return CCFixed.ToDateTime(rd+AddHijriDate);
192         }
193
194         /// <summary>
195         /// Protected member which converts the
196         /// <see cref="F:AddHijriDate"/>
197         /// adjusted fixed day number the a
198         /// <see cref="T:System.DateTime"/> value using a number
199         /// of time parameters.
200         /// </summary>
201         /// <param name="date">The
202         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
203         /// </param>
204         /// <param name="hour">An integer that specifies the hour.
205         /// </param>
206         /// <param name="minute">An integer that specifies the minute.
207         /// </param>
208         /// <param name="second">An integer that gives the second.
209         /// </param>
210         /// <param name="milliseconds">An integer that gives the
211         /// milliseconds.
212         /// </param>
213         /// <returns>The converted
214         /// <see cref="T:System.DateTime"/> value.
215         /// </returns>
216         internal DateTime M_ToDateTime(int date,
217                 int hour, int minute, int second, int milliseconds)
218         {
219                 return CCFixed.ToDateTime(date+AddHijriDate,
220                         hour, minute, second, milliseconds);
221         }
222
223         /// <summary>
224         /// A protected method checking the era number.
225         /// </summary>
226         /// <param name="era">The era number.</param>
227         /// <exception name="T:System.ArgumentException">
228         /// The exception is thrown if the era is not equal
229         /// <see cref="F:HijriEra"/>.
230         /// </exception>
231         internal void M_CheckEra(ref int era) {
232                 if (era == CurrentEra)
233                         era = HijriEra;
234                 if (era != HijriEra)
235                         throw new ArgumentException("Era value was not valid.");
236         }
237
238         /// <summary>
239         /// A protected method checking calendar year and the era number.
240         /// </summary>
241         /// <param name="year">An integer representing the calendar year.
242         /// </param>
243         /// <param name="era">The era number.</param>
244         /// <exception cref="T:System.ArgumentException">
245         /// The exception is thrown if the era is not equal
246         /// <see cref="F:HijriEra"/>.
247         /// </exception>
248         /// <exception cref="T:System.ArgumentOutOfRangeException">
249         /// The exception is thrown if the calendar year is outside of
250         /// the allowed range.
251         /// </exception>
252         internal override void M_CheckYE(int year, ref int era) {
253                 M_CheckEra(ref era);
254                 M_ArgumentInRange("year", year, 1, 9666);
255         }
256
257         /// <summary>
258         /// A protected method checking the calendar year, month, and
259         /// era number.
260         /// </summary>
261         /// <param name="year">An integer representing the calendar year.
262         /// </param>
263         /// <param name="month">An integer giving the calendar month.
264         /// </param>
265         /// <param name="era">The era number.</param>
266         /// <exception cref="T:System.ArgumentException">
267         /// The exception is thrown if the era is not equal
268         /// <see cref="F:HijriEra"/>.
269         /// </exception>
270         /// <exception cref="T:System.ArgumentOutOfRangeException">
271         /// The exception is thrown if the calendar year or month is
272         /// outside of the allowed range.
273         /// </exception>
274         internal void M_CheckYME(int year, int month, ref int era) {
275                 M_CheckYE(year, ref era);
276                 if (month < 1 || month > 12)
277                         throw new ArgumentOutOfRangeException("month",
278                                 "Month must be between one and twelve.");
279                 if (year == 9666) {
280                         int rd = CCHijriCalendar.fixed_from_dmy(1, month, year);
281                         M_CheckFixedHijri("month", rd);
282                 }
283         }
284
285         /// <summary>
286         /// A protected method checking the calendar day, month, and year
287         /// and the era number.
288         /// </summary>
289         /// <param name="year">An integer representing the calendar year.
290         /// </param>
291         /// <param name="month">An integer giving the calendar month.
292         /// </param>
293         /// <param name="day">An integer giving the calendar day.
294         /// </param>
295         /// <param name="era">The era number.</param>
296         /// <exception cref="T:System.ArgumentException">
297         /// The exception is thrown if the era is not equal
298         /// <see cref="F:HijriEra"/>.
299         /// </exception>
300         /// <exception cref="T:System.ArgumentOutOfRangeException">
301         /// The exception is thrown if the calendar year, month, or day is
302         /// outside of the allowed range.
303         /// </exception>
304         internal void M_CheckYMDE(int year, int month, int day, ref int era)
305         {
306                 M_CheckYME(year, month, ref era);
307                 M_ArgumentInRange("day", day, 1,
308                         GetDaysInMonth(year, month, HijriEra));
309                 if (year == 9666) {
310                         int rd = CCHijriCalendar.fixed_from_dmy(day, month,
311                                 year);
312                         M_CheckFixedHijri("day", rd);
313                 }
314         }
315
316 #if false
317         //
318         // The following routines are commented out as they do not appear on the .NET Framework 1.1
319         //
320
321         /// <summary>
322         /// Overridden. Adds days to a given date.
323         /// </summary>
324         /// <param name="time">The
325         /// <see cref="T:System.DateTime"/> to which to add
326         /// days.
327         /// </param>
328         /// <param name="days">The number of days to add.</param>
329         /// <returns>A new <see cref="T:System.DateTime"/> value, that
330         /// results from adding <paramref name="days"/> to the specified
331         /// DateTime.</returns>
332         /// <exception cref="T:System.ArgumentOutOfRangeException">
333         /// The exception is thrown if the
334         /// <see cref="T:System.DateTime"/> return value is not in the
335         /// supported range of the Hijri calendar.
336         /// </exception>
337         public override DateTime AddDays(DateTime time, int days) {
338                 DateTime t = base.AddDays(time, days);
339                 M_CheckDateTime(t);
340                 return t;
341         }
342
343         /// <summary>
344         /// Overridden. Adds hours to a given date.
345         /// </summary>
346         /// <param name="time">The
347         /// <see cref="T:System.DateTime"/> to which to add
348         /// hours.
349         /// </param>
350         /// <param name="hours">The number of hours to add.</param>
351         /// <returns>A new <see cref="T:System.DateTime"/> value, that
352         /// results from adding <paramref name="hours"/> to the specified
353         /// DateTime.</returns>
354         /// <exception cref="T:System.ArgumentOutOfRangeException">
355         /// The exception is thrown if the
356         /// <see cref="T:System.DateTime"/> return value is not in the
357         /// supported range of the Hijri calendar.
358         /// </exception>
359         public override DateTime AddHours(DateTime time, int hours) {
360                 DateTime t = base.AddHours(time, hours);
361                 M_CheckDateTime(t);
362                 return t;
363         }
364
365         /// <summary>
366         /// Overridden. Adds milliseconds to a given date.
367         /// </summary>
368         /// <param name="time">The
369         /// <see cref="T:System.DateTime"/> to which to add
370         /// milliseconds.
371         /// </param>
372         /// <param name="milliseconds">The number of milliseconds given as
373         /// double to add. Keep in mind the 100 nanosecond resolution of 
374         /// <see cref="T:System.DateTime"/>.
375         /// </param>
376         /// <returns>A new <see cref="T:System.DateTime"/> value, that
377         /// results from adding <paramref name="milliseconds"/> to the specified
378         /// DateTime.</returns>
379         /// <exception cref="T:System.ArgumentOutOfRangeException">
380         /// The exception is thrown if the
381         /// <see cref="T:System.DateTime"/> return value is not in the
382         /// supported range of the Hijri calendar.
383         /// </exception>
384         public override DateTime AddMilliseconds(DateTime time,
385                 double milliseconds)
386         {
387                 DateTime t = base.AddMilliseconds(time, milliseconds);
388                 M_CheckDateTime(t);
389                 return t;
390         }
391
392         /// <summary>
393         /// Overridden. Adds minutes to a given date.
394         /// </summary>
395         /// <param name="time">The
396         /// <see cref="T:System.DateTime"/> to which to add
397         /// minutes.
398         /// </param>
399         /// <param name="minutes">The number of minutes to add.</param>
400         /// <returns>A new <see cref="T:System.DateTime"/> value, that
401         /// results from adding <paramref name="minutes"/> to the specified
402         /// DateTime.</returns>
403         /// <exception cref="T:System.ArgumentOutOfRangeException">
404         /// The exception is thrown if the
405         /// <see cref="T:System.DateTime"/> return value is not in the
406         /// supported range of the Hijri calendar.
407         /// </exception>
408         public override DateTime AddMinutes(DateTime time, int minutes) {
409                 DateTime t = base.AddMinutes(time, minutes);
410                 M_CheckDateTime(t);
411                 return t;
412         }
413
414         /// <summary>
415         /// Overridden. Adds seconds to a given date.
416         /// </summary>
417         /// <param name="time">The
418         /// <see cref="T:System.DateTime"/> to which to add
419         /// seconds.
420         /// </param>
421         /// <param name="seconds">The number of seconds to add.</param>
422         /// <returns>A new <see cref="T:System.DateTime"/> value, that
423         /// results from adding <paramref name="seconds"/> to the specified
424         /// DateTime.</returns>
425         /// <exception cref="T:System.ArgumentOutOfRangeException">
426         /// The exception is thrown if the
427         /// <see cref="T:System.DateTime"/> return value is not in the
428         /// supported range of the Hijri calendar.
429         /// </exception>
430         public override DateTime AddSeconds(DateTime time, int seconds) {
431                 DateTime t = base.AddSeconds(time, seconds);
432                 M_CheckDateTime(t);
433                 return t;
434         }
435
436         /// <summary>
437         /// Overridden. Adds weeks to a given date.
438         /// </summary>
439         /// <param name="time">The
440         /// <see cref="T:System.DateTime"/> to which to add
441         /// weeks.
442         /// </param>
443         /// <param name="weeks">The number of weeks to add.</param>
444         /// <returns>A new <see cref="T:System.DateTime"/> value, that
445         /// results from adding <paramref name="weeks"/> to the specified
446         /// DateTime.</returns>
447         /// <exception cref="T:System.ArgumentOutOfRangeException">
448         /// The exception is thrown if the
449         /// <see cref="T:System.DateTime"/> return value is not in the
450         /// supported range of the Hijri calendar.
451         /// </exception>
452         public override DateTime AddWeeks(DateTime time, int weeks) {
453                 DateTime t = base.AddWeeks(time, weeks);
454                 M_CheckDateTime(t);
455                 return t;
456         }
457
458         /// <summary>
459         /// Overridden. Gives the hour of the specified time.
460         /// </summary>
461         /// <param name="time">The
462         /// <see cref="T:System.DateTime"/> that specifies the
463         /// time.
464         /// </param>
465         /// <returns>An integer that gives the hour of the specified time,
466         /// starting with 0.</returns>
467         /// <exception cref="T:System.ArgumentOutOfRangeException">
468         /// The exception is thrown if the
469         /// <see cref="T:System.DateTime"/> parameter is not in the
470         /// supported range of the Hijri calendar.
471         /// </exception>
472         public override int GetHour(DateTime time) {
473                 M_CheckDateTime(time);
474                 return base.GetHour(time);
475         }
476
477         /// <summary>
478         /// Overridden. Gives the milliseconds in the current second
479         /// of the specified time.
480         /// </summary>
481         /// <param name="time">The
482         /// <see cref="T:System.DateTime"/> that specifies the
483         /// time.
484         /// </param>
485         /// <returns>An integer that gives the milliseconds in the seconds
486         /// of the specified time, starting with 0.</returns>
487         /// <exception cref="T:System.ArgumentOutOfRangeException">
488         /// The exception is thrown if the
489         /// <see cref="T:System.DateTime"/> parameter is not in the
490         /// supported range of the Hijri calendar.
491         /// </exception>
492         public override double GetMilliseconds(DateTime time) {
493                 M_CheckDateTime(time);
494                 return base.GetMilliseconds(time);
495         }
496
497         /// <summary>
498         /// Overridden. Gives the minute of the specified time.
499         /// </summary>
500         /// <param name="time">The
501         /// <see cref="T:System.DateTime"/> that specifies the
502         /// time.
503         /// </param>
504         /// <returns>An integer that gives the minute of the specified time,
505         /// starting with 0.</returns>
506         /// <exception cref="T:System.ArgumentOutOfRangeException">
507         /// The exception is thrown if the
508         /// <see cref="T:System.DateTime"/> parameter is not in the
509         /// supported range of the Hijri calendar.
510         /// </exception>
511         public override int GetMinute(DateTime time) {
512                 M_CheckDateTime(time);
513                 return base.GetMinute(time);
514         }
515
516         /// <summary>
517         /// Overridden. Gives the second of the specified time.
518         /// </summary>
519         /// <param name="time">The
520         /// <see cref="T:System.DateTime"/> that specifies the
521         /// time.
522         /// </param>
523         /// <returns>An integer that gives the second of the specified time,
524         /// starting with 0.</returns>
525         /// <exception cref="T:System.ArgumentOutOfRangeException">
526         /// The exception is thrown if the
527         /// <see cref="T:System.DateTime"/> parameter is not in the
528         /// supported range of the Hijri calendar.
529         /// </exception>
530         public override int GetSecond(DateTime time) {
531                 M_CheckDateTime(time);
532                 return base.GetMinute(time);
533         }
534 #endif
535         
536         /// <summary>
537         /// Overrideden. Adds months to a given date.
538         /// </summary>
539         /// <param name="time">The
540         /// <see cref="T:System.DateTime"/> to which to add
541         /// months.
542         /// </param>
543         /// <param name="months">The number of months to add.</param>
544         /// <returns>A new <see cref="T:System.DateTime"/> value, that
545         /// results from adding <paramref name="months"/> to the specified
546         /// DateTime.</returns>
547         /// <exception cref="T:System.ArgumentOutOfRangeException">
548         /// The exception is thrown if the
549         /// <see cref="T:System.DateTime"/> return value is not in the
550         /// supported range of the Hijri calendar.
551         /// </exception>
552         public override DateTime AddMonths(DateTime time, int months) {
553                 int rd = M_FromDateTime(time);
554                 int day, month, year;
555                 CCHijriCalendar.dmy_from_fixed(
556                         out day, out month, out year, rd);
557                 month += months;
558                 year += CCMath.div_mod(out month, month, 12);
559                 rd = CCHijriCalendar.fixed_from_dmy(day, month, year);
560                 M_CheckFixedHijri("time", rd);
561                 DateTime t = M_ToDateTime(rd);
562                 return t.Add(time.TimeOfDay);
563         }
564
565         /// <summary>
566         /// Overrideden. Adds years to a given date.
567         /// </summary>
568         /// <param name="time">The
569         /// <see cref="T:System.DateTime"/> to which to add
570         /// years.
571         /// </param>
572         /// <param name="years">The number of years to add.</param>
573         /// <returns>A new <see cref="T:System.DateTime"/> value, that
574         /// results from adding <paramref name="years"/> to the specified
575         /// DateTime.</returns>
576         /// <exception cref="T:System.ArgumentOutOfRangeException">
577         /// The exception is thrown if the
578         /// <see cref="T:System.DateTime"/> return value is not in the
579         /// supported range of the Hijri calendar.
580         /// </exception>
581         public override DateTime AddYears(DateTime time, int years) {
582                 int rd = M_FromDateTime(time);
583                 int day, month, year;
584                 CCHijriCalendar.dmy_from_fixed(
585                         out day, out month, out year, rd);
586                 year += years;
587                 rd = CCHijriCalendar.fixed_from_dmy(day, month, year);
588                 M_CheckFixedHijri("time", rd);
589                 DateTime t = M_ToDateTime(rd);
590                 return t.Add(time.TimeOfDay);
591         }
592                 
593         /// <summary>
594         /// Overriden. Gets the day of the month from
595         /// <paramref name="time"/>.
596         /// </summary>
597         /// <param name="time">The
598         /// <see cref="T:System.DateTime"/> that specifies a
599         /// date.
600         /// </param>
601         /// <returns>An integer giving the day of months, starting with 1.
602         /// </returns>
603         /// <exception cref="T:System.ArgumentOutOfRangeException">
604         /// The exception is thrown if the
605         /// <see cref="T:System.DateTime"/> parameter is not in the
606         /// supported range of the Hijri calendar.
607         /// </exception>
608         public override int GetDayOfMonth(DateTime time) {
609                 int rd = M_FromDateTime(time);
610                 M_CheckFixedHijri("time", rd);
611                 return CCHijriCalendar.day_from_fixed(rd);
612         }
613
614         /// <summary>
615         /// Overriden. Gets the day of the week from the specified date.
616         /// </summary>
617         /// <param name="time">The
618         /// <see cref="T:System.DateTime"/> that specifies a
619         /// date.
620         /// </param>
621         /// <returns>An integer giving the day of months, starting with 1.
622         /// </returns>
623         /// <exception cref="T:System.ArgumentOutOfRangeException">
624         /// The exception is thrown if the
625         /// <see cref="T:System.DateTime"/> parameter is not in the
626         /// supported range of the Hijri calendar.
627         /// </exception>
628         public override DayOfWeek GetDayOfWeek(DateTime time) {
629                 int rd = M_FromDateTime(time);
630                 M_CheckFixedHijri("time", rd);
631                 return (DayOfWeek)CCFixed.day_of_week(rd);
632         }
633
634         /// <summary>
635         /// Overridden. Gives the number of the day in the year.
636         /// </summary>
637         /// <param name="time">The
638         /// <see cref="T:System.DateTime"/> that specifies a
639         /// date.
640         /// </param>
641         /// <returns>An integer representing the day of the year,
642         /// starting with 1.</returns>
643         /// <exception cref="T:System.ArgumentOutOfRangeException">
644         /// The exception is thrown if the
645         /// <see cref="T:System.DateTime"/> parameter is not in the
646         /// supported range of the Hijri calendar.
647         /// </exception>
648         public override int GetDayOfYear(DateTime time) {
649                 int rd = M_FromDateTime(time);
650                 M_CheckFixedHijri("time", rd);
651                 int year = CCHijriCalendar.year_from_fixed(rd);
652                 int rd1_1 = CCHijriCalendar.fixed_from_dmy(1, 1, year);
653                 return rd - rd1_1 + 1;
654         }
655
656         /// <summary>
657         /// Overridden. Gives the number of days in the specified month
658         /// of the given year and era.
659         /// </summary>
660         /// <param name="year">An integer that gives the year.
661         /// </param>
662         /// <param name="month">An integer that gives the month, starting
663         /// with 1.</param>
664         /// <param name="era">An intger that gives the era of the specified
665         /// year.</param>
666         /// <returns>An integer that gives the number of days of the
667         /// specified month.</returns>
668         /// <exception cref="T:System.ArgumentOutOfRangeException">
669         /// The exception is thrown, if <paramref name="month"/>,
670         /// <paramref name="year"/> ,or <paramref name="era"/> is outside
671         /// the allowed range.
672         /// </exception>
673         public override int GetDaysInMonth(int year, int month, int era) {
674                 M_CheckYME(year, month, ref era);
675                 int rd1 = CCHijriCalendar.fixed_from_dmy(1, month, year);
676                 int rd2 = CCHijriCalendar.fixed_from_dmy(1, month+1, year);
677                 return rd2 - rd1;
678         }
679
680         /// <summary>
681         /// Overridden. Gives the number of days of the specified
682         /// year of the given era. 
683         /// </summary>
684         /// <param name="year">An integer that specifies the year. 
685         /// </param>
686         /// <param name="era">An ineger that specifies the era.
687         /// </param>
688         /// <returns>An integer that gives the number of days of the
689         /// specified year.</returns>
690         /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
691         /// The exception is thrown, if
692         /// <paramref name="year"/> is outside the allowed range.
693         /// </exception>
694         public override int GetDaysInYear(int year, int era) {
695                 M_CheckYE(year, ref era);
696                 int rd1 = CCHijriCalendar.fixed_from_dmy(1, 1, year);
697                 int rd2 = CCHijriCalendar.fixed_from_dmy(1, 1, year+1);
698                 return rd2 - rd1;
699         }
700                 
701
702         /// <summary>
703         /// Overridden. Gives the era of the specified date.
704         /// </summary>
705         /// <param name="time">The
706         /// <see cref="T:System.DateTime"/> that specifies a
707         /// date.
708         /// </param>
709         /// <returns>An integer representing the era of the calendar.
710         /// </returns>
711         /// <exception cref="T:System.ArgumentOutOfRangeException">
712         /// The exception is thrown if the
713         /// <see cref="T:System.DateTime"/> parameter is not in the
714         /// supported range of the Hijri calendar.
715         /// </exception>
716         public override int GetEra(DateTime time) {
717                 M_CheckDateTime(time);
718                 return HijriEra;
719         }
720
721         /// <summary>
722         /// Overridden. Gives the number of the month of the specified
723         /// date.
724         /// </summary>
725         /// <param name="time">The
726         /// <see cref="T:System.DateTime"/> that specifies a
727         /// date.
728         /// </param>
729         /// <returns>An integer representing the month, 
730         /// starting with 1.</returns>
731         /// <exception cref="T:System.ArgumentOutOfRangeException">
732         /// The exception is thrown if the
733         /// <see cref="T:System.DateTime"/> parameter is not in the
734         /// supported range of the Hijri calendar.
735         /// </exception>
736         public override int GetMonth(DateTime time) {
737                 int rd = M_FromDateTime(time);
738                 M_CheckFixedHijri("time", rd);
739                 return CCHijriCalendar.month_from_fixed(rd);
740         }
741
742         /// <summary>
743         /// Overridden. Gives the number of months in the specified year 
744         /// and era.
745         /// </summary>
746         /// <param name="year">An integer that specifies the year.
747         /// </param>
748         /// <param name="era">An integer that specifies the era.
749         /// </param>
750         /// <returns>An integer that gives the number of the months in the
751         /// specified year.</returns>
752         /// <exception cref="T:System.ArgumentOutOfRangeException">
753         /// The exception is thrown, if the year or the era are not valid.
754         /// </exception>
755         public override int GetMonthsInYear(int year, int era) {
756                 M_CheckYE(year, ref era);
757                 return 12;
758         }
759
760         /// <summary>
761         /// Overridden. Gives the number of the year of the specified
762         /// date.
763         /// </summary>
764         /// <param name="time">The
765         /// <see cref="T:System.DateTime"/> that specifies a
766         /// date.
767         /// </param>
768         /// <returns>An integer representing the year, 
769         /// starting with 1.</returns>
770         /// <exception cref="T:System.ArgumentOutOfRangeException">
771         /// The exception is thrown if the
772         /// <see cref="T:System.DateTime"/> parameter is not in the
773         /// supported range of the Hijri calendar.
774         /// </exception>
775         public override int GetYear(DateTime time) {
776                 int rd = M_FromDateTime(time);
777                 M_CheckFixedHijri("time", rd);
778                 return CCHijriCalendar.year_from_fixed(rd);
779         }
780
781         /// <summary>
782         /// Overridden. Tells whether the given day 
783         /// is a leap day.
784         /// </summary>
785         /// <param name="year">An integer that specifies the year in the
786         /// given era.
787         /// </param>
788         /// <param name="month">An integer that specifies the month.
789         /// </param>
790         /// <param name="day">An integer that specifies the day.
791         /// </param>
792         /// <param name="era">An integer that specifies the era.
793         /// </param>
794         /// <returns>A boolean that tells whether the given day is a leap
795         /// day.
796         /// </returns>
797         /// <exception cref="T:System.ArgumentOutOfRangeException">
798         /// The exception is thrown, if the year, month, day, or era is not
799         /// valid.
800         /// </exception>
801         public override bool IsLeapDay(int year, int month, int day, int era)
802         {
803                 M_CheckYMDE(year, month, day, ref era);
804                 return IsLeapYear(year) && month == 12 && day == 30;
805         }
806
807         /// <summary>
808         /// Overridden. Tells whether the given month 
809         /// is a leap month.
810         /// </summary>
811         /// <param name="year">An integer that specifies the year in the
812         /// given era.
813         /// </param>
814         /// <param name="month">An integer that specifies the month.
815         /// </param>
816         /// <param name="era">An integer that specifies the era.
817         /// </param>
818         /// <returns>A boolean that tells whether the given month is a leap
819         /// month.
820         /// </returns>
821         /// <exception cref="T:System.ArgumentOutOfRangeException">
822         /// The exception is thrown, if the year, month, or era is not
823         /// valid.
824         /// </exception>
825         public override bool IsLeapMonth(int year, int month, int era) {
826                 M_CheckYME(year, month, ref era);
827                 return false;
828         }
829
830         /// <summary>
831         /// Overridden. Tells whether the given year
832         /// is a leap year.
833         /// </summary>
834         /// <param name="year">An integer that specifies the year in the
835         /// given era.
836         /// </param>
837         /// <param name="era">An integer that specifies the era.
838         /// </param>
839         /// <returns>A boolean that tells whether the given year is a leap
840         /// year.
841         /// </returns>
842         /// <exception cref="T:System.ArgumentOutOfRangeException">
843         /// The exception is thrown, if the year or era is not
844         /// valid.
845         /// </exception>
846         public override bool IsLeapYear(int year, int era) {
847                 M_CheckYE(year, ref era);
848                 return CCHijriCalendar.is_leap_year(year);
849         }
850
851         /// <summary>
852         /// Overridden. Creates the
853         /// <see cref="T:System.DateTime"/> from the parameters.
854         /// </summary>
855         /// <param name="year">An integer that gives the year in the
856         /// <paramref name="era"/>.
857         /// </param>
858         /// <param name="month">An integer that specifies the month.
859         /// </param>
860         /// <param name="day">An integer that specifies the day.
861         /// </param>
862         /// <param name="hour">An integer that specifies the hour.
863         /// </param>
864         /// <param name="minute">An integer that specifies the minute.
865         /// </param>
866         /// <param name="second">An integer that gives the second.
867         /// </param>
868         /// <param name="milliseconds">An integer that gives the
869         /// milliseconds.
870         /// </param>
871         /// <param name="era">An integer that specifies the era.
872         /// </param>
873         /// <returns>A
874         /// <see cref="T:system.DateTime"/> representig the date and time.
875         /// </returns>
876         /// <exception cref="T:System.ArgumentOutOfRangeException">
877         /// The exception is thrown, if at least one of the parameters
878         /// is out of range.
879         /// </exception>
880         public override DateTime ToDateTime(int year, int month, int day,
881                 int hour, int minute, int second, int milliseconds,
882                 int era)
883         {
884                 M_CheckYMDE(year, month, day, ref era);
885                 M_CheckHMSM(hour, minute, second, milliseconds);
886                 int rd = CCHijriCalendar.fixed_from_dmy(day, month, year);
887                 return M_ToDateTime(rd,
888                         hour, minute, second, milliseconds);
889         }
890
891         [MonoTODO]
892         public override int ToFourDigitYear(int year)
893         {
894                 throw new NotImplementedException();
895         }
896         
897 } // class HijriCalendar
898         
899 } // namespace System.Globalization