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