GenericParameter.cs: override Module properly
[mcs.git] / class / corlib / System.Globalization / CalendricalCalculations.cs
blobecec3da1c1fb4bd8de8a9ad9d081c5ac7983e233
1 // CalendricalCalculations.cs
2 //
3 // (C) Ulrich Kunitz 2002
4 //
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.
29 namespace System.Globalization {
31 using System.Collections;
33 /// <summary>A class that provides mathematical functions.</summary>
34 /// <remarks>
35 /// <para>
36 /// We are breaking the .Net
37 /// naming conventions to be compatible to the "Calendrical Calculations"
38 /// bool.
39 /// </para>
40 /// </remarks>
41 internal class CCMath {
42 /// <summary>
43 /// A static method which rounds a double value.
44 /// </summary>
45 /// <param name="x">The double value to round.</param>
46 /// <returns>The rounded double.</returns>
47 public static double round(double x) {
48 return System.Math.Floor(x+0.5);
51 /// <summary>
52 /// A static method that computes the remainder of the division
53 /// of two doubles.
54 /// </summary>
55 /// <param name="x">The double value which is divided.</param>
56 /// <param name="y">The divisor.</param>
57 /// <returns>The remainder as double value.</returns>
58 public static double mod(double x, double y) {
59 return x - y * System.Math.Floor(x/y);
62 /// <summary>
63 /// The static method divides two integers.
64 /// </summary>
65 /// <param name="x">The integer x value.</param>
66 /// <param name="y">The integer y value.</param>
67 /// <returns>The qotient of x and y defined by floor(x/y).
68 /// </returns>
69 /// <remarks>
70 /// Please notify that the function is not compatible to the standard
71 /// integer divide operation /.
72 /// </remarks>
73 public static int div(int x, int y) {
74 return (int)System.Math.Floor((double)x/(double)y);
77 /// <summary>
78 /// The static method computes the remainder of two integers.
79 /// </summary>
80 /// <param name="x">The integer value which will be divided.</param>
81 /// <param name="y">The divisor integer value.</param>
82 /// <returns> The remainder as integer value.</returns>
83 /// <remarks>
84 /// Please notify that the method is not compatible to the C#
85 /// remainder operation %.
86 /// </remarks>
87 public static int mod(int x, int y) {
88 return x - y * div(x, y);
91 /// <summary>
92 /// A static method that combines integer division and remainder
93 /// computation.
94 /// </summary>
95 /// <param name="remainder">Remainder integer output value.
96 /// </param>
97 /// <param name="x">Integer to be divided.</param>
98 /// <param name="y">Divisor integer value.</param>
99 /// <returns>The quotient as integer.</returns>
100 /// <seealso cref="M:div"/>
101 /// <seealso cref="M:mod"/>
102 public static int div_mod(out int remainder, int x, int y) {
103 int d = div(x, y);
104 remainder = x - y * d;
105 return d;
108 /// <summary>
109 /// A static method returning the sign of the argument.
110 /// </summary>
111 /// <param name="x">The double argument.</param>
112 /// <returns>An integer value: -1 for a negative argument;
113 /// 0 for a zero argument, and 1 for a positive argument.
114 /// </returns>
115 public static int signum(double x) {
116 if (x < 0.0)
117 return -1;
118 if (x == 0.0)
119 return 0;
120 return 1;
123 /// <summary>
124 /// A static method returning the sign of the integer
125 /// argument.
126 /// </summary>
127 /// <param name="x">The integer argument.</param>
128 /// <returns>An integer value: -1 for a negative argument;
129 /// 0 for a zero argument, and 1 for a positive argument.
130 /// </returns>
131 public static int signum(int x) {
132 if (x < 0)
133 return -1;
134 if (x == 0)
135 return 0;
136 return 1;
139 /// <summary>
140 /// An adjusted remainder function as defined in "Calendrical
141 /// Calculations".
142 /// </summary>
143 /// <param name="x">The double x argument.</param>
144 /// <param name="y">The double y argument, the divisor.</param>
145 /// <returns>A double value representing remainder; but instead 0.0
146 /// the divisor y is returned.
147 /// </returns>
148 public static double amod(double x, double y) {
149 double d = mod(x, y);
150 return (d == 0.0) ? y : d;
153 /// <summary>
154 /// The adjusted remainder functions for integers as defined in
155 /// "Calendrical Calculations".
156 /// </summary>
157 /// <param name="x">The integer argument to be divided.</param>
158 /// <param name="y">The integer divisor argument.</param>
159 /// <returns>The remainder as an integer; however instead 0
160 /// is the divisor y returned.
161 /// </returns>
162 public static int amod(int x, int y) {
163 int i = mod(x, y);
164 return (i == 0) ? y : i;
168 /// <summary>The class implements methods to handle the fixed date value from
169 /// the "Calendrical Calculations" books.
170 /// </summary>
171 /// <remarks>
172 /// <para>
173 /// For implementing the Calendar classes I used the algorithms from the
174 /// book "Calendrical Calculations" by Nachum Dershowitz and Edward M.
175 /// Rheingold, second reprint 1998. Trying to prevent the introduction of new
176 /// bugs, I implemented their algorithms in the
177 /// <see cref="N:CalendricalCalculations"/>
178 /// namespace and wrapped it in the calendar classes.
179 /// </para>
180 /// <para>
181 /// The fixed day number is also known as R.D. - rata die.
182 /// Midnight at the onset of Monday,
183 /// January 1, year 1 (Gregorian) is R.D. 1.
184 /// </para>
185 /// <para>Here are all my references:</para>
186 /// <list type="table">
187 /// <item><description>
188 /// [1] Nachum Dershowitz and Edward M. Rheingold: "Calendrical Calculations";
189 /// Cambridge University Press; second reprint 1998.
190 /// </description></item>
191 /// <item><description>
192 /// [2] P. Kenneth Seidelmann (ed.): "Explanatory Supplement to the Astronomical
193 /// Almanac"; University Science Books, Sausalito; 1992
194 /// </description></item>
195 /// <item><description>
196 /// [3] F. Richard Stephenson: "Historical Eclipses and Earth Rotation";
197 /// Cambridge University Press; 1997
198 /// </description></item>
199 /// </list>
200 /// </remarks>
201 internal class CCFixed {
202 /// <summary>The method computes the
203 /// <see cref="T:System.DateTime"/>
204 /// from a fixed day number.
205 /// </summary>
206 /// <param name="date">A integer representing the fixed day number.
207 /// </param>
208 /// <returns>The <see cref="T:System.DateTime"/> representing
209 /// the date.
210 /// </returns>
211 public static System.DateTime ToDateTime(int date) {
212 long ticks = (date - 1) * System.TimeSpan.TicksPerDay;
213 return new System.DateTime(ticks);
216 /// <summary>The method computes the
217 /// <see cref="T:System.DateTime"/>
218 /// from a fixed day number and time arguments.
219 /// </summary>
220 /// <param name="date">An integer representing the fixed day number.
221 /// </param>
222 /// <param name="hour">An integer argument specifying the hour.
223 /// </param>
224 /// <param name="minute">An integer argument specifying the minute.
225 /// </param>
226 /// <param name="second">An integer argument giving the second.
227 /// </param>
228 /// <param name="milliseconds">An double argument specifying
229 /// the milliseconds. Notice that
230 /// <see cref="T:System.DateTime"/> has 100 nanosecond resolution.
231 /// </param>
232 /// <returns>The <see cref="T:System.DateTime"/> representing
233 /// the date.
234 /// </returns>
235 public static System.DateTime ToDateTime(int date,
236 int hour, int minute, int second, double milliseconds)
238 System.DateTime time = ToDateTime(date);
239 time = time.AddHours(hour);
240 time = time.AddMinutes(minute);
241 time = time.AddSeconds(second);
242 return time.AddMilliseconds(milliseconds);
245 /// <summary>
246 /// A static method computing the fixed day number from a
247 /// <see cref="T:System.DateTime"/> value.
248 /// </summary>
249 /// <param name="time">A
250 /// <see cref="T:System.DateTime"/> value representing the date.
251 /// </param>
252 /// <returns>The fixed day number as integer representing the date.
253 /// </returns>
254 public static int FromDateTime(System.DateTime time) {
255 return 1 + (int)(time.Ticks / System.TimeSpan.TicksPerDay);
258 /// <summary>
259 /// The static method computes the <see cref="T:DayOfWeek"/>.
260 /// </summary>
261 /// <param name="date">An integer representing the fixed day number.
262 /// </param>
263 /// <returns>The day of week.</returns>
264 public static DayOfWeek day_of_week(int date) {
265 return (DayOfWeek)CCMath.mod(date, 7);
268 /// <summary>
269 /// The static method computes the date of a day of week on or before
270 /// a particular date.
271 /// </summary>
272 /// <param name="date">An integer representing the date as
273 /// fixed day number.
274 /// </param>
275 /// <param name="k">An integer representing the day of the week,
276 /// starting with 0 for sunday.
277 /// </param>
278 /// <returns>The fixed day number of the day of week specified by k
279 /// on or before the given date.
280 /// </returns>
281 public static int kday_on_or_before(int date, int k) {
282 return date - (int)day_of_week(date-k);
285 /// <summary>
286 /// The static method computes the date of a day of week on or after
287 /// a particular date.
288 /// </summary>
289 /// <param name="date">An integer representing the date as
290 /// fixed day number.
291 /// </param>
292 /// <param name="k">An integer representing the day of the week,
293 /// starting with 0 for sunday.
294 /// </param>
295 /// <returns>The fixed day number of the day of week specified by k
296 /// on or after the given date.
297 /// </returns>
298 public static int kday_on_or_after(int date, int k) {
299 return kday_on_or_before(date+6, k);
302 /// <summary>
303 /// The static method computes the date of a day of week that is
304 /// nearest to a particular date.
305 /// </summary>
306 /// <param name="date">An integer representing the date as
307 /// fixed day number.
308 /// </param>
309 /// <param name="k">An integer representing the day of the week,
310 /// starting with 0 for sunday.
311 /// </param>
312 /// <returns>The fixed day number of the day of week neares to the
313 /// given date.
314 /// </returns>
315 public static int kd_nearest(int date, int k) {
316 return kday_on_or_before(date+3, k);
319 /// <summary>
320 /// The static method computes the date of a day of week after
321 /// a particular date.
322 /// </summary>
323 /// <param name="date">An integer representing the date as
324 /// fixed day number.
325 /// </param>
326 /// <param name="k">An integer representing the day of the week,
327 /// starting with 0 for sunday.
328 /// </param>
329 /// <returns>The fixed day number of the day of week specified by k
330 /// after the given date.
331 /// </returns>
332 public static int kday_after(int date, int k) {
333 return kday_on_or_before(date+7, k);
336 /// <summary>
337 /// The static method computes the date of a day of week before
338 /// a particular date.
339 /// </summary>
340 /// <param name="date">An integer representing the date as
341 /// fixed day number.
342 /// </param>
343 /// <param name="k">An integer representing the day of the week,
344 /// starting with 0 for sunday.
345 /// </param>
346 /// <returns>The fixed day number of the day of week specified by k
347 /// before the given date.
348 /// </returns>
349 public static int kday_before(int date, int k) {
350 return kday_on_or_before(date-1, k);
352 } // class CCFixed
354 /// <summary>
355 /// A class encapsulating the functions of the Gregorian calendar as static
356 /// methods.
357 /// </summary>
358 /// <remarks>
359 /// <para>
360 /// This class is not compatible to
361 /// <see cref="T:System.Globalization.GregorianCalendar"/>.
362 /// </para>
363 /// <para>
364 /// The fixed day number is also known as R.D. - rata die.
365 /// Midnight at the onset of Monday,
366 /// January 1, year 1 (Gregorian) is R.D. 1.
367 /// </para>
368 /// <seealso cref="T:CCFixed"/>
369 /// </remarks>
370 internal class CCGregorianCalendar {
371 /// <summary>An integer defining the epoch of the Gregorian calendar
372 /// as fixed day number.</summary>
373 /// <remarks>The epoch is January 3, 1 C.E. (Julian).</remarks>
374 const int epoch = 1;
376 /// <summary>The enumeration defines the months of the Gregorian
377 /// calendar.
378 /// </summary>
379 public enum Month {
380 /// <summary>
381 /// January.
382 /// </summary>
383 january = 1,
384 /// <summary>
385 /// February.
386 /// </summary>
387 february,
388 /// <summary>
389 /// March.
390 /// </summary>
391 march,
392 /// <summary>
393 /// April.
394 /// </summary>
395 april,
396 /// <summary>
397 /// May.
398 /// </summary>
399 may,
400 /// <summary>
401 /// June.
402 /// </summary>
403 june,
404 /// <summary>
405 /// July.
406 /// </summary>
407 july,
408 /// <summary>
409 /// August.
410 /// </summary>
411 august,
412 /// <summary>
413 /// September.
414 /// </summary>
415 september,
416 /// <summary>
417 /// October.
418 /// </summary>
419 october,
420 /// <summary>
421 /// November.
422 /// </summary>
423 november,
424 /// <summary>
425 /// December.
426 /// </summary>
427 december
431 /// <summary>
432 /// The method tells whether the year is a leap year.
433 /// </summary>
434 /// <param name="year">An integer representing the Gregorian year.
435 /// </param>
436 /// <returns>A boolean which is true if <paramref name="year"/> is
437 /// a leap year.
438 /// </returns>
439 public static bool is_leap_year(int year) {
440 if (CCMath.mod(year, 4) != 0)
441 return false;
442 switch (CCMath.mod(year, 400)) {
443 case 100:
444 return false;
445 case 200:
446 return false;
447 case 300:
448 return false;
450 return true;
453 /// <summary>
454 /// The method returns the fixed day number of the given Gregorian
455 /// date.
456 /// </summary>
457 /// <param name="day">An integer representing the day of the month,
458 /// counting from 1.
459 /// </param>
460 /// <param name="month">An integer representing the month in the
461 /// Gregorian year.
462 /// </param>
463 /// <param name="year">An integer representing the Gregorian year.
464 /// Non-positive values are allowed also.
465 /// </param>
466 /// <returns>An integer value representing the fixed day number.
467 /// </returns>
468 public static int fixed_from_dmy(int day, int month, int year) {
469 int k = epoch - 1;
470 k += 365 * (year-1);
471 k += CCMath.div(year-1, 4);
472 k -= CCMath.div(year-1, 100);
473 k += CCMath.div(year-1, 400);
474 k += CCMath.div(367*month-362, 12);
475 if (month > 2) {
476 k += is_leap_year(year) ? -1 : -2;
479 k += day;
481 return k;
484 /// <summary>
485 /// The method computes the Gregorian year from a fixed day number.
486 /// </summary>
487 /// <param name="date">The fixed day number.
488 /// </param>
489 /// <returns>An integer value giving the Gregorian year of the date.
490 /// </returns>
491 public static int year_from_fixed(int date) {
492 int d = date - epoch;
493 int n_400 = CCMath.div_mod(out d, d, 146097);
494 int n_100 = CCMath.div_mod(out d, d, 36524);
495 int n_4 = CCMath.div_mod(out d, d, 1461);
496 int n_1 = CCMath.div(d, 365);
498 int year = 400*n_400 + 100*n_100 + 4*n_4 + n_1;
499 return (n_100 == 4 || n_1 == 4) ? year : year + 1;
502 /// <summary>
503 /// The method computes the Gregorian year and month from a fixed day
504 /// number.
505 /// </summary>
506 /// <param name="month">The output value giving the Gregorian month.
507 /// </param>
508 /// <param name="year">The output value giving the Gregorian year.
509 /// </param>
510 /// <param name="date">An integer value specifying the fixed day
511 /// number.</param>
512 public static void my_from_fixed(out int month, out int year,
513 int date)
515 year = year_from_fixed(date);
517 int prior_days = date - fixed_from_dmy(1, (int)Month.january,
518 year);
520 int correction;
521 if (date < fixed_from_dmy(1, (int)Month.march, year)) {
522 correction = 0;
523 } else if (is_leap_year(year)) {
524 correction = 1;
525 } else {
526 correction = 2;
529 month = CCMath.div(12 * (prior_days + correction) + 373, 367);
533 /// <summary>
534 /// The method computes the Gregorian year, month, and day from a
535 /// fixed day number.
536 /// </summary>
537 /// <param name="day">The output value returning the day of the
538 /// month.
539 /// </param>
540 /// <param name="month">The output value giving the Gregorian month.
541 /// </param>
542 /// <param name="year">The output value giving the Gregorian year.
543 /// </param>
544 /// <param name="date">An integer value specifying the fixed day
545 /// number.</param>
546 public static void dmy_from_fixed(out int day, out int month,
547 out int year,
548 int date)
550 my_from_fixed(out month, out year, date);
551 day = date - fixed_from_dmy(1, month, year) + 1;
554 /// <summary>A method computing the Gregorian month from a fixed
555 /// day number.
556 /// </summary>
557 /// <param name="date">An integer specifying the fixed day number.
558 /// </param>
559 /// <returns>An integer value representing the Gregorian month.
560 /// </returns>
561 public static int month_from_fixed(int date) {
562 int month, year;
564 my_from_fixed(out month, out year, date);
565 return month;
568 /// <summary>
569 /// A method computing the day of the month from a fixed day number.
570 /// </summary>
571 /// <param name="date">An integer specifying the fixed day number.
572 /// </param>
573 /// <returns>An integer value representing the day of the month.
574 /// </returns>
575 public static int day_from_fixed(int date) {
576 int day, month, year;
578 dmy_from_fixed(out day, out month, out year, date);
579 return day;
582 /// <summary>
583 /// The method computes the difference between two Gregorian dates.
584 /// </summary>
585 /// <param name="dayA">The integer parameter gives the day of month
586 /// of the first date.
587 /// </param>
588 /// <param name="monthA">The integer parameter gives the Gregorian
589 /// month of the first date.
590 /// </param>
591 /// <param name="yearA">The integer parameter gives the Gregorian
592 /// year of the first date.
593 /// </param>
594 /// <param name="dayB">The integer parameter gives the day of month
595 /// of the second date.
596 /// </param>
597 /// <param name="monthB">The integer parameter gives the Gregorian
598 /// month of the second date.
599 /// </param>
600 /// <param name="yearB">The integer parameter gives the Gregorian
601 /// year of the second date.
602 /// </param>
603 /// <returns>An integer giving the difference of days from the first
604 /// the second date.
605 /// </returns>
606 public static int date_difference(int dayA, int monthA, int yearA,
607 int dayB, int monthB, int yearB)
609 return fixed_from_dmy(dayB, monthB, yearB) -
610 fixed_from_dmy(dayA, monthA, yearA);
613 /// <summary>
614 /// The method computes the number of the day in the year from
615 /// a Gregorian date.
616 /// </summary>
617 /// <param name="day">An integer representing the day of the month,
618 /// counting from 1.
619 /// </param>
620 /// <param name="month">An integer representing the month in the
621 /// Gregorian year.
622 /// </param>
623 /// <param name="year">An integer representing the Gregorian year.
624 /// Non-positive values are allowed also.
625 /// </param>
626 /// <returns>An integer value giving the number of the day in the
627 /// Gregorian year, counting from 1.
628 /// </returns>
629 public static int day_number(int day, int month, int year) {
630 return date_difference(31, (int)Month.december, year-1,
631 day, month, year);
634 /// <summary>
635 /// The method computes the days remaining in the given Gregorian
636 /// year from a Gregorian date.
637 /// </summary>
638 /// <param name="day">An integer representing the day of the month,
639 /// counting from 1.
640 /// </param>
641 /// <param name="month">An integer representing the month in the
642 /// Gregorian year.
643 /// </param>
644 /// <param name="year">An integer representing the Gregorian year.
645 /// Non-positive values are allowed also.
646 /// </param>
647 /// <returns>An integer value giving the number of days remaining in
648 /// the Gregorian year.
649 /// </returns>
650 public static int days_remaining(int day, int month, int year) {
651 return date_difference(day, month, year,
652 31, (int)Month.december, year);
655 // Helper functions for the Gregorian calendars.
657 /// <summary>
658 /// Adds months to the given date.
659 /// </summary>
660 /// <param name="time">The
661 /// <see cref="T:System.DateTime"/> to which to add
662 /// months.
663 /// </param>
664 /// <param name="months">The number of months to add.</param>
665 /// <returns>A new <see cref="T:System.DateTime"/> value, that
666 /// results from adding <paramref name="months"/> to the specified
667 /// DateTime.</returns>
668 public static System.DateTime AddMonths(System.DateTime time,
669 int months)
671 int rd = CCFixed.FromDateTime(time);
672 int day, month, year;
673 dmy_from_fixed(out day, out month, out year, rd);
674 month += months;
675 year += CCMath.div_mod(out month, month, 12);
676 int maxday = GetDaysInMonth (year, month);
677 if (day > maxday)
678 day = maxday;
679 rd = fixed_from_dmy(day, month, year);
680 System.DateTime t = CCFixed.ToDateTime(rd);
681 return t.Add(time.TimeOfDay);
684 /// <summary>
685 /// Adds years to the given date.
686 /// </summary>
687 /// <param name="time">The
688 /// <see cref="T:System.DateTime"/> to which to add
689 /// months.
690 /// </param>
691 /// <param name="years">The number of years to add.</param>
692 /// <returns>A new <see cref="T:System.DateTime"/> value, that
693 /// results from adding <paramref name="years"/> to the specified
694 /// DateTime.</returns>
695 public static System.DateTime AddYears(System.DateTime time,
696 int years)
698 int rd = CCFixed.FromDateTime(time);
699 int day, month, year;
700 dmy_from_fixed(out day, out month, out year, rd);
701 year += years;
702 int maxday = GetDaysInMonth (year, month);
703 if (day > maxday)
704 day = maxday;
705 rd = fixed_from_dmy(day, month, year);
706 System.DateTime t = CCFixed.ToDateTime(rd);
707 return t.Add(time.TimeOfDay);
710 /// <summary>
711 /// Gets the of the month from <paramref name="time"/>.
712 /// </summary>
713 /// <param name="time">The
714 /// <see cref="T:System.DateTime"/> that specifies a
715 /// date.
716 /// </param>
717 /// <returns>An integer giving the day of months, starting with 1.
718 /// </returns>
719 public static int GetDayOfMonth(System.DateTime time) {
720 return day_from_fixed(CCFixed.FromDateTime(time));
723 /// <summary>
724 /// The method gives the number of the day in the year.
725 /// </summary>
726 /// <param name="time">The
727 /// <see cref="T:System.DateTime"/> that specifies a
728 /// date.
729 /// </param>
730 /// <returns>An integer representing the day of the year,
731 /// starting with 1.</returns>
732 public static int GetDayOfYear(System.DateTime time) {
733 int rd = CCFixed.FromDateTime(time);
734 int year = year_from_fixed(rd);
735 int rd1_1 = fixed_from_dmy(1, 1, year);
736 return rd - rd1_1 + 1;
739 /// <summary>
740 /// A method that gives the number of days of the specified
741 /// month of the <paramref name="year"/>.
742 /// </summary>
743 /// <param name="year">An integer that gives the year in the current
744 /// era.</param>
745 /// <param name="month">An integer that gives the month, starting
746 /// with 1.</param>
747 /// <returns>An integer that gives the number of days of the
748 /// specified month.</returns>
749 public static int GetDaysInMonth(int year, int month) {
750 int rd1 = fixed_from_dmy(1, month, year);
751 int rd2 = fixed_from_dmy(1, month+1, year);
752 return rd2 - rd1;
755 /// <summary>
756 /// The method gives the number of days in the specified year.
757 /// </summary>
758 /// <param name="year">An integer that gives the year.
759 /// </param>
760 /// <returns>An integer that gives the number of days of the
761 /// specified year.</returns>
762 public static int GetDaysInYear(int year) {
763 int rd1 = fixed_from_dmy(1, 1, year);
764 int rd2 = fixed_from_dmy(1, 1, year+1);
765 return rd2 - rd1;
768 /// <summary>
769 /// The method gives the number of the month of the specified
770 /// date.
771 /// </summary>
772 /// <param name="time">The
773 /// <see cref="T:System.DateTime"/> that specifies a
774 /// date.
775 /// </param>
776 /// <returns>An integer representing the month,
777 /// starting with 1.</returns>
778 public static int GetMonth(System.DateTime time) {
779 return month_from_fixed(CCFixed.FromDateTime(time));
782 /// <summary>
783 /// The method gives the number of the year of the specified
784 /// date.
785 /// </summary>
786 /// <param name="time">The
787 /// <see cref="T:System.DateTime"/> that specifies a
788 /// date.
789 /// </param>
790 /// <returns>An integer representing the year.
791 /// </returns>
792 public static int GetYear(System.DateTime time) {
793 return year_from_fixed(CCFixed.FromDateTime(time));
796 /// <summary>
797 /// A virtual method that tells whether the given day
798 /// is a leap day.
799 /// </summary>
800 /// <param name="year">An integer that specifies the year.
801 /// </param>
802 /// <param name="month">An integer that specifies the month.
803 /// </param>
804 /// <param name="day">An integer that specifies the day.
805 /// </param>
806 /// <returns>A boolean that tells whether the given day is a leap
807 /// day.
808 /// </returns>
809 public static bool IsLeapDay(int year, int month, int day) {
810 return is_leap_year(year) && month == 2 && day == 29;
813 /// <summary>
814 /// A method that creates the
815 /// <see cref="T:System.DateTime"/> from the parameters.
816 /// </summary>
817 /// <param name="year">An integer that gives the year
818 /// </param>
819 /// <param name="month">An integer that specifies the month.
820 /// </param>
821 /// <param name="day">An integer that specifies the day.
822 /// </param>
823 /// <param name="hour">An integer that specifies the hour.
824 /// </param>
825 /// <param name="minute">An integer that specifies the minute.
826 /// </param>
827 /// <param name="second">An integer that gives the second.
828 /// </param>
829 /// <param name="milliseconds">An integer that gives the
830 /// milliseconds.
831 /// </param>
832 /// <returns>A
833 /// <see cref="T:system.DateTime"/> representig the date and time.
834 /// </returns>
835 public static System.DateTime ToDateTime(int year, int month, int day,
836 int hour, int minute, int second, int milliseconds)
838 return CCFixed.ToDateTime(fixed_from_dmy(day, month, year),
839 hour, minute, second, milliseconds);
841 } // class CCGregorianCalendar
843 /// <summary>
844 /// A class encapsulating the functions of the Julian calendar as static
845 /// methods.
846 /// </summary>
847 /// <remarks>
848 /// <para>The algorithms don't support a year 0. Years before Common Era
849 /// (B.C.E. or B.C.) are negative and years of Common Era (C.E. or A.D.)
850 /// are positive.
851 /// </para>
852 /// <para>
853 /// This class is not compatible to
854 /// <see cref="T:System.Globalization.JulianCalendar"/>.
855 /// </para>
856 /// <seealso cref="T:CCFixed"/>
857 /// </remarks>
858 internal class CCJulianCalendar {
859 /// <summary>An integer defining the epoch of the Julian calendar
860 /// as fixed day number.</summary>
861 /// <remarks>The epoch is December 30, 0 (Gregorian).</remarks>
862 const int epoch = -1; // 30. 12. 0 Gregorian
864 /// <summary>The enumeration defines the months of the Julian
865 /// calendar.
866 /// </summary>
867 public enum Month {
868 /// <summary>
869 /// January.
870 /// </summary>
871 january = 1,
872 /// <summary>
873 /// February.
874 /// </summary>
875 february,
876 /// <summary>
877 /// March.
878 /// </summary>
879 march,
880 /// <summary>
881 /// April.
882 /// </summary>
883 april,
884 /// <summary>
885 /// May.
886 /// </summary>
887 may,
888 /// <summary>
889 /// June.
890 /// </summary>
891 june,
892 /// <summary>
893 /// July.
894 /// </summary>
895 july,
896 /// <summary>
897 /// August.
898 /// </summary>
899 august,
900 /// <summary>
901 /// September.
902 /// </summary>
903 september,
904 /// <summary>
905 /// October.
906 /// </summary>
907 october,
908 /// <summary>
909 /// November.
910 /// </summary>
911 november,
912 /// <summary>
913 /// December.
914 /// </summary>
915 december
918 /// <summary>
919 /// The method tells whether the year is a leap year.
920 /// </summary>
921 /// <param name="year">An integer representing the Julian year.
922 /// </param>
923 /// <returns>A boolean which is true if <paramref name="year"/> is
924 /// a leap year.
925 /// </returns>
926 public static bool is_leap_year(int year) {
927 return CCMath.mod(year, 4) == (year > 0 ? 0 : 3);
930 /// <summary>
931 /// The method returns the fixed day number of the given Julian
932 /// date.
933 /// </summary>
934 /// <param name="day">An integer representing the day of the month,
935 /// counting from 1.
936 /// </param>
937 /// <param name="month">An integer representing the month in the
938 /// Julian year.
939 /// </param>
940 /// <param name="year">An integer representing the Julian year.
941 /// Positive and Negative values are allowed.
942 /// </param>
943 /// <returns>An integer value representing the fixed day number.
944 /// </returns>
945 public static int fixed_from_dmy(int day, int month, int year) {
946 int y = year < 0 ? year+1 : year;
947 int k = epoch - 1;
948 k += 365 * (y-1);
949 k += CCMath.div(y-1, 4);
950 k += CCMath.div(367*month-362, 12);
951 if (month > 2) {
952 k += is_leap_year(year) ? -1 : -2;
954 k += day;
956 return k;
959 /// <summary>
960 /// The method computes the Julian year from a fixed day number.
961 /// </summary>
962 /// <param name="date">The fixed day number.
963 /// </param>
964 /// <returns>An integer value giving the Julian year of the date.
965 /// </returns>
966 public static int year_from_fixed(int date) {
967 int approx = CCMath.div(4*(date-epoch)+1464, 1461);
968 return approx <= 0 ? approx - 1 : approx;
971 /// <summary>
972 /// The method computes the Julian year and month from a fixed day
973 /// number.
974 /// </summary>
975 /// <param name="month">The output value giving the Julian month.
976 /// </param>
977 /// <param name="year">The output value giving the Julian year.
978 /// </param>
979 /// <param name="date">An integer value specifying the fixed day
980 /// number.</param>
981 public static void my_from_fixed(out int month, out int year, int date)
983 year = year_from_fixed(date);
985 int prior_days = date - fixed_from_dmy(1, (int)Month.january,
986 year);
988 int correction;
989 if (date < fixed_from_dmy(1, (int)Month.march, year)) {
990 correction = 0;
991 } else if (is_leap_year(year)) {
992 correction = 1;
993 } else {
994 correction = 2;
997 month = CCMath.div(12 * (prior_days + correction) + 373, 367);
1001 /// <summary>
1002 /// The method computes the Julian year, month, and day from a
1003 /// fixed day number.
1004 /// </summary>
1005 /// <param name="day">The output value returning the day of the
1006 /// month.
1007 /// </param>
1008 /// <param name="month">The output value giving the Julian month.
1009 /// </param>
1010 /// <param name="year">The output value giving the Julian year.
1011 /// </param>
1012 /// <param name="date">An integer value specifying the fixed day
1013 /// number.</param>
1014 public static void dmy_from_fixed(out int day, out int month,
1015 out int year, int date)
1017 my_from_fixed(out month, out year, date);
1018 day = date - fixed_from_dmy(1, month, year) + 1;
1021 /// <summary>A method computing the Julian month from a fixed
1022 /// day number.
1023 /// </summary>
1024 /// <param name="date">An integer specifying the fixed day number.
1025 /// </param>
1026 /// <returns>An integer value representing the Julian month.
1027 /// </returns>
1028 public static int month_from_fixed(int date) {
1029 int month, year;
1031 my_from_fixed(out month, out year, date);
1032 return month;
1035 /// <summary>
1036 /// A method computing the day of the month from a fixed day number.
1037 /// </summary>
1038 /// <param name="date">An integer specifying the fixed day number.
1039 /// </param>
1040 /// <returns>An integer value representing the day of the month.
1041 /// </returns>
1042 public static int day_from_fixed(int date) {
1043 int day;
1044 int month;
1045 int year;
1047 dmy_from_fixed(out day, out month, out year, date);
1048 return day;
1051 /// <summary>
1052 /// The method computes the difference between two Julian dates.
1053 /// </summary>
1054 /// <param name="dayA">The integer parameter gives the day of month
1055 /// of the first date.
1056 /// </param>
1057 /// <param name="monthA">The integer parameter gives the Julian
1058 /// month of the first date.
1059 /// </param>
1060 /// <param name="yearA">The integer parameter gives the Julian
1061 /// year of the first date.
1062 /// </param>
1063 /// <param name="dayB">The integer parameter gives the day of month
1064 /// of the second date.
1065 /// </param>
1066 /// <param name="monthB">The integer parameter gives the Julian
1067 /// month of the second date.
1068 /// </param>
1069 /// <param name="yearB">The integer parameter gives the Julian
1070 /// year of the second date.
1071 /// </param>
1072 /// <returns>An integer giving the difference of days from the first
1073 /// the second date.
1074 /// </returns>
1075 public static int date_difference(int dayA, int monthA, int yearA,
1076 int dayB, int monthB, int yearB)
1078 return fixed_from_dmy(dayB, monthB, yearB) -
1079 fixed_from_dmy(dayA, monthA, yearA);
1082 /// <summary>
1083 /// The method computes the number of the day in the year from
1084 /// a Julian date.
1085 /// </summary>
1086 /// <param name="day">An integer representing the day of the month,
1087 /// counting from 1.
1088 /// </param>
1089 /// <param name="month">An integer representing the month in the
1090 /// Julian year.
1091 /// </param>
1092 /// <param name="year">An integer representing the Julian year.
1093 /// Negative values are allowed also.
1094 /// </param>
1095 /// <returns>An integer value giving the number of the day in the
1096 /// Julian year, counting from 1.
1097 /// </returns>
1098 public static int day_number(int day, int month, int year) {
1099 return date_difference(31, (int)Month.december, year-1,
1100 day, month, year);
1103 /// <summary>
1104 /// The method computes the days remaining in the given Julian
1105 /// year from a Julian date.
1106 /// </summary>
1107 /// <param name="day">An integer representing the day of the month,
1108 /// counting from 1.
1109 /// </param>
1110 /// <param name="month">An integer representing the month in the
1111 /// Julian year.
1112 /// </param>
1113 /// <param name="year">An integer representing the Julian year.
1114 /// Negative values are allowed also.
1115 /// </param>
1116 /// <returns>An integer value giving the number of days remaining in
1117 /// the Julian year.
1118 /// </returns>
1119 public static int days_remaining(int day, int month, int year) {
1120 return date_difference(day, month, year,
1121 31, (int)Month.december, year);
1123 } // class CCJulianCalendar
1125 /// <summary>
1126 /// A class encapsulating the functions of the Hebrew calendar as static
1127 /// methods.
1128 /// </summary>
1129 /// <remarks>
1130 /// <para>
1131 /// This class is not compatible to
1132 /// <see cref="T:System.Globalization.HebrewCalendar"/>.
1133 /// </para>
1134 /// <seealso cref="T:CCFixed"/>
1135 /// </remarks>
1136 internal class CCHebrewCalendar {
1137 /// <summary>An integer defining the epoch of the Hebrew calendar
1138 /// as fixed day number.</summary>
1139 /// <remarks>The epoch is October 10, 3761 B.C.E. (Julian).</remarks>
1140 const int epoch = -1373427;
1142 /// <summary>The enumeration defines the months of the Gregorian
1143 /// calendar.
1144 /// </summary>
1145 /// <remarks>
1146 /// The enumaration differs from .NET which defines Tishri as month 1.
1147 /// </remarks>
1148 public enum Month {
1149 /// <summary>
1150 /// Nisan.
1151 /// </summary>
1152 nisan = 1,
1153 /// <summary>
1154 /// Iyyar.
1155 /// </summary>
1156 iyyar,
1157 /// <summary>
1158 /// Sivan.
1159 /// </summary>
1160 sivan,
1161 /// <summary>
1162 /// Tammuz.
1163 /// </summary>
1164 tammuz,
1165 /// <summary>
1166 /// Av.
1167 /// </summary>
1169 /// <summary>
1170 /// Elul.
1171 /// </summary>
1172 elul,
1173 /// <summary>
1174 /// Tishri.
1175 /// </summary>
1176 tishri,
1177 /// <summary>
1178 /// Heshvan.
1179 /// </summary>
1180 heshvan,
1181 /// <summary>
1182 /// Kislev.
1183 /// </summary>
1184 kislev,
1185 /// <summary>
1186 /// Teveth.
1187 /// </summary>
1188 teveth,
1189 /// <summary>
1190 /// Shevat.
1191 /// </summary>
1192 shevat,
1193 /// <summary>
1194 /// Adar.
1195 /// </summary>
1196 adar,
1197 /// <summary>
1198 /// Adar I. Only in years with Adar II.
1199 /// </summary>
1200 adar_I = 12,
1201 /// <summary>
1202 /// Adar II. Only in years wirh Adar I.
1203 /// </summary>
1204 adar_II = 13,
1207 /// <summary>
1208 /// The method tells whether the year is a leap year.
1209 /// </summary>
1210 /// <param name="year">An integer representing the Hebrew year.
1211 /// </param>
1212 /// <returns>A boolean which is true if <paramref name="year"/> is
1213 /// a leap year.
1214 /// </returns>
1215 public static bool is_leap_year(int year) {
1216 return CCMath.mod(7*year+1, 19) < 7;
1219 /// <summary>
1220 /// The Method gives the number of the last month in a year, which
1221 /// is equal with the number of month in a Hebrew year.
1222 /// </summary>
1223 /// <param name="year">An integer representing the Hebrew year.
1224 /// </param>
1225 /// <returns>An integer giving the number of the last month of the
1226 /// Hebrew year, which is the same as the numbers of month in the
1227 /// year.
1228 /// </returns>
1229 public static int last_month_of_year(int year) {
1230 return is_leap_year(year) ? 13 : 12;
1234 /// <summary>The method is a helper function.</summary>
1235 /// <param name="year">An integer specifying the Hebrew year.
1236 /// </param>
1237 /// <returns>An integer representing the number of elapsed days
1238 /// until the Hebrew year.</returns>
1239 public static int elapsed_days(int year) {
1240 int months_elapsed = CCMath.div(235*year-234, 19);
1241 int r;
1242 int d = CCMath.div_mod(out r, months_elapsed, 1080);
1243 int parts_elapsed = 204 + 793 * r;
1244 int hours_elapsed = 11 + 12 * months_elapsed +
1245 793 * d + CCMath.div(parts_elapsed, 1080);
1247 int day = 29*months_elapsed + CCMath.div(hours_elapsed, 24);
1249 if (CCMath.mod(3*(day+1), 7) < 3) {
1250 day += 1;
1253 return day;
1256 /// <summary>A method computing the delay of new year for the given
1257 /// Hebrew year.
1258 /// </summary>
1259 /// <param name="year">An integer that gives the Hebrew year.
1260 /// </param>
1261 /// <returns>The new year delay in days of the given Hebrew year.
1262 /// </returns>
1263 public static int new_year_delay(int year) {
1264 int ny1 = elapsed_days(year);
1265 int ny2 = elapsed_days(year+1);
1267 if (ny2 - ny1 == 356) {
1268 return 2;
1270 int ny0 = elapsed_days(year-1);
1271 if (ny1 - ny0 == 382) {
1272 return 1;
1274 return 0;
1277 /// <summary>
1278 /// The method computes the last day of month (nummer of days in a
1279 /// month) of the given Hebrew year.
1280 /// </summary>
1281 /// <param name="month">The Hebrew month, allowed value between
1282 /// One and Thirteen.
1283 /// </param>
1284 /// <param name="year">An integer that gives the Hebrew year.
1285 /// </param>
1286 /// <returns>The number of the last day of the month of the given
1287 /// Hebrew year, which gives automatically the number of days in the
1288 /// month.
1289 /// </returns>
1290 /// <exception cref="T:System.ArgumentOutOfRange.Exception">
1291 /// The exception is thrown if month not between One and Thirteen.
1292 /// </exception>
1293 public static int last_day_of_month(int month, int year) {
1294 if (month < 1 || month > 13)
1295 throw new System.ArgumentOutOfRangeException("month",
1296 "Month should be between One and Thirteen.");
1297 switch (month) {
1298 case 2: return 29;
1299 case 4: return 29;
1300 case 6: return 29;
1301 case 8:
1302 if (!long_heshvan(year))
1303 return 29;
1304 break;
1305 case 9:
1306 if (short_kislev(year))
1307 return 29;
1308 break;
1309 case 10: return 29;
1310 case 12:
1311 if (!is_leap_year(year))
1312 return 29;
1313 break;
1314 case 13: return 29;
1316 return 30;
1319 /// <summary>
1320 /// The functions checks whether the month Heshvan is a long one
1321 /// in the given Hebrew year.
1322 /// </summary>
1323 /// <param name="year">An integer that gives the Hebrew year.
1324 /// </param>
1325 /// <returns>A boolean value: true if there is a long Heshvan
1326 /// in the given Hebrew year; false otherwise.
1327 /// </returns>
1328 public static bool long_heshvan(int year) {
1329 return CCMath.mod(days_in_year(year), 10) == 5;
1332 /// <summary>
1333 /// The functions checks whether the month Kislev is a short one
1334 /// in the given Hebrew year.
1335 /// </summary>
1336 /// <param name="year">An integer that gives the Hebrew year.
1337 /// </param>
1338 /// <returns>A boolean value: true if there is a short Kislev
1339 /// in the given Hebrew year; false otherwise.
1340 /// </returns>
1341 public static bool short_kislev(int year) {
1342 return CCMath.mod(days_in_year(year), 10) == 3;
1345 /// <summary>
1346 /// The functions gives the number of days in the specified Hebrew
1347 /// year.
1348 /// </summary>
1349 /// <param name="year">An integer that gives the Hebrew year.
1350 /// </param>
1351 /// <returns>The days of the Hebrew year as integer.
1352 /// </returns>
1353 public static int days_in_year(int year) {
1354 return fixed_from_dmy(1, 7, year+1) -
1355 fixed_from_dmy(1, 7, year);
1358 /// <summary>
1359 /// The method returns the fixed day number of the given Hebrew
1360 /// date.
1361 /// </summary>
1362 /// <param name="day">An integer representing the day of the month,
1363 /// counting from 1.
1364 /// </param>
1365 /// <param name="month">An integer representing the month in the
1366 /// Hebrew year.
1367 /// </param>
1368 /// <param name="year">An integer representing the Hebrew year.
1369 /// Non-positive values are allowed also.
1370 /// </param>
1371 /// <returns>An integer value representing the fixed day number.
1372 /// </returns>
1373 public static int fixed_from_dmy(int day, int month, int year) {
1374 int m;
1375 int k = epoch-1;
1376 k += elapsed_days(year);
1377 k += new_year_delay(year);
1379 if (month < 7) {
1380 int l = last_month_of_year(year);
1381 for (m = 7; m <= l; m++) {
1382 k += last_day_of_month(m, year);
1384 for (m = 1; m < month; m++) {
1385 k += last_day_of_month(m, year);
1388 else {
1389 for (m = 7; m < month; m++) {
1390 k += last_day_of_month(m, year);
1394 k += day;
1396 return k;
1399 /// <summary>
1400 /// The method computes the Hebrew year from a fixed day number.
1401 /// </summary>
1402 /// <param name="date">The fixed day number.
1403 /// </param>
1404 /// <returns>An integer value giving the Hebrew year of the date.
1405 /// </returns>
1406 public static int year_from_fixed(int date) {
1407 int approx = (int)System.Math.Floor(
1408 ((double)(date - epoch))/(35975351.0/98496.0));
1409 int y;
1410 for (y = approx; date >= fixed_from_dmy(1, 7, y); y++) {}
1411 return y-1;
1414 /// <summary>
1415 /// The method computes the Hebrew year and month from a fixed day
1416 /// number.
1417 /// </summary>
1418 /// <param name="month">The output value giving the Hebrew month.
1419 /// </param>
1420 /// <param name="year">The output value giving the Hebrew year.
1421 /// </param>
1422 /// <param name="date">An integer value specifying the fixed day
1423 /// number.</param>
1424 public static void my_from_fixed(out int month, out int year,
1425 int date)
1427 year = year_from_fixed(date);
1429 int start = date < fixed_from_dmy(1, 1, year) ? 7 : 1;
1431 for (month = start;
1432 date > fixed_from_dmy(last_day_of_month(month, year),
1433 month, year);
1434 month++)
1438 /// <summary>
1439 /// The method computes the Hebrew year, month, and day from a
1440 /// fixed day number.
1441 /// </summary>
1442 /// <param name="day">The output value returning the day of the
1443 /// month.
1444 /// </param>
1445 /// <param name="month">The output value giving the Hebrew month.
1446 /// </param>
1447 /// <param name="year">The output value giving the Hebrew year.
1448 /// </param>
1449 /// <param name="date">An integer value specifying the fixed day
1450 /// number.</param>
1451 public static void dmy_from_fixed(out int day, out int month,
1452 out int year, int date)
1454 my_from_fixed(out month, out year, date);
1455 day = date - fixed_from_dmy(1, month, year) + 1;
1458 /// <summary>A method computing the Hebrew month from a fixed
1459 /// day number.
1460 /// </summary>
1461 /// <param name="date">An integer specifying the fixed day number.
1462 /// </param>
1463 /// <returns>An integer value representing the Hebrew month.
1464 /// </returns>
1465 public static int month_from_fixed(int date) {
1466 int month, year;
1468 my_from_fixed(out month, out year, date);
1469 return month;
1472 /// <summary>
1473 /// A method computing the day of the month from a fixed day number.
1474 /// </summary>
1475 /// <param name="date">An integer specifying the fixed day number.
1476 /// </param>
1477 /// <returns>An integer value representing the day of the month.
1478 /// </returns>
1479 public static int day_from_fixed(int date) {
1480 int day, month, year;
1482 dmy_from_fixed(out day, out month, out year, date);
1483 return day;
1486 /// <summary>
1487 /// The method computes the difference between two Hebrew dates.
1488 /// </summary>
1489 /// <param name="dayA">The integer parameter gives the day of month
1490 /// of the first date.
1491 /// </param>
1492 /// <param name="monthA">The integer parameter gives the Hebrew
1493 /// month of the first date.
1494 /// </param>
1495 /// <param name="yearA">The integer parameter gives the Hebrew
1496 /// year of the first date.
1497 /// </param>
1498 /// <param name="dayB">The integer parameter gives the day of month
1499 /// of the second date.
1500 /// </param>
1501 /// <param name="monthB">The integer parameter gives the Hebrew
1502 /// month of the second date.
1503 /// </param>
1504 /// <param name="yearB">The integer parameter gives the Hebrew
1505 /// year of the second date.
1506 /// </param>
1507 /// <returns>An integer giving the difference of days from the first
1508 /// the second date.
1509 /// </returns>
1510 public static int date_difference(int dayA, int monthA, int yearA,
1511 int dayB, int monthB, int yearB)
1513 return fixed_from_dmy(dayB, monthB, yearB) -
1514 fixed_from_dmy(dayA, monthA, yearA);
1517 /// <summary>
1518 /// The method computes the number of the day in the year from
1519 /// a Hebrew date.
1520 /// </summary>
1521 /// <param name="day">An integer representing the day of the month,
1522 /// counting from 1.
1523 /// </param>
1524 /// <param name="month">An integer representing the month in the
1525 /// Hebrew year.
1526 /// </param>
1527 /// <param name="year">An integer representing the Hebrew year.
1528 /// </param>
1529 /// <returns>An integer value giving the number of the day in the
1530 /// Hebrew year, counting from 1.
1531 /// </returns>
1532 public static int day_number(int day, int month, int year) {
1533 return date_difference(1, 7, year,
1534 day, month, year) + 1;
1537 /// <summary>
1538 /// The method computes the days remaining in the given Hebrew
1539 /// year from a Hebrew date.
1540 /// </summary>
1541 /// <param name="day">An integer representing the day of the month,
1542 /// counting from 1.
1543 /// </param>
1544 /// <param name="month">An integer representing the month in the
1545 /// Hebrew year.
1546 /// </param>
1547 /// <param name="year">An integer representing the Hebrew year.
1548 /// </param>
1549 /// <returns>An integer value giving the number of days remaining in
1550 /// the Hebrew year.
1551 /// </returns>
1552 public static int days_remaining(int day, int month, int year) {
1553 return date_difference(day, month, year,
1554 1, 7, year+1)-1;
1556 } // class HebrewCalendar
1559 /// <summary>
1560 /// A class encapsulating the functions of the Islamic calendar as static
1561 /// methods.
1562 /// </summary>
1563 /// <remarks>
1564 /// <para>There is no difference here in using Hijri or Islamic calendar.
1565 /// </para>
1566 /// <para>The epoch of the Islamic calendar isn't fixed, because we cannot
1567 /// surely say today, when the crescent of the new moon has been observed
1568 /// around the July 16, 622 C.E. Julian. Even today the start and end of
1569 /// the month Ramadan is defined by religous authorities. So the calendar
1570 /// can be offset by two days.
1571 /// </para>
1572 /// <para>
1573 /// We don't support the offset here, however we changed the epoch from
1574 /// "Calendrical Calculations" to value, that .Net seems to be using.
1575 /// </para>
1576 /// <para>
1577 /// This class is not compatible to
1578 /// <see cref="T:System.Globalization.HijriCalendar"/>.
1579 /// </para>
1580 /// <seealso cref="T:CCFixed"/>
1581 /// </remarks>
1582 internal class CCHijriCalendar {
1583 /// <summary>An integer defining the epoch of the Gregorian calendar
1584 /// as fixed day number.</summary>
1585 /// <remarks>
1586 /// <para>
1587 /// The epoch is given as 16 July 622 C.E. Julian (R.D. 227015)
1588 /// in Calendrical Calculations, the approximate date of
1589 /// the emigration of
1590 /// Muhammed to Medina. However there is no way to determine today
1591 /// the observation of the crescent of the new moon in July 622 C.E.
1592 /// (Julian). So there is some variability in the epoch.
1593 /// Religous authorities determine the epoch by observing the
1594 /// crescent of the new moon for the month Ramadan, so there might
1595 /// be an offsets by two days of the epoch.
1596 /// </para>
1597 /// <para>Windows
1598 /// supports an AddHijriDate parameter in the registry to adapt
1599 /// for it. It seems that the .NET implementation of
1600 /// HijriCalendar uses an epoch of 227014, so we use it here. The
1601 /// ArgumentOutOfRangeException gives July, 18 622 as epoch,
1602 /// which is 227014 supporting our theory.
1603 /// </para>
1604 /// </remarks>
1605 const int epoch = 227014;
1607 /// <summary>The enumeration defines the months of the Islamic
1608 /// calendar.
1609 /// </summary>
1610 public enum Month {
1611 /// <summary>
1612 /// Muharram.
1613 /// </summary>
1614 muharram = 1,
1615 /// <summary>
1616 /// Safar.
1617 /// </summary>
1618 safar,
1619 /// <summary>
1620 /// Rabi I.
1621 /// </summary>
1622 rabi_I,
1623 /// <summary>
1624 /// Rabi II.
1625 /// </summary>
1626 rabi_II,
1627 /// <summary>
1628 /// Jumada I.
1629 /// </summary>
1630 jumada_I,
1631 /// <summary>
1632 /// Jumada II.
1633 /// </summary>
1634 jumada_II,
1635 /// <summary>
1636 /// Rajab.
1637 /// </summary>
1638 rajab,
1639 /// <summary>
1640 /// Shaban.
1641 /// </summary>
1642 shaban,
1643 /// <summary>
1644 /// Ramadan.
1645 /// </summary>
1646 ramadan,
1647 /// <summary>
1648 /// Shawwal.
1649 /// </summary>
1650 shawwal,
1651 /// <summary>
1652 /// Dhu Al-Quada.
1653 /// </summary>
1654 dhu_al_quada,
1655 /// <summary>
1656 /// Dhu Al-Hijja.
1657 /// </summary>
1658 dhu_al_hijja,
1661 /// <summary>
1662 /// The method tells whether the year is a leap year.
1663 /// </summary>
1664 /// <param name="year">An integer representing the Islamic year.
1665 /// </param>
1666 /// <returns>A boolean which is true if <paramref name="year"/> is
1667 /// a leap year.
1668 /// </returns>
1669 public static bool is_leap_year(int year) {
1670 return CCMath.mod(14+11*year, 30) < 11;
1673 /// <summary>
1674 /// The method returns the fixed day number of the given Islamic
1675 /// date.
1676 /// </summary>
1677 /// <param name="day">An integer representing the day of the month,
1678 /// counting from 1.
1679 /// </param>
1680 /// <param name="month">An integer representing the month in the
1681 /// Islamic year.
1682 /// </param>
1683 /// <param name="year">An integer representing the Islamic year.
1684 /// Non-positive values are allowed also.
1685 /// </param>
1686 /// <returns>An integer value representing the fixed day number.
1687 /// </returns>
1688 public static int fixed_from_dmy(int day, int month, int year) {
1689 int k = epoch - 1;
1690 k += 354 * (year-1);
1691 k += CCMath.div(3+11*year, 30);
1692 k += (int)System.Math.Ceiling(29.5 * (double)(month-1));
1693 k += day;
1695 return k;
1698 /// <summary>
1699 /// The method computes the Islamic year from a fixed day number.
1700 /// </summary>
1701 /// <param name="date">The fixed day number.
1702 /// </param>
1703 /// <returns>An integer value giving the Islamic year of the date.
1704 /// </returns>
1705 public static int year_from_fixed(int date) {
1706 return CCMath.div(30*(date-epoch)+10646, 10631);
1709 /// <summary>
1710 /// The method computes the Islamic year and month from a fixed day
1711 /// number.
1712 /// </summary>
1713 /// <param name="month">The output value giving the Islamic month.
1714 /// </param>
1715 /// <param name="year">The output value giving the Islamic year.
1716 /// </param>
1717 /// <param name="date">An integer value specifying the fixed day
1718 /// number.</param>
1719 public static void my_from_fixed(out int month, out int year, int date)
1721 year = year_from_fixed(date);
1723 int m = 1+(int)System.Math.Ceiling(
1724 ((double)(date-29-fixed_from_dmy(1,1,year)))/29.5);
1726 month = m < 12 ? m : 12;
1729 /// <summary>
1730 /// The method computes the Islamic year, month, and day from a
1731 /// fixed day number.
1732 /// </summary>
1733 /// <param name="day">The output value returning the day of the
1734 /// month.
1735 /// </param>
1736 /// <param name="month">The output value giving the Islamic month.
1737 /// </param>
1738 /// <param name="year">The output value giving the Islamic year.
1739 /// </param>
1740 /// <param name="date">An integer value specifying the fixed day
1741 /// number.</param>
1742 public static void dmy_from_fixed(out int day, out int month,
1743 out int year, int date)
1745 my_from_fixed(out month, out year, date);
1746 day = date - fixed_from_dmy(1, month, year) + 1;
1749 /// <summary>A method computing the Islamic month from a fixed
1750 /// day number.
1751 /// </summary>
1752 /// <param name="date">An integer specifying the fixed day number.
1753 /// </param>
1754 /// <returns>An integer value representing the Islamic month.
1755 /// </returns>
1756 public static int month_from_fixed(int date) {
1757 int month, year;
1759 my_from_fixed(out month, out year, date);
1760 return month;
1763 /// <summary>
1764 /// A method computing the day of the month from a fixed day number.
1765 /// </summary>
1766 /// <param name="date">An integer specifying the fixed day number.
1767 /// </param>
1768 /// <returns>An integer value representing the day of the month.
1769 /// </returns>
1770 public static int day_from_fixed(int date) {
1771 int day;
1772 int month;
1773 int year;
1775 dmy_from_fixed(out day, out month, out year, date);
1776 return day;
1779 /// <summary>
1780 /// The method computes the difference between two Islamic dates.
1781 /// </summary>
1782 /// <param name="dayA">The integer parameter gives the day of month
1783 /// of the first date.
1784 /// </param>
1785 /// <param name="monthA">The integer parameter gives the Islamic
1786 /// month of the first date.
1787 /// </param>
1788 /// <param name="yearA">The integer parameter gives the Islamic
1789 /// year of the first date.
1790 /// </param>
1791 /// <param name="dayB">The integer parameter gives the day of month
1792 /// of the second date.
1793 /// </param>
1794 /// <param name="monthB">The integer parameter gives the Islamic
1795 /// month of the second date.
1796 /// </param>
1797 /// <param name="yearB">The integer parameter gives the Islamic
1798 /// year of the second date.
1799 /// </param>
1800 /// <returns>An integer giving the difference of days from the first
1801 /// the second date.
1802 /// </returns>
1803 public static int date_difference(int dayA, int monthA, int yearA,
1804 int dayB, int monthB, int yearB)
1806 return fixed_from_dmy(dayB, monthB, yearB) -
1807 fixed_from_dmy(dayA, monthA, yearA);
1810 /// <summary>
1811 /// The method computes the number of the day in the year from
1812 /// a Islamic date.
1813 /// </summary>
1814 /// <param name="day">An integer representing the day of the month,
1815 /// counting from 1.
1816 /// </param>
1817 /// <param name="month">An integer representing the month in the
1818 /// Islamic year.
1819 /// </param>
1820 /// <param name="year">An integer representing the Islamic year.
1821 /// </param>
1822 /// <returns>An integer value giving the number of the day in the
1823 /// Islamic year, counting from 1.
1824 /// </returns>
1825 public static int day_number(int day, int month, int year) {
1826 return date_difference(31, 12, year-1, day, month, year);
1829 /// <summary>
1830 /// The method computes the days remaining in the given Islamic
1831 /// year from a Islamic date.
1832 /// </summary>
1833 /// <param name="day">An integer representing the day of the month,
1834 /// counting from 1.
1835 /// </param>
1836 /// <param name="month">An integer representing the month in the
1837 /// Islamic year.
1838 /// </param>
1839 /// <param name="year">An integer representing the Islamic year.
1840 /// Non-positive values are allowed also.
1841 /// </param>
1842 /// <returns>An integer value giving the number of days remaining in
1843 /// the Islamic year.
1844 /// </returns>
1845 public static int days_remaining(int day, int month, int year) {
1846 return date_difference(day, month, year,31, 12, year);
1848 } // class CCHijriCalendar
1850 internal class CCEastAsianLunisolarCalendar
1852 public static int fixed_from_dmy (int day, int month, int year)
1855 int k = epoch - 1;
1856 k += 354 * (year - 1);
1857 k += CCMath.div (3+11*year, 30);
1858 k += (int) Math.Ceiling(29.53 * (double)(month-1));
1859 k += day;
1861 return k;
1863 throw new Exception ("fixed_from_dmy");
1866 public static int year_from_fixed (int date)
1868 throw new Exception ("year_from_fixed");
1871 public static void my_from_fixed(out int month, out int year, int date)
1874 year = year_from_fixed (date);
1876 int m = 1+(int)System.Math.Ceiling(
1877 ((double)(date-29-fixed_from_dmy(1,1,year)))/29.5);
1879 month = m < 12 ? m : 12;
1881 throw new Exception ("my_from_fixed");
1884 public static void dmy_from_fixed(out int day, out int month,
1885 out int year, int date)
1888 my_from_fixed (out month, out year, date);
1889 day = date - fixed_from_dmy (1, month, year) + 1;
1891 throw new Exception ("dmy_from_fixed");
1894 public static DateTime AddMonths (DateTime date, int months)
1897 throw new Exception ("AddMonths");
1900 public static DateTime AddYears (DateTime date, int years)
1902 throw new Exception ("AddYears");
1905 public static int GetDayOfMonth (DateTime date)
1907 throw new Exception ("GetDayOfMonth");
1910 public static int GetDayOfYear (DateTime date)
1912 throw new Exception ("GetDayOfYear");
1915 public static int GetDaysInMonth (int gyear, int month)
1917 throw new Exception ("GetDaysInMonth");
1920 public static int GetDaysInYear (int year)
1922 throw new Exception ("GetDaysInYear");
1925 public static int GetMonth (DateTime date)
1927 throw new Exception ("GetMonth");
1930 public static bool IsLeapMonth (int gyear, int month)
1932 int goldenNumber = gyear % 19;
1934 bool chu = false;
1935 bool leap = false;
1936 double s = 0;
1937 for (int y = 0; y < goldenNumber; y++) {
1938 for (int l = 0, m = 1; m <= month; m++) {
1939 if (leap) {
1940 l += 30;
1941 leap = false;
1942 if (y == goldenNumber && m == month)
1943 return true;
1944 } else {
1945 l += chu ? 30 : 29;
1946 chu = !chu;
1947 s += 30.44;
1948 if (s - l > 29)
1949 leap = true;
1953 return false;
1956 public static bool IsLeapYear (int gyear)
1959 // FIXME: it is still wrong.
1960 int d = gyear % 19;
1961 switch (d) {
1962 case 0: case 3: case 6: case 9: case 11: case 14: case 17:
1963 return true;
1964 default:
1965 return false;
1968 int goldenNumber = (gyear - 1900) % 19;
1969 int epact = 29;
1970 bool leap = false;
1971 while (goldenNumber-- >= 0) {
1972 epact += 11;
1973 leap = epact > 30;
1974 if (epact > 30)
1975 epact -= 30;
1977 return leap;
1981 public static DateTime ToDateTime (int year, int month, int day, int hour, int minute, int second, int millisecond)
1983 throw new Exception ("ToDateTime");
1987 /// <summary>
1988 /// A class that supports the Gregorian based calendars with other eras
1989 /// (e.g. <see cref="T:System.Gloablization.JapaneseCalendar"/>).
1990 /// </summary>
1991 [System.Serializable]
1992 internal class CCGregorianEraHandler {
1993 /// <summary>
1994 /// A struct that represents a single era.
1995 /// </summary>
1996 [System.Serializable]
1997 struct Era {
1998 /// <summary>
1999 /// The integer number identifying the era.
2000 /// </summary>
2001 private int _nr;
2003 /// <value>
2004 /// A get-only property that gives the era integer number.
2005 /// </value>
2006 public int Nr { get { return _nr; } }
2008 /// <summary>This integer gives the first day of the era as
2009 /// fixed day number.
2010 /// </summary>
2011 private int _start; // inclusive
2012 /// <summary>
2013 /// This integer gives the gregorian year of the
2014 /// <see cref="M:_start"/> value.
2015 /// </summary>
2016 private int _gregorianYearStart;
2017 /// <summary>
2018 /// This integer gives the last day of the era as fixed day
2019 /// number.
2020 /// </summary>
2021 private int _end; // inclusive
2022 /// <summary>
2023 /// This integer gives the largest year number of this era.
2024 /// </summary>
2025 private int _maxYear;
2027 /// <summary>
2028 /// This constructor creates the era structure.
2029 /// </summary>
2030 /// <param name="nr">The integer number of the era.
2031 /// </param>
2032 /// <param name="start">The fixed day number defining the
2033 /// first day of the era.
2034 /// </param>
2035 /// <param name="end">The fixed day number that defines the
2036 /// last day of the era.
2037 /// </param>
2038 public Era(int nr, int start, int end) {
2039 if (nr == 0)
2040 throw new System.ArgumentException(
2041 "Era number shouldn't be zero.");
2042 _nr = nr;
2043 if (start > end) {
2044 throw new System.ArgumentException(
2045 "Era should start before end.");
2047 _start = start;
2048 _end = end;
2050 _gregorianYearStart =
2051 CCGregorianCalendar.year_from_fixed(_start);
2052 int gregorianYearEnd =
2053 CCGregorianCalendar.year_from_fixed(_end);
2054 _maxYear = gregorianYearEnd - _gregorianYearStart + 1;
2057 /// <summary>
2058 /// This method computes the Gregorian year from the year
2059 /// of this era.
2060 /// </summary>
2061 /// <param name="year">An integer giving the year in the
2062 /// era.
2063 /// </param>
2064 /// <returns>
2065 /// The Gregorian year as integer.
2066 /// </returns>
2067 /// <exception cref="T:System.ArgumentOutOfRangeException">
2068 /// The exception is thrown if the year isn't valid in this
2069 /// era.
2070 /// </exception>
2071 public int GregorianYear(int year) {
2072 if (year < 1 || year > _maxYear) {
2073 System.IO.StringWriter sw =
2074 new System.IO.StringWriter();
2075 sw.Write(
2076 "Valid Values are between " +
2077 "{0} and {1}, inclusive.",
2078 1, _maxYear);
2079 throw new System.ArgumentOutOfRangeException(
2080 "year", sw.ToString());
2082 return year + _gregorianYearStart - 1;
2085 /// <summary>
2086 /// This function checks wether the given fixed day number is
2087 /// ion the time span of the era.
2088 /// </summary>
2089 /// <param name="date">An integer giving the fixed day
2090 /// number.
2091 /// </param>
2092 /// <returns>A boolean: true if the argument is in the time
2093 /// span of the era.
2094 /// </returns>
2095 public bool Covers(int date) {
2096 return _start <= date && date <= _end;
2099 /// <summary>
2100 /// This function returns the year of the era and sets
2101 /// the era in an output parameter.
2102 /// </summary>
2103 /// <param name="era">An output parameter returning the
2104 /// era number.
2105 /// </param>
2106 /// <param name="date">An integer giving the fixed day
2107 /// number.
2108 /// </param>
2109 /// <returns>An integer giving the year of the era.
2110 /// </returns>
2111 /// <exception cref="T:System.ArgumentOutOfRangeException">
2112 /// The exception is thrown if date is outside of the time
2113 /// span of the era.
2114 /// </exception>
2115 public int EraYear(out int era, int date) {
2116 if (!Covers(date))
2117 throw new System.ArgumentOutOfRangeException(
2118 "date",
2119 "Time was out of Era range.");
2120 int gregorianYear =
2121 CCGregorianCalendar.year_from_fixed(date);
2122 era = _nr;
2123 return gregorianYear - _gregorianYearStart + 1;
2125 } // struct Era
2127 /// <summary>
2128 /// A private member storing the eras in a
2129 /// <see cref="T:System.Collections.SortedList"/>.
2130 /// </summary>
2131 private SortedList _Eras;
2133 /// <value>
2134 /// The property returns the era numbers as an array of integers.
2135 /// </value>
2136 public int[] Eras {
2137 get {
2138 int[] a = new int[_Eras.Count];
2140 for (int i = 0; i < _Eras.Count; i++) {
2141 Era e = (Era)_Eras.GetByIndex(i);
2142 a[i] = e.Nr;
2145 return a;
2149 /// <summary>
2150 /// Constructor.
2151 /// </summary>
2152 public CCGregorianEraHandler() {
2153 _Eras = new SortedList();
2156 /// <summary>
2157 /// Method adds an era to the GregorianEraHandler instance.
2158 /// </summary>
2159 /// <param name="nr">The integer number of the era.
2160 /// </param>
2161 /// <param name="rd_start">The fixed day number defining the
2162 /// first day of the era.
2163 /// </param>
2164 /// <param name="rd_end">The fixed day number that defines the
2165 /// last day of the era.
2166 /// </param>
2167 public void appendEra(int nr, int rd_start, int rd_end) {
2168 Era era = new Era(nr, rd_start, rd_end);
2169 _Eras[(System.Object)nr] = era;
2171 /// <summary>
2172 /// Method adds a yet not-ended era to the GregorianEraHandler
2173 /// instance.
2174 /// </summary>
2175 /// <param name="nr">The integer number of the era.
2176 /// </param>
2177 /// <param name="rd_start">The fixed day number defining the
2178 /// first day of the era.
2179 /// </param>
2180 public void appendEra(int nr, int rd_start) {
2181 appendEra(nr, rd_start,
2182 CCFixed.FromDateTime(DateTime.MaxValue));
2185 /// <summary>
2186 /// This method computes the Gregorian year from the year
2187 /// of the given era.
2188 /// </summary>
2189 /// <param name="year">An integer giving the year in the
2190 /// era.
2191 /// </param>
2192 /// <param name="era">An integer giving the era number.
2193 /// </param>
2194 /// <returns>
2195 /// The Gregorian year as integer.
2196 /// </returns>
2197 /// <exception cref="T:System.ArgumentOutOfRangeException">
2198 /// The exception is thrown if the year isn't valid in this
2199 /// era.
2200 /// </exception>
2201 public int GregorianYear(int year, int era) {
2202 Era e = (Era)_Eras[(System.Object)era];
2203 return e.GregorianYear(year);
2206 /// <summary>
2207 /// This function returns the year of the era and sets
2208 /// the era in an output parameter.
2209 /// </summary>
2210 /// <param name="era">An output parameter returning the
2211 /// era number.
2212 /// </param>
2213 /// <param name="date">An integer giving the fixed day
2214 /// number.
2215 /// </param>
2216 /// <returns>An integer giving the year of the era.
2217 /// </returns>
2218 /// <exception cref="T:System.ArgumentOutOfRangeException">
2219 /// The exception is thrown if the fixed day number is outside of the
2220 /// time spans of all eras.
2221 /// </exception>
2222 public int EraYear(out int era, int date)
2224 IList list = _Eras.GetValueList();
2226 foreach (Era e in list) {
2227 if (e.Covers(date))
2228 return e.EraYear(out era, date);
2231 throw new System.ArgumentOutOfRangeException("date",
2232 "Time value was out of era range.");
2235 /// <summary>
2236 /// The method checks whether a given
2237 /// <see cref="T:System.DateTime"/> is covered by any era.
2238 /// </summary>
2239 /// <param name="time">A
2240 /// <see cref="T:System.DateTime"/> giving the date and time.
2241 /// </param>
2242 /// <exception cref="T:System.ArgumentOutOfRangeException">
2243 /// The exception is thrown if the argument isn't inside the time
2244 /// span of any era.
2245 /// </exception>
2246 public void CheckDateTime(System.DateTime time) {
2247 int date = CCFixed.FromDateTime(time);
2249 if (!ValidDate(date))
2250 throw new System.ArgumentOutOfRangeException("time",
2251 "Time value was out of era range.");
2254 /// <summary>
2255 /// The method tests whether a given
2256 /// fixed day number is covered by any era.
2257 /// </summary>
2258 /// <param name="date">An integer representing the fixed day number.
2259 /// </param>
2260 /// <returns> A boolean is returned: true if the argument is inside
2261 /// the time span of one era; false otherwise.
2262 /// </returns>
2263 public bool ValidDate(int date) {
2264 IList list = _Eras.GetValueList();
2266 foreach (Era e in list) {
2267 if (e.Covers(date))
2268 return true;
2271 return false;
2274 /// <summary>
2275 /// The method tests, whether the era number does exist.
2276 /// </summary>
2277 /// <param name="era">An integer giving the era number.
2278 /// </param>
2279 /// <returns>A boole value: True if the era number does exist;
2280 /// false otherwise.
2281 /// </returns>
2282 public bool ValidEra(int era) {
2283 return _Eras.Contains((System.Object)era);
2285 } // class CCGregorianEraHandler
2288 // FIXME: remove this class. It should be identical to CCGregorianEraHandler
2289 [System.Serializable]
2290 internal class CCEastAsianLunisolarEraHandler
2292 [Serializable]
2293 struct Era
2295 private int _nr; // era index
2297 public int Nr {
2298 get { return _nr; }
2301 private int _start; // inclusive
2302 private int _gregorianYearStart;
2303 private int _end; // inclusive
2304 private int _maxYear;
2306 public Era (int nr, int start, int end)
2308 if (nr == 0)
2309 throw new ArgumentException ("Era number shouldn't be zero.");
2310 _nr = nr;
2311 if (start > end)
2312 throw new ArgumentException ("Era should start before end.");
2313 _start = start;
2314 _end = end;
2316 _gregorianYearStart = CCGregorianCalendar.year_from_fixed (_start);
2317 int gregorianYearEnd = CCGregorianCalendar.year_from_fixed (_end);
2318 _maxYear = gregorianYearEnd - _gregorianYearStart + 1;
2321 public int GregorianYear (int year)
2323 if (year < 1 || year > _maxYear)
2324 throw new ArgumentOutOfRangeException ("year", String.Format ("Valid Values are between {0} and {1}, inclusive.", 1, _maxYear));
2325 return year + _gregorianYearStart - 1;
2328 public bool Covers (int date) {
2329 return _start <= date && date <= _end;
2332 public int EraYear (out int era, int date) {
2333 if (!Covers (date))
2334 throw new ArgumentOutOfRangeException ("date", "Time was out of Era range.");
2335 int gregorianYear = CCGregorianCalendar.year_from_fixed (date);
2336 era = _nr;
2337 return gregorianYear - _gregorianYearStart + 1;
2341 private SortedList _Eras;
2343 public int [] Eras
2345 get {
2346 int[] a = new int [_Eras.Count];
2347 for (int i = 0; i < _Eras.Count; i++) {
2348 Era e = (Era) _Eras.GetByIndex (i);
2349 a[i] = e.Nr;
2351 return a;
2355 public CCEastAsianLunisolarEraHandler ()
2357 _Eras = new SortedList ();
2360 public void appendEra (int nr, int rd_start, int rd_end)
2362 Era era = new Era (nr, rd_start, rd_end);
2363 _Eras [nr] = era;
2366 public void appendEra (int nr, int rd_start)
2368 appendEra (nr, rd_start, CCFixed.FromDateTime (DateTime.MaxValue));
2371 public int GregorianYear (int year, int era)
2373 Era e = (Era) _Eras [era];
2374 return e.GregorianYear (year);
2377 public int EraYear (out int era, int date)
2379 foreach (Era e in _Eras.Values)
2380 if (e.Covers (date))
2381 return e.EraYear (out era, date);
2383 throw new ArgumentOutOfRangeException ("date", "Time value was out of era range.");
2386 public void CheckDateTime (DateTime time)
2388 int date = CCFixed.FromDateTime (time);
2390 if (!ValidDate (date))
2391 throw new ArgumentOutOfRangeException ("time", "Time value was out of era range.");
2394 public bool ValidDate (int date)
2396 foreach (Era e in _Eras.Values) {
2397 if (e.Covers (date))
2398 return true;
2400 return false;
2403 public bool ValidEra (int era)
2405 return _Eras.Contains (era);
2409 } // namespace System.Globalization