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