2006-03-20 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / corlib / System.Globalization / HebrewCalendar.cs
1 // HebrewCalendar.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 /// <summary>
35 /// This is the Hebrew calendar.
36 /// </summary>
37 /// <remarks>
38 /// <para>The Hebrew calendar supports only years between 5343 A.M. and
39 /// 6000 A.M. This has been done to be compatible with .NET.
40 /// </para>
41 /// <para>The implementation uses the
42 /// <see cref="N:CalendricalCalculations"/> namespace.
43 /// </para>
44 /// </remarks>
45 [Serializable]
46 [MonoTODO ("Fix serialization compatibility with MS.NET")]
47 public class HebrewCalendar : Calendar {
48         /// <summary>
49         /// Constructor.
50         /// </summary>
51         public HebrewCalendar() {
52                 M_AbbrEraNames = new string[] {"A.M."};
53                 M_EraNames = new string[] {"Anno Mundi"};
54                 if (M_TwoDigitYearMax == 99)
55                         M_TwoDigitYearMax = 5790;
56         }
57
58         /// <summary>
59         /// The era number for the Anno Mundi (A.M.) era, called
60         /// plain HebrewEra.
61         /// </summary>
62         public static readonly int HebrewEra = 1;
63
64         /// <summary>
65         /// The
66         /// <see cref="T:System.DateTime"/> ticks for first day of year
67         /// 5343 A.M.
68         /// </summary>
69         internal const long M_MinTicks = 499147488000000000L;
70         /// <summary>
71         /// The number of
72         /// <see cref="T:System.DateTime"/> ticks for the last day of year
73         /// 6000 A.M.
74         /// </summary>
75         internal const long M_MaxTicks = 706783967999999999L;
76         /// <summary>
77         /// The minimum year in the A.M. era supported.
78         /// </summary>
79         internal const int M_MinYear = 5343;
80         /// <summary>
81         /// The maximum year supported in the A.M. era.
82         /// </summary>
83         internal override int M_MaxYear {
84                 get { return 6000; }
85         }
86
87         /// <value>Overridden. Gives the eras supported by the Gregorian
88         /// calendar as an array of integers.
89         /// </value>
90         public override int[] Eras {
91                 get {
92                         return new int[] { HebrewEra }; 
93                 }
94         }
95
96         int twoDigitYearMax = 5790;
97         
98         public override int TwoDigitYearMax 
99         {
100                 get {
101                         return twoDigitYearMax;
102                 }
103                 set {
104                         CheckReadOnly ();
105                         M_ArgumentInRange ("value", value, M_MinYear, M_MaxYear);
106
107                         twoDigitYearMax = value;
108                 }
109         }
110
111         /// <summary>
112         /// A protected member checking a
113         /// <see cref="T:System.DateTime"/> value.
114         /// </summary>
115         /// <param name="time">The
116         /// <see cref="T:System.DateTime"/>
117         /// to check.
118         /// </param>
119         /// <exception cref="T:System.ArgumentOutOfRangeException">
120         /// The exception is thrown if the
121         /// <see cref="T:System.DateTime"/> parameter is not in the years
122         /// between 5343 A.M. and 6000 A.M., inclusive.
123         /// </exception>
124         internal void M_CheckDateTime(DateTime time) {
125                 if (time.Ticks < M_MinTicks || time.Ticks > M_MaxTicks)
126                         throw new ArgumentOutOfRangeException(
127                                 "time",
128                                 "Only hebrew years between 5343 and 6000," +
129                                 " inclusive, are supported.");
130         }
131
132         /// <summary>
133         /// A protected method checking the era number.
134         /// </summary>
135         /// <param name="era">The era number.</param>
136         /// <exception name="T:System.ArgumentException">
137         /// The exception is thrown if the era is not equal
138         /// <see cref="F:HebrewEra"/>.
139         /// </exception>
140         internal void M_CheckEra(ref int era) {
141                 if (era == CurrentEra)
142                         era = HebrewEra;
143                 if (era != HebrewEra)
144                         throw new ArgumentException("Era value was not valid.");
145         }
146
147         /// <summary>
148         /// A protected method checking calendar year and the era number.
149         /// </summary>
150         /// <param name="year">An integer representing the calendar year.
151         /// </param>
152         /// <param name="era">The era number.</param>
153         /// <exception cref="T:System.ArgumentException">
154         /// The exception is thrown if the era is not equal
155         /// <see cref="F:HebrewEra"/>.
156         /// </exception>
157         /// <exception cref="T:System.ArgumentOutOfRangeException">
158         /// The exception is thrown if the calendar year is outside of
159         /// the allowed range.
160         /// </exception>
161         internal override void M_CheckYE(int year, ref int era) {
162                 M_CheckEra(ref era);
163                 if (year < M_MinYear || year > M_MaxYear)
164                         throw new ArgumentOutOfRangeException(
165                                 "year",
166                                 "Only hebrew years between 5343 and 6000," +
167                                 " inclusive, are supported.");
168         }
169
170         /// <summary>
171         /// A protected method checking the calendar year, month, and
172         /// era number.
173         /// </summary>
174         /// <param name="year">An integer representing the calendar year.
175         /// </param>
176         /// <param name="month">An integer giving the calendar month.
177         /// </param>
178         /// <param name="era">The era number.</param>
179         /// <exception cref="T:System.ArgumentException">
180         /// The exception is thrown if the era is not equal
181         /// <see cref="F:HebrewEra"/>.
182         /// </exception>
183         /// <exception cref="T:System.ArgumentOutOfRangeException">
184         /// The exception is thrown if the calendar year or month is
185         /// outside of the allowed range.
186         /// </exception>
187         internal void M_CheckYME(int year, int month, ref int era) {
188                 M_CheckYE(year, ref era);
189                 int l = CCHebrewCalendar.last_month_of_year(year);
190                 if (month < 1 || month > l) {
191                         StringWriter sw = new StringWriter();
192                         sw.Write("Month must be between 1 and {0}.", l);
193                         throw new ArgumentOutOfRangeException("month",
194                                 sw.ToString());
195                 }
196         }
197
198         /// <summary>
199         /// A protected method checking the calendar day, month, and year
200         /// and the era number.
201         /// </summary>
202         /// <param name="year">An integer representing the calendar year.
203         /// </param>
204         /// <param name="month">An integer giving the calendar month.
205         /// </param>
206         /// <param name="day">An integer giving the calendar day.
207         /// </param>
208         /// <param name="era">The era number.</param>
209         /// <exception cref="T:System.ArgumentException">
210         /// The exception is thrown if the era is not equal
211         /// <see cref="F:HebrewEra"/>.
212         /// </exception>
213         /// <exception cref="T:System.ArgumentOutOfRangeException">
214         /// The exception is thrown if the calendar year, month, or day is
215         /// outside of the allowed range.
216         /// </exception>
217         internal void M_CheckYMDE(int year, int month, int day,
218                 ref int era)
219         {
220                 M_CheckYME(year, month, ref era);
221                 M_ArgumentInRange("day", day, 1, GetDaysInMonth(year, month,
222                         era));
223         }
224
225         
226         /// <summary>
227         /// Overrideden. Adds months to a given date.
228         /// </summary>
229         /// <param name="time">The
230         /// <see cref="T:System.DateTime"/> to which to add
231         /// months.
232         /// </param>
233         /// <param name="months">The number of months to add.</param>
234         /// <returns>A new <see cref="T:System.DateTime"/> value, that
235         /// results from adding <paramref name="months"/> to the specified
236         /// DateTime.</returns>
237         /// <exception cref="T:System.ArgumentOutOfRangeException">
238         /// The exception is thrown if the
239         /// <see cref="T:System.DateTime"/> return value is not in the years
240         /// between 5343 A.M. and 6000 A.M., inclusive.
241         /// </exception>
242         public override DateTime AddMonths(DateTime time, int months) {
243                 int y, m, d;
244                 DateTime t;
245
246                 if (months == 0) {
247                         t = time;
248                 } else {
249                         int rd = CCFixed.FromDateTime(time);
250                         CCHebrewCalendar.dmy_from_fixed(
251                                 out d, out m, out y, rd);
252                         m = M_Month(m, y);
253                         if (months < 0) {
254                                 while (months < 0) {
255                                         if (m+months > 0) {
256                                                 m += months;
257                                                 months = 0;
258                                         } else {
259                                                 months += m;
260                                                 y -= 1;
261                                                 m = GetMonthsInYear(y);
262                                         }
263                                 }
264                         }
265                         else {
266                                 while (months > 0) {
267                                         int my = GetMonthsInYear(y);
268                                         if (m+months <= my) {
269                                                 m += months;
270                                                 months = 0;
271                                         } else {
272                                                 months -= my-m+1;
273                                                 m = 1;
274                                                 y += 1;
275                                         }
276                                 }
277                         }
278                         t = ToDateTime(y, m, d, 0, 0, 0, 0);
279                         t = t.Add(time.TimeOfDay);
280                 }
281                 M_CheckDateTime(t);
282                 return t;
283         }
284
285         /// <summary>
286         /// Overridden. Adds years to a given date.
287         /// </summary>
288         /// <param name="time">The
289         /// <see cref="T:System.DateTime"/> to which to add
290         /// years.
291         /// </param>
292         /// <param name="years">The number of years to add.</param>
293         /// <returns>A new <see cref="T:System.DateTime"/> value, that
294         /// results from adding <paramref name="years"/> to the specified
295         /// DateTime.</returns>
296         /// <exception cref="T:System.ArgumentOutOfRangeException">
297         /// The exception is thrown if the
298         /// <see cref="T:System.DateTime"/> return value is not in the years
299         /// between 5343 A.M. and 6000 A.M., inclusive.
300         /// </exception>
301         public override DateTime AddYears(DateTime time, int years) {
302                 int rd = CCFixed.FromDateTime(time);
303                 int day, month, year;
304                 CCHebrewCalendar.dmy_from_fixed(
305                         out day, out month, out year, rd);
306                 year += years;
307                 rd = CCHebrewCalendar.fixed_from_dmy(day, month, year);
308                 DateTime t = CCFixed.ToDateTime(rd);
309                 t = t.Add(time.TimeOfDay);
310                 M_CheckDateTime(t);
311                 return t;
312         }
313                 
314         /// <summary>
315         /// Overriden. Gets the day of the month from
316         /// <paramref name="time"/>.
317         /// </summary>
318         /// <param name="time">The
319         /// <see cref="T:System.DateTime"/> that specifies a
320         /// date.
321         /// </param>
322         /// <returns>An integer giving the day of months, starting with 1.
323         /// </returns>
324         /// <exception cref="T:System.ArgumentOutOfRangeException">
325         /// The exception is thrown if the
326         /// <see cref="T:System.DateTime"/> parameter is not in the years
327         /// between 5343 A.M. and 6000 A.M., inclusive.
328         /// </exception>
329         public override int GetDayOfMonth(DateTime time) {
330                 M_CheckDateTime(time);
331                 int rd = CCFixed.FromDateTime(time);
332                 return CCHebrewCalendar.day_from_fixed(rd);
333         }
334
335         /// <summary>
336         /// Overriden. Gets the day of the week from the specified date.
337         /// </summary>
338         /// <param name="time">The
339         /// <see cref="T:System.DateTime"/> that specifies a
340         /// date.
341         /// </param>
342         /// <returns>An integer giving the day of months, starting with 1.
343         /// </returns>
344         /// <exception cref="T:System.ArgumentOutOfRangeException">
345         /// The exception is thrown if the
346         /// <see cref="T:System.DateTime"/> parameter is not in the years
347         /// between 5343 A.M. and 6000 A.M., inclusive.
348         /// </exception>
349         public override DayOfWeek GetDayOfWeek(DateTime time) {
350                 M_CheckDateTime(time);
351                 int rd = CCFixed.FromDateTime(time);
352                 return (DayOfWeek)CCFixed.day_of_week(rd);
353         }
354
355         /// <summary>
356         /// Overridden. Gives the number of the day in the year.
357         /// </summary>
358         /// <param name="time">The
359         /// <see cref="T:System.DateTime"/> that specifies a
360         /// date.
361         /// </param>
362         /// <returns>An integer representing the day of the year,
363         /// starting with 1.</returns>
364         /// <exception cref="T:System.ArgumentOutOfRangeException">
365         /// The exception is thrown if the
366         /// <see cref="T:System.DateTime"/> parameter is not in the years
367         /// between 5343 A.M. and 6000 A.M., inclusive.
368         /// </exception>
369         public override int GetDayOfYear(DateTime time) {
370                 M_CheckDateTime(time);
371                 int rd = CCFixed.FromDateTime(time);
372                 int year = CCHebrewCalendar.year_from_fixed(rd);
373                 int rd1_7 = CCHebrewCalendar.fixed_from_dmy(1, 7, year);
374                 return rd - rd1_7 + 1;
375         }
376
377         /// <summary>
378         /// The method maps a .NET Hebrew month to a Calencdrical
379         /// Calculations Hebrew month. 
380         /// </summary>
381         /// <param name="month">An integer representing a month in .NET
382         /// counting (starting with Tishri).
383         /// </param>
384         /// <param name="year">An integer representing the Hebrew year.
385         /// </param>
386         /// <returns>The Hebrew month in Calendrical Calculations counting,
387         /// staring with the Hebrew month Nisan.
388         /// </returns>
389         /// <remarks>
390         /// <para>
391         /// In .NET the month counting starts with the Hebrew month Tishri.
392         /// Calendrical Calculations starts with the month Tisan. So we must
393         /// map here.
394         /// </para>
395         /// </remarks>
396         internal int M_CCMonth(int month, int year) {
397                 if (month <= 6) {
398                         return 6+month;
399                 }
400                 else {
401                         int l = CCHebrewCalendar.last_month_of_year(year);
402                         if (l == 12) {
403                                 return month-6;
404                         }
405                         else {
406                                 return month <= 7 ? 6+month : month-7;  
407                         }
408                 }
409         }
410
411         /// <summary>
412         /// The method maps a Calendrical Calculations Hebrew month
413         /// to a .NET Hebrew month. 
414         /// </summary>
415         /// <param name="ccmonth">An integer representing a month in
416         /// Calendrical Calculations counting, starting with Nisan.
417         /// </param>
418         /// <param name="year">An integer representing the Hebrew year.
419         /// </param>
420         /// <returns>The Hebrew month in .NET counting,
421         /// staring with the Hebrew month Tishri.
422         /// </returns>
423         /// <remarks>
424         /// <para>
425         /// In .NET the month counting starts with the Hebrew month Tishri.
426         /// Calendrical Calculations starts with the month Tisan. So we must
427         /// map here.
428         /// </para>
429         /// </remarks>
430         internal int M_Month(int ccmonth, int year) {
431                 if (ccmonth >= 7) {
432                         return ccmonth - 6;
433                 } else {
434                         int l = CCHebrewCalendar.last_month_of_year(year);
435                         return ccmonth + (l == 12 ? 6 : 7);
436                 }
437         }
438
439         /// <summary>
440         /// Overridden. Gives the number of days in the specified month
441         /// of the given year and era.
442         /// </summary>
443         /// <param name="year">An integer that gives the year.
444         /// </param>
445         /// <param name="month">An integer that gives the month, starting
446         /// with 1.</param>
447         /// <param name="era">An integer that gives the era of the specified
448         /// year.</param>
449         /// <returns>An integer that gives the number of days of the
450         /// specified month.</returns>
451         /// <exception cref="T:System.ArgumentOutOfRangeException">
452         /// The exception is thrown, if <paramref name="month"/>,
453         /// <paramref name="year"/> ,or <paramref name="era"/> is outside
454         /// the allowed range.
455         /// </exception>
456         public override int GetDaysInMonth(int year, int month, int era) {
457                 M_CheckYME(year, month, ref era);
458                 int ccmonth = M_CCMonth(month, year); 
459                 int rd1 = CCHebrewCalendar.fixed_from_dmy(1, ccmonth, year);
460                 int rd2 = CCHebrewCalendar.fixed_from_dmy(1, ccmonth+1, year);
461                 return rd2 - rd1;
462         }
463
464         /// <summary>
465         /// Overridden. Gives the number of days of the specified
466         /// year of the given era. 
467         /// </summary>
468         /// <param name="year">An integer that specifies the year. 
469         /// </param>
470         /// <param name="era">An ineger that specifies the era.
471         /// </param>
472         /// <returns>An integer that gives the number of days of the
473         /// specified year.</returns>
474         /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
475         /// The exception is thrown, if
476         /// <paramref name="year"/> or <paramref name="era"/> are outside the
477         /// allowed range.
478         /// </exception>
479         public override int GetDaysInYear(int year, int era) {
480                 M_CheckYE(year, ref era);
481                 int rd1 = CCHebrewCalendar.fixed_from_dmy(1, 7, year);
482                 int rd2 = CCHebrewCalendar.fixed_from_dmy(1, 7, year+1);
483                 return rd2 - rd1;
484         }
485                 
486
487         /// <summary>
488         /// Overridden. Gives the era of the specified date.
489         /// </summary>
490         /// <param name="time">The
491         /// <see cref="T:System.DateTime"/> that specifies a
492         /// date.
493         /// </param>
494         /// <returns>An integer representing the era of the calendar.
495         /// </returns>
496         /// <exception cref="T:System.ArgumentOutOfRangeException">
497         /// The exception is thrown if the
498         /// <see cref="T:System.DateTime"/> parameter is not in the years
499         /// between 5343 A.M. and 6000 A.M., inclusive.
500         /// </exception>
501         public override int GetEra(DateTime time) {
502                 M_CheckDateTime(time);
503                 return HebrewEra;
504         }
505
506         /// <summary>
507         /// Overridden. Gives the number of the month of the specified
508         /// date.
509         /// </summary>
510         /// <param name="time">The
511         /// <see cref="T:System.DateTime"/> that specifies a
512         /// date.
513         /// </param>
514         /// <returns>An integer representing the month, 
515         /// starting with 1.</returns>
516         /// <exception cref="T:System.ArgumentOutOfRangeException">
517         /// The exception is thrown if the
518         /// <see cref="T:System.DateTime"/> parameter is not in the years
519         /// between 5343 A.M. and 6000 A.M., inclusive.
520         /// </exception>
521         public override int GetMonth(DateTime time) {
522                 M_CheckDateTime(time);
523                 int rd = CCFixed.FromDateTime(time);
524                 int ccmonth, year;
525                 CCHebrewCalendar.my_from_fixed(out ccmonth, out year, rd);
526                 return M_Month(ccmonth, year);
527         }
528
529         /// <summary>
530         /// Overridden. Gives the number of months in the specified year 
531         /// and era.
532         /// </summary>
533         /// <param name="year">An integer that specifies the year.
534         /// </param>
535         /// <param name="era">An integer that specifies the era.
536         /// </param>
537         /// <returns>An integer that gives the number of the months in the
538         /// specified year.</returns>
539         /// <exception cref="T:System.ArgumentOutOfRangeException">
540         /// The exception is thrown, if the year or the era are not valid.
541         /// </exception>
542         public override int GetMonthsInYear(int year, int era) {
543                 M_CheckYE(year, ref era);
544                 return CCHebrewCalendar.last_month_of_year(year);
545         }
546
547         /// <summary>
548         /// Overridden. Gives the number of the year of the specified
549         /// date.
550         /// </summary>
551         /// <param name="time">The
552         /// <see cref="T:System.DateTime"/> that specifies a
553         /// date.
554         /// </param>
555         /// <returns>An integer representing the year, 
556         /// starting with 1.</returns>
557         /// <exception cref="T:System.ArgumentOutOfRangeException">
558         /// The exception is thrown if the
559         /// <see cref="T:System.DateTime"/> parameter is not in the years
560         /// between 5343 A.M. and 6000 A.M., inclusive.
561         /// </exception>
562         public override int GetYear(DateTime time) {
563                 M_CheckDateTime(time);
564                 int rd = CCFixed.FromDateTime(time);
565                 return CCHebrewCalendar.year_from_fixed(rd);
566         }
567
568         /// <summary>
569         /// Overridden. Tells whether the given day 
570         /// is a leap day.
571         /// </summary>
572         /// <param name="year">An integer that specifies the year in the
573         /// given era.
574         /// </param>
575         /// <param name="month">An integer that specifies the month.
576         /// </param>
577         /// <param name="day">An integer that specifies the day.
578         /// </param>
579         /// <param name="era">An integer that specifies the era.
580         /// </param>
581         /// <returns>A boolean that tells whether the given day is a leap
582         /// day.
583         /// </returns>
584         /// <exception cref="T:System.ArgumentOutOfRangeException">
585         /// The exception is thrown, if the year, month, day, or era is not
586         /// valid.
587         /// </exception>
588         /// <remarks>All days in Adar II are viewed as leap days and the
589         /// last day of Adar I.
590         /// </remarks>
591         public override bool IsLeapDay(int year, int month, int day, int era)
592         {
593                 M_CheckYMDE(year, month, day, ref era);
594                 return IsLeapYear(year) &&
595                         (month == 7 || (month == 6 && day == 30)); 
596         }
597
598         /// <summary>
599         /// Overridden. Tells whether the given month 
600         /// is a leap month.
601         /// </summary>
602         /// <param name="year">An integer that specifies the year in the
603         /// given era.
604         /// </param>
605         /// <param name="month">An integer that specifies the month.
606         /// </param>
607         /// <param name="era">An integer that specifies the era.
608         /// </param>
609         /// <returns>A boolean that tells whether the given month is a leap
610         /// month.
611         /// </returns>
612         /// <exception cref="T:System.ArgumentOutOfRangeException">
613         /// The exception is thrown, if the year, month, or era is not
614         /// valid.
615         /// </exception>
616         /// <remarks>
617         /// Adar II is viewed as leap month.
618         /// </remarks>
619         public override bool IsLeapMonth(int year, int month, int era) {
620                 M_CheckYME(year, month, ref era);
621                 return IsLeapYear(year) && month == 7; 
622         }
623
624         /// <summary>
625         /// Overridden. Tells whether the given year
626         /// is a leap year.
627         /// </summary>
628         /// <param name="year">An integer that specifies the year in the
629         /// given era.
630         /// </param>
631         /// <param name="era">An integer that specifies the era.
632         /// </param>
633         /// <returns>A boolean that tells whether the given year is a leap
634         /// year.
635         /// </returns>
636         /// <exception cref="T:System.ArgumentOutOfRangeException">
637         /// The exception is thrown, if the year or era is not
638         /// valid.
639         /// </exception>
640         public override bool IsLeapYear(int year, int era) {
641                 M_CheckYE(year, ref era);
642                 return CCHebrewCalendar.is_leap_year(year);
643         }
644
645         /// <summary>
646         /// Overridden. Creates the
647         /// <see cref="T:System.DateTime"/> from the parameters.
648         /// </summary>
649         /// <param name="year">An integer that gives the year in the
650         /// <paramref name="era"/>.
651         /// </param>
652         /// <param name="month">An integer that specifies the month.
653         /// </param>
654         /// <param name="day">An integer that specifies the day.
655         /// </param>
656         /// <param name="hour">An integer that specifies the hour.
657         /// </param>
658         /// <param name="minute">An integer that specifies the minute.
659         /// </param>
660         /// <param name="second">An integer that gives the second.
661         /// </param>
662         /// <param name="milliseconds">An integer that gives the
663         /// milliseconds.
664         /// </param>
665         /// <param name="era">An integer that specifies the era.
666         /// </param>
667         /// <returns>A
668         /// <see cref="T:system.DateTime"/> representig the date and time.
669         /// </returns>
670         /// <exception cref="T:System.ArgumentOutOfRangeException">
671         /// The exception is thrown, if at least one of the parameters
672         /// is out of range.
673         /// </exception>
674         public override DateTime ToDateTime(int year, int month, int day,
675                 int hour, int minute, int second, int milliseconds,
676                 int era)
677         {
678                 M_CheckYMDE(year, month, day, ref era);
679                 M_CheckHMSM(hour, minute, second, milliseconds);
680                 int ccm = M_CCMonth(month, year);
681                 int rd = CCHebrewCalendar.fixed_from_dmy(day, ccm, year);
682                 return CCFixed.ToDateTime(rd,
683                         hour, minute, second, milliseconds);
684         }
685
686         public override int ToFourDigitYear (int year)
687         {
688                 M_ArgumentInRange ("year", year, 0, 99);
689                 
690                 int baseExtra = this.twoDigitYearMax % 100;
691                 int baseCentury = this.twoDigitYearMax - baseExtra;
692                 
693                 if (year <= baseExtra)
694                         return baseCentury + year;
695                 else
696                         return baseCentury + year - 100;
697         }
698 #if NET_2_0
699         public override CalendarAlgorithmType AlgorithmType {
700                 get {
701                         return CalendarAlgorithmType.LunisolarCalendar;
702                 }
703         }
704
705         static DateTime Min = new DateTime (1583, 1, 1, 0, 0, 0);
706         static DateTime Max = new DateTime (2239, 9, 29, 11, 59, 59);
707                 
708         public override DateTime MinSupportedDateTime {
709                 get {
710                         return Min;
711                 }
712         }
713
714         public override DateTime MaxSupportedDateTime {
715                 get {
716                         return Max;
717                 }
718         }
719 #endif
720
721 } // class HebrewCalendar
722         
723 } // namespace System.Globalization