Add [Category ("NotWorking")] to failing test.
[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 namespace System.Globalization {
37
38 using System;
39 using System.IO;
40
41
42 /// <summary>
43 /// This is the Hijri calendar which might be called Islamic calendar. 
44 /// </summary>
45 /// <remarks>
46 /// <para>The calendar supports only dates in the UmAlQuraEra starting with the 
47 /// epoch.
48 /// </para>
49 /// <para>
50 /// The epoch of the Hijri Calendar might be adjusted by the 
51 /// <see cref="F:System.Globalization.HijriCalendar.AddHijriDate"/>
52 /// property. See the discussion of the
53 /// <see cref="F:CalendricalCalculations.HijriCalendar.epoch">
54 /// epoch
55 /// </see>
56 /// of the Hijri calendar.
57 /// </para>
58 /// <para>The implementation uses the
59 /// <see cref="N:CalendricalCalculations"/> namespace.
60 /// </para>
61 /// </remarks>
62 [Serializable]
63 [MonoTODO ("Serialization format not compatible with .NET")]
64 public class UmAlQuraCalendar : Calendar {
65         /// <summary>
66         /// Constructor.
67         /// </summary>
68         public UmAlQuraCalendar() {
69                 M_AbbrEraNames = new string[] {"A.H."};
70                 M_EraNames = new string[] {"Anno Hegirae"};
71                 if (twoDigitYearMax == 99)
72                         twoDigitYearMax = 1451;
73         }
74
75         /// <summary>
76         /// The era number for the Anno Hegirae (A.H.) era.
77         /// </summary>
78         public const int UmAlQuraEra = 1;
79
80         /// <summary>
81         /// The minimum fixed day number supported by the Hijri calendar.
82         /// </summary>
83         internal static readonly int M_MinFixed =
84                 CCHijriCalendar.fixed_from_dmy(1, 1, 1);
85         /// <summary>
86         /// The maximum fixed day number supported by the Hijri calendar.
87         /// </summary>
88         internal static readonly int M_MaxFixed =
89                 CCGregorianCalendar.fixed_from_dmy(31, 12, 9999);
90
91         /// <value>Overridden. Gives the eras supported by the Gregorian
92         /// calendar as an array of integers.
93         /// </value>
94         public override int[] Eras {
95                 get {
96                         return new int[] { UmAlQuraEra }; 
97                 }
98         }
99
100         // FIXME: [MonoTODO ("Add call into operating system")]
101         public override int TwoDigitYearMax 
102         {
103                 get {
104                         return twoDigitYearMax;
105                 }
106                 set {
107                         CheckReadOnly ();
108                         M_ArgumentInRange ("value", value, 100, M_MaxYear);
109
110                         twoDigitYearMax = value;
111                 }
112         }
113
114         /// <summary>
115         /// Protected field storing the
116         /// <see cref="F:AddHijriDate"/>.
117         /// </summary>
118         internal int M_AddHijriDate = 0;
119
120         // TODO: I don't know currently, which sign to use with the parameter.
121         /// <value>An integer property representing the adjustment to the epoch
122         /// of the Hijri calendar. Not supported by .NET.
123         /// </value>
124         internal virtual int AddHijriDate {
125                 get {
126                         return M_AddHijriDate;
127                 }
128                 set {
129                         CheckReadOnly ();
130                         if (value < -3 && value > 3)
131                                 throw new ArgumentOutOfRangeException(
132                                         "AddHijriDate",
133                                         "Value should be between -3 and 3.");
134                         M_AddHijriDate = value;
135                 }
136         }
137         
138         /// <summary>
139         /// A protected method checking an
140         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
141         /// </summary>
142         /// <param name="param">A string giving the name of the parameter
143         /// to check.</param>
144         /// <param name="rdHijri">An integer giving the AddHijriDate adjusted
145         /// fixed day number.
146         /// </param>
147         /// <exception cref="T:System.ArgumentOutOfRangeException">
148         /// Exception is thrown, if the AddHijriDate adjusted fixed day
149         /// number is outside the supported range.
150         /// </exception>
151         internal void M_CheckFixedHijri(string param, int rdHijri) {
152                 if (rdHijri < M_MinFixed || rdHijri > M_MaxFixed-AddHijriDate) {
153                         StringWriter sw = new StringWriter();
154                         int day, month, year;
155                         CCHijriCalendar.dmy_from_fixed(out day, out month,
156                                 out year, M_MaxFixed-AddHijriDate);
157                         if (AddHijriDate != 0) {
158                                 sw.Write("This HijriCalendar " +
159                                         "(AddHijriDate {0})" +
160                                         " allows dates from 1. 1. 1 to " +
161                                         "{1}. {2}. {3}.",
162                                         AddHijriDate,
163                                         day, month, year);
164                         } else {
165                                 sw.Write("HijriCalendar allows dates from " +
166                                         "1.1.1 to {0}.{1}.{2}.",
167                                         day, month, year);
168                         }
169                         throw new ArgumentOutOfRangeException(param,
170                                 sw.ToString());
171                 }
172         }
173
174         /// <summary>
175         /// A protected member checking a
176         /// <see cref="T:System.DateTime"/> value.
177         /// </summary>
178         /// <param name="time">The
179         /// <see cref="T:System.DateTime"/>
180         /// to check.
181         /// </param>
182         /// <exception cref="T:System.ArgumentOutOfRangeException">
183         /// The exception is thrown if the
184         /// <see cref="T:System.DateTime"/> parameter is not in the supported 
185         /// range of the Hijri calendar.
186         /// </exception>
187         internal void M_CheckDateTime(DateTime time) {
188                 int rd = CCFixed.FromDateTime(time) - AddHijriDate;
189                 M_CheckFixedHijri("time", rd);
190         }
191
192         /// <summary>
193         /// Protected member which computes the
194         /// <see cref="F:AddHijriDate"/>
195         /// adjusted fixed day number from a
196         /// <see cref="T:System.DateTime"/>.
197         /// </summary>
198         /// <param name="time">The
199         /// <see cref="T:System.DateTime"/>
200         /// to convert.
201         /// </param>
202         /// <returns>The
203         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
204         /// </returns>
205         internal int M_FromDateTime(DateTime time) {
206                 return CCFixed.FromDateTime(time) - AddHijriDate;
207         }
208
209         /// <summary>
210         /// Protected member which converts the
211         /// <see cref="F:AddHijriDate"/>
212         /// adjusted fixed day number the a
213         /// <see cref="T:System.DateTime"/> value.
214         /// </summary>
215         /// <param name="rd">The
216         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
217         /// </param>
218         /// <returns>The converted
219         /// <see cref="T:System.DateTime"/> value.
220         /// </returns>
221         internal DateTime M_ToDateTime(int rd) {
222                 return CCFixed.ToDateTime(rd+AddHijriDate);
223         }
224
225         /// <summary>
226         /// Protected member which converts the
227         /// <see cref="F:AddHijriDate"/>
228         /// adjusted fixed day number the a
229         /// <see cref="T:System.DateTime"/> value using a number
230         /// of time parameters.
231         /// </summary>
232         /// <param name="date">The
233         /// <see cref="F:AddHijriDate"/> adjusted fixed day number.
234         /// </param>
235         /// <param name="hour">An integer that specifies the hour.
236         /// </param>
237         /// <param name="minute">An integer that specifies the minute.
238         /// </param>
239         /// <param name="second">An integer that gives the second.
240         /// </param>
241         /// <param name="milliseconds">An integer that gives the
242         /// milliseconds.
243         /// </param>
244         /// <returns>The converted
245         /// <see cref="T:System.DateTime"/> value.
246         /// </returns>
247         internal DateTime M_ToDateTime(int date,
248                 int hour, int minute, int second, int milliseconds)
249         {
250                 return CCFixed.ToDateTime(date+AddHijriDate,
251                         hour, minute, second, milliseconds);
252         }
253
254         /// <summary>
255         /// A protected method checking the era number.
256         /// </summary>
257         /// <param name="era">The era number.</param>
258         /// <exception name="T:System.ArgumentException">
259         /// The exception is thrown if the era is not equal
260         /// <see cref="F:UmAlQuraEra"/>.
261         /// </exception>
262         internal void M_CheckEra(ref int era) {
263                 if (era == CurrentEra)
264                         era = UmAlQuraEra;
265                 if (era != UmAlQuraEra)
266                         throw new ArgumentException("Era value was not valid.");
267         }
268
269         /// <summary>
270         /// A protected method checking calendar year and the era number.
271         /// </summary>
272         /// <param name="year">An integer representing the calendar year.
273         /// </param>
274         /// <param name="era">The era number.</param>
275         /// <exception cref="T:System.ArgumentException">
276         /// The exception is thrown if the era is not equal
277         /// <see cref="F:UmAlQuraEra"/>.
278         /// </exception>
279         /// <exception cref="T:System.ArgumentOutOfRangeException">
280         /// The exception is thrown if the calendar year is outside of
281         /// the allowed range.
282         /// </exception>
283         internal override void M_CheckYE(int year, ref int era) {
284                 M_CheckEra(ref era);
285                 M_ArgumentInRange("year", year, 1, 9666);
286         }
287
288         /// <summary>
289         /// A protected method checking the calendar year, month, and
290         /// era number.
291         /// </summary>
292         /// <param name="year">An integer representing the calendar year.
293         /// </param>
294         /// <param name="month">An integer giving the calendar month.
295         /// </param>
296         /// <param name="era">The era number.</param>
297         /// <exception cref="T:System.ArgumentException">
298         /// The exception is thrown if the era is not equal
299         /// <see cref="F:UmAlQuraEra"/>.
300         /// </exception>
301         /// <exception cref="T:System.ArgumentOutOfRangeException">
302         /// The exception is thrown if the calendar year or month is
303         /// outside of the allowed range.
304         /// </exception>
305         internal void M_CheckYME(int year, int month, ref int era) {
306                 M_CheckYE(year, ref era);
307                 if (month < 1 || month > 12)
308                         throw new ArgumentOutOfRangeException("month",
309                                 "Month must be between one and twelve.");
310                 if (year == 9666) {
311                         int rd = CCHijriCalendar.fixed_from_dmy(1, month, year);
312                         M_CheckFixedHijri("month", rd);
313                 }
314         }
315
316         /// <summary>
317         /// A protected method checking the calendar day, month, and year
318         /// and the era number.
319         /// </summary>
320         /// <param name="year">An integer representing the calendar year.
321         /// </param>
322         /// <param name="month">An integer giving the calendar month.
323         /// </param>
324         /// <param name="day">An integer giving the calendar day.
325         /// </param>
326         /// <param name="era">The era number.</param>
327         /// <exception cref="T:System.ArgumentException">
328         /// The exception is thrown if the era is not equal
329         /// <see cref="F:UmAlQuraEra"/>.
330         /// </exception>
331         /// <exception cref="T:System.ArgumentOutOfRangeException">
332         /// The exception is thrown if the calendar year, month, or day is
333         /// outside of the allowed range.
334         /// </exception>
335         internal void M_CheckYMDE(int year, int month, int day, ref int era)
336         {
337                 M_CheckYME(year, month, ref era);
338                 M_ArgumentInRange("day", day, 1,
339                         GetDaysInMonth(year, month, UmAlQuraEra));
340                 if (year == 9666) {
341                         int rd = CCHijriCalendar.fixed_from_dmy(day, month,
342                                 year);
343                         M_CheckFixedHijri("day", rd);
344                 }
345         }
346
347 #if false
348         //
349         // The following routines are commented out as they do not appear on the .NET Framework 1.1
350         //
351
352         /// <summary>
353         /// Overridden. Adds days to a given date.
354         /// </summary>
355         /// <param name="time">The
356         /// <see cref="T:System.DateTime"/> to which to add
357         /// days.
358         /// </param>
359         /// <param name="days">The number of days to add.</param>
360         /// <returns>A new <see cref="T:System.DateTime"/> value, that
361         /// results from adding <paramref name="days"/> to the specified
362         /// DateTime.</returns>
363         /// <exception cref="T:System.ArgumentOutOfRangeException">
364         /// The exception is thrown if the
365         /// <see cref="T:System.DateTime"/> return value is not in the
366         /// supported range of the Hijri calendar.
367         /// </exception>
368         public override DateTime AddDays(DateTime time, int days) {
369                 DateTime t = base.AddDays(time, days);
370                 M_CheckDateTime(t);
371                 return t;
372         }
373
374         /// <summary>
375         /// Overridden. Adds hours to a given date.
376         /// </summary>
377         /// <param name="time">The
378         /// <see cref="T:System.DateTime"/> to which to add
379         /// hours.
380         /// </param>
381         /// <param name="hours">The number of hours to add.</param>
382         /// <returns>A new <see cref="T:System.DateTime"/> value, that
383         /// results from adding <paramref name="hours"/> to the specified
384         /// DateTime.</returns>
385         /// <exception cref="T:System.ArgumentOutOfRangeException">
386         /// The exception is thrown if the
387         /// <see cref="T:System.DateTime"/> return value is not in the
388         /// supported range of the Hijri calendar.
389         /// </exception>
390         public override DateTime AddHours(DateTime time, int hours) {
391                 DateTime t = base.AddHours(time, hours);
392                 M_CheckDateTime(t);
393                 return t;
394         }
395
396         /// <summary>
397         /// Overridden. Adds milliseconds to a given date.
398         /// </summary>
399         /// <param name="time">The
400         /// <see cref="T:System.DateTime"/> to which to add
401         /// milliseconds.
402         /// </param>
403         /// <param name="milliseconds">The number of milliseconds given as
404         /// double to add. Keep in mind the 100 nanosecond resolution of 
405         /// <see cref="T:System.DateTime"/>.
406         /// </param>
407         /// <returns>A new <see cref="T:System.DateTime"/> value, that
408         /// results from adding <paramref name="milliseconds"/> to the specified
409         /// DateTime.</returns>
410         /// <exception cref="T:System.ArgumentOutOfRangeException">
411         /// The exception is thrown if the
412         /// <see cref="T:System.DateTime"/> return value is not in the
413         /// supported range of the Hijri calendar.
414         /// </exception>
415         public override DateTime AddMilliseconds(DateTime time,
416                 double milliseconds)
417         {
418                 DateTime t = base.AddMilliseconds(time, milliseconds);
419                 M_CheckDateTime(t);
420                 return t;
421         }
422
423         /// <summary>
424         /// Overridden. Adds minutes to a given date.
425         /// </summary>
426         /// <param name="time">The
427         /// <see cref="T:System.DateTime"/> to which to add
428         /// minutes.
429         /// </param>
430         /// <param name="minutes">The number of minutes to add.</param>
431         /// <returns>A new <see cref="T:System.DateTime"/> value, that
432         /// results from adding <paramref name="minutes"/> to the specified
433         /// DateTime.</returns>
434         /// <exception cref="T:System.ArgumentOutOfRangeException">
435         /// The exception is thrown if the
436         /// <see cref="T:System.DateTime"/> return value is not in the
437         /// supported range of the Hijri calendar.
438         /// </exception>
439         public override DateTime AddMinutes(DateTime time, int minutes) {
440                 DateTime t = base.AddMinutes(time, minutes);
441                 M_CheckDateTime(t);
442                 return t;
443         }
444
445         /// <summary>
446         /// Overridden. Adds seconds to a given date.
447         /// </summary>
448         /// <param name="time">The
449         /// <see cref="T:System.DateTime"/> to which to add
450         /// seconds.
451         /// </param>
452         /// <param name="seconds">The number of seconds to add.</param>
453         /// <returns>A new <see cref="T:System.DateTime"/> value, that
454         /// results from adding <paramref name="seconds"/> to the specified
455         /// DateTime.</returns>
456         /// <exception cref="T:System.ArgumentOutOfRangeException">
457         /// The exception is thrown if the
458         /// <see cref="T:System.DateTime"/> return value is not in the
459         /// supported range of the Hijri calendar.
460         /// </exception>
461         public override DateTime AddSeconds(DateTime time, int seconds) {
462                 DateTime t = base.AddSeconds(time, seconds);
463                 M_CheckDateTime(t);
464                 return t;
465         }
466
467         /// <summary>
468         /// Overridden. Adds weeks to a given date.
469         /// </summary>
470         /// <param name="time">The
471         /// <see cref="T:System.DateTime"/> to which to add
472         /// weeks.
473         /// </param>
474         /// <param name="weeks">The number of weeks to add.</param>
475         /// <returns>A new <see cref="T:System.DateTime"/> value, that
476         /// results from adding <paramref name="weeks"/> to the specified
477         /// DateTime.</returns>
478         /// <exception cref="T:System.ArgumentOutOfRangeException">
479         /// The exception is thrown if the
480         /// <see cref="T:System.DateTime"/> return value is not in the
481         /// supported range of the Hijri calendar.
482         /// </exception>
483         public override DateTime AddWeeks(DateTime time, int weeks) {
484                 DateTime t = base.AddWeeks(time, weeks);
485                 M_CheckDateTime(t);
486                 return t;
487         }
488
489         /// <summary>
490         /// Overridden. Gives the hour of the specified time.
491         /// </summary>
492         /// <param name="time">The
493         /// <see cref="T:System.DateTime"/> that specifies the
494         /// time.
495         /// </param>
496         /// <returns>An integer that gives the hour of the specified time,
497         /// starting with 0.</returns>
498         /// <exception cref="T:System.ArgumentOutOfRangeException">
499         /// The exception is thrown if the
500         /// <see cref="T:System.DateTime"/> parameter is not in the
501         /// supported range of the Hijri calendar.
502         /// </exception>
503         public override int GetHour(DateTime time) {
504                 M_CheckDateTime(time);
505                 return base.GetHour(time);
506         }
507
508         /// <summary>
509         /// Overridden. Gives the milliseconds in the current second
510         /// of the specified time.
511         /// </summary>
512         /// <param name="time">The
513         /// <see cref="T:System.DateTime"/> that specifies the
514         /// time.
515         /// </param>
516         /// <returns>An integer that gives the milliseconds in the seconds
517         /// of the specified time, starting with 0.</returns>
518         /// <exception cref="T:System.ArgumentOutOfRangeException">
519         /// The exception is thrown if the
520         /// <see cref="T:System.DateTime"/> parameter is not in the
521         /// supported range of the Hijri calendar.
522         /// </exception>
523         public override double GetMilliseconds(DateTime time) {
524                 M_CheckDateTime(time);
525                 return base.GetMilliseconds(time);
526         }
527
528         /// <summary>
529         /// Overridden. Gives the minute of the specified time.
530         /// </summary>
531         /// <param name="time">The
532         /// <see cref="T:System.DateTime"/> that specifies the
533         /// time.
534         /// </param>
535         /// <returns>An integer that gives the minute of the specified time,
536         /// starting with 0.</returns>
537         /// <exception cref="T:System.ArgumentOutOfRangeException">
538         /// The exception is thrown if the
539         /// <see cref="T:System.DateTime"/> parameter is not in the
540         /// supported range of the Hijri calendar.
541         /// </exception>
542         public override int GetMinute(DateTime time) {
543                 M_CheckDateTime(time);
544                 return base.GetMinute(time);
545         }
546
547         /// <summary>
548         /// Overridden. Gives the second of the specified time.
549         /// </summary>
550         /// <param name="time">The
551         /// <see cref="T:System.DateTime"/> that specifies the
552         /// time.
553         /// </param>
554         /// <returns>An integer that gives the second of the specified time,
555         /// starting with 0.</returns>
556         /// <exception cref="T:System.ArgumentOutOfRangeException">
557         /// The exception is thrown if the
558         /// <see cref="T:System.DateTime"/> parameter is not in the
559         /// supported range of the Hijri calendar.
560         /// </exception>
561         public override int GetSecond(DateTime time) {
562                 M_CheckDateTime(time);
563                 return base.GetMinute(time);
564         }
565 #endif
566         
567         /// <summary>
568         /// Overrideden. Adds months to a given date.
569         /// </summary>
570         /// <param name="time">The
571         /// <see cref="T:System.DateTime"/> to which to add
572         /// months.
573         /// </param>
574         /// <param name="months">The number of months to add.</param>
575         /// <returns>A new <see cref="T:System.DateTime"/> value, that
576         /// results from adding <paramref name="months"/> to the specified
577         /// DateTime.</returns>
578         /// <exception cref="T:System.ArgumentOutOfRangeException">
579         /// The exception is thrown if the
580         /// <see cref="T:System.DateTime"/> return value is not in the
581         /// supported range of the Hijri calendar.
582         /// </exception>
583         public override DateTime AddMonths(DateTime time, int months) {
584                 int rd = M_FromDateTime(time);
585                 int day, month, year;
586                 CCHijriCalendar.dmy_from_fixed(
587                         out day, out month, out year, rd);
588                 month += months;
589                 year += CCMath.div_mod(out month, month, 12);
590                 rd = CCHijriCalendar.fixed_from_dmy(day, month, year);
591                 M_CheckFixedHijri("time", rd);
592                 DateTime t = M_ToDateTime(rd);
593                 return t.Add(time.TimeOfDay);
594         }
595
596         /// <summary>
597         /// Overrideden. Adds years to a given date.
598         /// </summary>
599         /// <param name="time">The
600         /// <see cref="T:System.DateTime"/> to which to add
601         /// years.
602         /// </param>
603         /// <param name="years">The number of years to add.</param>
604         /// <returns>A new <see cref="T:System.DateTime"/> value, that
605         /// results from adding <paramref name="years"/> to the specified
606         /// DateTime.</returns>
607         /// <exception cref="T:System.ArgumentOutOfRangeException">
608         /// The exception is thrown if the
609         /// <see cref="T:System.DateTime"/> return value is not in the
610         /// supported range of the Hijri calendar.
611         /// </exception>
612         public override DateTime AddYears(DateTime time, int years) {
613                 int rd = M_FromDateTime(time);
614                 int day, month, year;
615                 CCHijriCalendar.dmy_from_fixed(
616                         out day, out month, out year, rd);
617                 year += years;
618                 rd = CCHijriCalendar.fixed_from_dmy(day, month, year);
619                 M_CheckFixedHijri("time", rd);
620                 DateTime t = M_ToDateTime(rd);
621                 return t.Add(time.TimeOfDay);
622         }
623                 
624         /// <summary>
625         /// Overriden. Gets the day of the month from
626         /// <paramref name="time"/>.
627         /// </summary>
628         /// <param name="time">The
629         /// <see cref="T:System.DateTime"/> that specifies a
630         /// date.
631         /// </param>
632         /// <returns>An integer giving the day of months, starting with 1.
633         /// </returns>
634         /// <exception cref="T:System.ArgumentOutOfRangeException">
635         /// The exception is thrown if the
636         /// <see cref="T:System.DateTime"/> parameter is not in the
637         /// supported range of the Hijri calendar.
638         /// </exception>
639         public override int GetDayOfMonth(DateTime time) {
640                 int rd = M_FromDateTime(time);
641                 M_CheckFixedHijri("time", rd);
642                 return CCHijriCalendar.day_from_fixed(rd);
643         }
644
645         /// <summary>
646         /// Overriden. Gets the day of the week from the specified date.
647         /// </summary>
648         /// <param name="time">The
649         /// <see cref="T:System.DateTime"/> that specifies a
650         /// date.
651         /// </param>
652         /// <returns>An integer giving the day of months, starting with 1.
653         /// </returns>
654         /// <exception cref="T:System.ArgumentOutOfRangeException">
655         /// The exception is thrown if the
656         /// <see cref="T:System.DateTime"/> parameter is not in the
657         /// supported range of the Hijri calendar.
658         /// </exception>
659         public override DayOfWeek GetDayOfWeek(DateTime time) {
660                 int rd = M_FromDateTime(time);
661                 M_CheckFixedHijri("time", rd);
662                 return (DayOfWeek)CCFixed.day_of_week(rd);
663         }
664
665         /// <summary>
666         /// Overridden. Gives the number of the day in the year.
667         /// </summary>
668         /// <param name="time">The
669         /// <see cref="T:System.DateTime"/> that specifies a
670         /// date.
671         /// </param>
672         /// <returns>An integer representing the day of the year,
673         /// starting with 1.</returns>
674         /// <exception cref="T:System.ArgumentOutOfRangeException">
675         /// The exception is thrown if the
676         /// <see cref="T:System.DateTime"/> parameter is not in the
677         /// supported range of the Hijri calendar.
678         /// </exception>
679         public override int GetDayOfYear(DateTime time) {
680                 int rd = M_FromDateTime(time);
681                 M_CheckFixedHijri("time", rd);
682                 int year = CCHijriCalendar.year_from_fixed(rd);
683                 int rd1_1 = CCHijriCalendar.fixed_from_dmy(1, 1, year);
684                 return rd - rd1_1 + 1;
685         }
686
687         /// <summary>
688         /// Overridden. Gives the number of days in the specified month
689         /// of the given year and era.
690         /// </summary>
691         /// <param name="year">An integer that gives the year.
692         /// </param>
693         /// <param name="month">An integer that gives the month, starting
694         /// with 1.</param>
695         /// <param name="era">An intger that gives the era of the specified
696         /// year.</param>
697         /// <returns>An integer that gives the number of days of the
698         /// specified month.</returns>
699         /// <exception cref="T:System.ArgumentOutOfRangeException">
700         /// The exception is thrown, if <paramref name="month"/>,
701         /// <paramref name="year"/> ,or <paramref name="era"/> is outside
702         /// the allowed range.
703         /// </exception>
704         public override int GetDaysInMonth(int year, int month, int era) {
705                 M_CheckYME(year, month, ref era);
706                 int rd1 = CCHijriCalendar.fixed_from_dmy(1, month, year);
707                 int rd2 = CCHijriCalendar.fixed_from_dmy(1, month+1, year);
708                 return rd2 - rd1;
709         }
710
711         /// <summary>
712         /// Overridden. Gives the number of days of the specified
713         /// year of the given era. 
714         /// </summary>
715         /// <param name="year">An integer that specifies the year. 
716         /// </param>
717         /// <param name="era">An ineger that specifies the era.
718         /// </param>
719         /// <returns>An integer that gives the number of days of the
720         /// specified year.</returns>
721         /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
722         /// The exception is thrown, if
723         /// <paramref name="year"/> is outside the allowed range.
724         /// </exception>
725         public override int GetDaysInYear(int year, int era) {
726                 M_CheckYE(year, ref era);
727                 int rd1 = CCHijriCalendar.fixed_from_dmy(1, 1, year);
728                 int rd2 = CCHijriCalendar.fixed_from_dmy(1, 1, year+1);
729                 return rd2 - rd1;
730         }
731                 
732
733         /// <summary>
734         /// Overridden. Gives the era of the specified date.
735         /// </summary>
736         /// <param name="time">The
737         /// <see cref="T:System.DateTime"/> that specifies a
738         /// date.
739         /// </param>
740         /// <returns>An integer representing the era of the calendar.
741         /// </returns>
742         /// <exception cref="T:System.ArgumentOutOfRangeException">
743         /// The exception is thrown if the
744         /// <see cref="T:System.DateTime"/> parameter is not in the
745         /// supported range of the Hijri calendar.
746         /// </exception>
747         public override int GetEra(DateTime time) {
748                 M_CheckDateTime(time);
749                 return UmAlQuraEra;
750         }
751
752         public override int GetLeapMonth (int year, int era)
753         {
754                 return 0;
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 millisecond,
918                 int era)
919         {
920                 M_CheckYMDE(year, month, day, ref era);
921                 M_CheckHMSM(hour, minute, second, millisecond);
922                 int rd = CCHijriCalendar.fixed_from_dmy(day, month, year);
923                 return M_ToDateTime(rd,
924                         hour, minute, second, millisecond);
925         }
926
927         public override int ToFourDigitYear(int year)
928         {
929                 return base.ToFourDigitYear (year);
930         }
931
932 #if !NET_2_1
933         public override CalendarAlgorithmType AlgorithmType  {
934                 get {
935                         return CalendarAlgorithmType.LunarCalendar;
936                 }
937         }
938 #endif
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         
955 } // class HijriCalendar
956         
957 } // namespace System.Globalization