1 // System.Globalization.Calendar.cs
3 // (C) Ulrich Kunitz 2002
7 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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 {
33 using System.Runtime.InteropServices;
36 /// The class serves as a base class for calendar classes.
40 public abstract class Calendar : ICloneable
42 /// <value>An protected integer property that gives the number of
43 /// days in a week. It might be overridden.</value>
44 internal virtual int M_DaysInWeek
50 /// The protected method creates the string used in the
51 /// <see cref="T:System.ArgumentOutOfRangeException"/>
53 /// <param name="a">An object that represents the smallest
54 /// allowable value.</param>
55 /// <param name="b">An object that represents the greatest allowable
57 /// <returns>The string used in the
58 /// <see cref="T:System.ArgumentOutOfRangeException"/>
60 internal string M_ValidValues(object a, object b)
62 StringWriter sw = new StringWriter();
63 sw.Write("Valid values are between {0} and {1}, inclusive.",
69 /// The protected method checks wether the parameter
70 /// <paramref name="arg"/> is in the allowed range.
72 /// <param name="param">A string that gives the name of the
73 /// parameter to check.</param>
74 /// <param name="arg">An integer that gives the value to check.
76 /// <param name="a">An integer that represents the smallest allowed
78 /// <param name="b">An integer that represents the greatest allowed
80 /// <exception cref="T:System.ArgumentOutOfRangeException">
81 /// The exception is thrown, if the <paramref name="arg"/> is outside
82 /// the allowed range.
84 internal void M_ArgumentInRange(string param, int arg, int a, int b)
86 if (a <= arg && arg <= b)
88 throw new ArgumentOutOfRangeException(param, M_ValidValues(a, b));
92 /// The protected method, that checks whether
93 /// <paramref name="hour"/>, <paramref name="minute"/>,
94 /// <paramref name="second"/>, and <parameref name="millisecond"/>
95 /// are in their valid ranges
97 /// <param name="hour">An integer that represents a hour,
98 /// should be between 0 and 23.</param>
99 /// <param name="minute">An integer that represents a minute,
100 /// should be between 0 and 59.</param>
101 /// <param name="second">An integer that represents a second,
102 /// should be between 0 and 59.</param>
103 /// <param name="milliseconds">An integer that represents a number
104 /// of milliseconds, should be between 0 and 999999.</param>
105 /// <exception cref="T:System.ArgumentOutOfRangeException">
106 /// The Exception is thrown, if one of the parameter is outside the
107 /// allowed the range.
109 internal void M_CheckHMSM(int hour, int minute, int second,
112 M_ArgumentInRange("hour", hour, 0, 23);
113 M_ArgumentInRange("minute", minute, 0, 59);
114 M_ArgumentInRange("second", second, 0, 59);
115 M_ArgumentInRange("milliseconds", milliseconds, 0, 999999);
119 /// A represantation of the CurrentEra.
121 public const int CurrentEra = 0;
123 /// <value>When overridden gives the eras supported by the
124 /// calendar as an array of integers.
126 public abstract int[] Eras { get; }
131 [System.Runtime.InteropServices.ComVisible(false)]
132 public virtual CalendarAlgorithmType AlgorithmType {
134 return CalendarAlgorithmType.Unknown;
138 [System.Runtime.InteropServices.ComVisible(false)]
139 public virtual DateTime MaxSupportedDateTime {
141 return DateTime.MaxValue;
145 [System.Runtime.InteropServices.ComVisible(false)]
146 public virtual DateTime MinSupportedDateTime {
148 return DateTime.MinValue;
152 // LAMESPEC: huh, why not Calendar but Object?
154 public virtual object Clone ()
156 Calendar c = (Calendar) MemberwiseClone ();
157 c.m_isReadOnly = false;
162 public virtual int GetLeapMonth (int year)
164 return GetLeapMonth (year, GetEra (ToDateTime (year, 1, 1, 0, 0, 0, 0)));
168 public virtual int GetLeapMonth (int year, int era)
170 int max = GetMonthsInYear (year, era);
171 for (int i = 1; i <= max; i++)
172 if (IsLeapMonth (year, i, era))
178 public bool IsReadOnly {
179 get { return m_isReadOnly; }
183 public static Calendar ReadOnly (Calendar calendar)
185 if (calendar.m_isReadOnly)
187 Calendar c = (Calendar) calendar.Clone ();
188 c.m_isReadOnly = true;
192 internal void CheckReadOnly ()
195 throw new InvalidOperationException ("This Calendar is read-only.");
199 /// The protected member stores the value for the
200 /// <see cref="P:TwoDigitYearMax"/>
204 internal int twoDigitYearMax;
208 /// Private field containing the maximum year for the calendar.
211 private int M_MaxYearValue = 0;
214 /// Get-only property returing the maximum allowed year for this
217 internal virtual int M_MaxYear {
219 if (M_MaxYearValue == 0) {
220 M_MaxYearValue = GetYear(DateTime.MaxValue);
222 return M_MaxYearValue;
227 /// Checks whether the year is the era is valid, if era = CurrentEra
228 /// the right value is set.
230 /// <param name="year">The year to check.</param>
231 /// <param name="era">The era to check.</Param>
232 /// <exception cref="T:ArgumentOutOfRangeException">
233 /// The exception will be thrown, if the year is not valid.
235 internal virtual void M_CheckYE(int year, ref int era)
238 // By default, we do nothing.
240 // This used to be an abstract method in Mono's implementation,
241 // but that means that end-user code could not create their
244 // Binaries would also crash in this condition.
248 /// <para>The property gives the maximum value for years with two
249 /// digits. If the property has the value 2029, than the two-digit
250 /// integer 29 results in the year 2029 and 30 in the
251 /// year 1930.</para>
252 /// <para>It might be overridden.</para>
254 public virtual int TwoDigitYearMax {
255 get { return twoDigitYearMax; }
258 M_ArgumentInRange("year", value, 100, M_MaxYear);
259 int era = CurrentEra;
260 M_CheckYE(value, ref era);
261 twoDigitYearMax = value;
266 /// The virtual method adds days to a given date.
268 /// <param name="time">The
269 /// <see cref="T:System.DateTime"/> to which to add
272 /// <param name="days">The number of days to add.</param>
273 /// <returns>A new <see cref="T:System.DateTime"/> value, that
274 /// results from adding <paramref name="days"/> to the specified
275 /// DateTime.</returns>
276 public virtual DateTime AddDays(DateTime time, int days) {
277 return time.Add(TimeSpan.FromDays(days));
281 /// The virtual method adds hours to a given date.
283 /// <param name="time">The
284 /// <see cref="T:System.DateTime"/> to which to add
287 /// <param name="hours">The number of hours to add.</param>
288 /// <returns>A new <see cref="T:System.DateTime"/> value, that
289 /// results from adding <paramref name="hours"/> to the specified
290 /// DateTime.</returns>
291 public virtual DateTime AddHours(DateTime time, int hours) {
292 return time.Add(TimeSpan.FromHours(hours));
296 /// The virtual method adds milliseconds to a given date.
298 /// <param name="time">The
299 /// <see cref="T:System.DateTime"/> to which to add
302 /// <param name="milliseconds">The number of milliseconds given as
303 /// double to add. Keep in mind the 100 nanosecond resolution of
304 /// <see cref="T:System.DateTime"/>.
306 /// <returns>A new <see cref="T:System.DateTime"/> value, that
307 /// results from adding <paramref name="milliseconds"/> to the specified
308 /// DateTime.</returns>
309 public virtual DateTime AddMilliseconds(DateTime time,
312 return time.Add(TimeSpan.FromMilliseconds(milliseconds));
316 /// The virtual method adds minutes to a given date.
318 /// <param name="time">The
319 /// <see cref="T:System.DateTime"/> to which to add
322 /// <param name="minutes">The number of minutes to add.</param>
323 /// <returns>A new <see cref="T:System.DateTime"/> value, that
324 /// results from adding <paramref name="minutes"/> to the specified
325 /// DateTime.</returns>
326 public virtual DateTime AddMinutes(DateTime time, int minutes) {
327 return time.Add(TimeSpan.FromMinutes(minutes));
331 /// When overrideden adds months to a given date.
333 /// <param name="time">The
334 /// <see cref="T:System.DateTime"/> to which to add
337 /// <param name="months">The number of months to add.</param>
338 /// <returns>A new <see cref="T:System.DateTime"/> value, that
339 /// results from adding <paramref name="months"/> to the specified
340 /// DateTime.</returns>
341 public abstract DateTime AddMonths(DateTime time, int months);
344 /// The virtual method adds seconds to a given date.
346 /// <param name="time">The
347 /// <see cref="T:System.DateTime"/> to which to add
350 /// <param name="seconds">The number of seconds to add.</param>
351 /// <returns>A new <see cref="T:System.DateTime"/> value, that
352 /// results from adding <paramref name="seconds"/> to the specified
353 /// DateTime.</returns>
354 public virtual DateTime AddSeconds(DateTime time, int seconds) {
355 return time.Add(TimeSpan.FromSeconds(seconds));
359 /// A wirtual method that adds weeks to a given date.
361 /// <param name="time">The
362 /// <see cref="T:System.DateTime"/> to which to add
365 /// <param name="weeks">The number of weeks to add.</param>
366 /// <returns>A new <see cref="T:System.DateTime"/> value, that
367 /// results from adding <paramref name="weeks"/> to the specified
368 /// DateTime.</returns>
369 public virtual DateTime AddWeeks(DateTime time, int weeks) {
370 return time.AddDays(weeks * M_DaysInWeek);
374 /// When overrideden adds years to a given date.
376 /// <param name="time">The
377 /// <see cref="T:System.DateTime"/> to which to add
380 /// <param name="years">The number of years to add.</param>
381 /// <returns>A new <see cref="T:System.DateTime"/> value, that
382 /// results from adding <paramref name="years"/> to the specified
383 /// DateTime.</returns>
384 public abstract DateTime AddYears(DateTime time, int years);
387 /// When overriden gets the day of the month from
388 /// <paramref name="time"/>.
390 /// <param name="time">The
391 /// <see cref="T:System.DateTime"/> that specifies a
394 /// <returns>An integer giving the day of months, starting with 1.
396 public abstract int GetDayOfMonth(DateTime time);
399 /// When overriden gets the day of the week from the specified date.
401 /// <param name="time">The
402 /// <see cref="T:System.DateTime"/> that specifies a
405 /// <returns>An integer giving the day of months, starting with 1.
407 public abstract DayOfWeek GetDayOfWeek(DateTime time);
410 /// When overridden gives the number of the day in the year.
412 /// <param name="time">The
413 /// <see cref="T:System.DateTime"/> that specifies a
416 /// <returns>An integer representing the day of the year,
417 /// starting with 1.</returns>
418 public abstract int GetDayOfYear(DateTime time);
421 /// A virtual method that gives the number of days of the specified
422 /// month of the <paramref name="year"/> and the
423 /// <see cref="P:CurrentEra"/>.
425 /// <param name="year">An integer that gives the year in the current
427 /// <param name="month">An integer that gives the month, starting
429 /// <returns>An integer that gives the number of days of the
430 /// specified month.</returns>
431 /// <exception cref="T:System.ArgumentOutOfRangeException">
432 /// The exception is thrown, if <paramref name="month"/> or
433 /// <paramref name="year"/> is outside the allowed range.
435 public virtual int GetDaysInMonth(int year, int month) {
436 return GetDaysInMonth(year, month, CurrentEra);
440 /// When overridden gives the number of days in the specified month
441 /// of the given year and era.
443 /// <param name="year">An integer that gives the year.
445 /// <param name="month">An integer that gives the month, starting
447 /// <param name="era">An intger that gives the era of the specified
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.
456 public abstract int GetDaysInMonth(int year, int month, int era);
459 /// A virtual method that gives the number of days of the specified
460 /// year of the <see cref="P:CurrentEra"/>.
462 /// <param name="year">An integer that gives the year in the current
464 /// <returns>An integer that gives the number of days of the
465 /// specified year.</returns>
466 /// <exception cref="T:System.ArgumentOutOfRangeException">
467 /// The exception is thrown, if
468 /// <paramref name="year"/> is outside the allowed range.
470 public virtual int GetDaysInYear(int year) {
471 return GetDaysInYear(year, CurrentEra);
475 /// When overridden gives the number of days of the specified
476 /// year of the given era..
478 /// <param name="year">An integer that specifies the year.
480 /// <param name="era">An ineger that specifies the era.
482 /// <returns>An integer that gives the number of days of the
483 /// specified year.</returns>
484 /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
485 /// The exception is thrown, if
486 /// <paramref name="year"/> is outside the allowed range.
488 public abstract int GetDaysInYear(int year, int era);
491 /// When overridden gives the era of the specified date.
493 /// <param name="time">The
494 /// <see cref="T:System.DateTime"/> that specifies a
497 /// <returns>An integer representing the era of the calendar.
499 public abstract int GetEra(DateTime time);
502 /// Virtual method that gives the hour of the specified time.
504 /// <param name="time">The
505 /// <see cref="T:System.DateTime"/> that specifies the
508 /// <returns>An integer that gives the hour of the specified time,
509 /// starting with 0.</returns>
510 public virtual int GetHour(DateTime time) {
511 return time.TimeOfDay.Hours;
515 /// Virtual method that gives the milliseconds in the current second
516 /// of the specified time.
518 /// <param name="time">The
519 /// <see cref="T:System.DateTime"/> that specifies the
522 /// <returns>An integer that gives the milliseconds in the seconds
523 /// of the specified time, starting with 0.</returns>
524 public virtual double GetMilliseconds(DateTime time) {
525 return time.TimeOfDay.Milliseconds;
529 /// Virtual method that gives the minute of the specified time.
531 /// <param name="time">The
532 /// <see cref="T:System.DateTime"/> that specifies the
535 /// <returns>An integer that gives the minute of the specified time,
536 /// starting with 0.</returns>
537 public virtual int GetMinute(DateTime time) {
538 return time.TimeOfDay.Minutes;
542 /// When overridden gives the number of the month of the specified
545 /// <param name="time">The
546 /// <see cref="T:System.DateTime"/> that specifies a
549 /// <returns>An integer representing the month,
550 /// starting with 1.</returns>
551 public abstract int GetMonth(DateTime time);
554 /// Virtual method that gives the number of months of the specified
555 /// year of the <see cref="M:CurrentEra"/>.
557 /// <param name="year">An integer that specifies the year in the
560 /// <returns>An integer that gives the number of the months in the
561 /// specified year.</returns>
562 /// <exception cref="T:System.ArgumentOutOfRangeException">
563 /// The exception is thrown, if the year is not allowed in the
566 public virtual int GetMonthsInYear(int year) {
567 return GetMonthsInYear(year, CurrentEra);
571 /// When overridden gives the number of months in the specified year
574 /// <param name="year">An integer that specifies the year.
576 /// <param name="era">An integer that specifies the era.
578 /// <returns>An integer that gives the number of the months in the
579 /// specified year.</returns>
580 /// <exception cref="T:System.ArgumentOutOfRangeException">
581 /// The exception is thrown, if the year or the era are not valid.
583 public abstract int GetMonthsInYear(int year, int era);
586 /// Virtual method that gives the second of the specified time.
588 /// <param name="time">The
589 /// <see cref="T:System.DateTime"/> that specifies the
592 /// <returns>An integer that gives the second of the specified time,
593 /// starting with 0.</returns>
594 public virtual int GetSecond(DateTime time) {
595 return time.TimeOfDay.Seconds;
599 /// A protected method to calculate the number of days between two
602 /// <param name="timeA">A <see cref="T:System.DateTime"/>
603 /// representing the first date.
605 /// <param name="timeB">A <see cref="T:System.DateTime"/>
606 /// representing the second date.
608 /// <returns>An integer that represents the difference of days
609 /// between <paramref name="timeA"/> and <paramref name="timeB"/>.
611 internal int M_DiffDays(DateTime timeA, DateTime timeB) {
612 long diff = timeA.Ticks - timeB.Ticks;
615 return (int)(diff/TimeSpan.TicksPerDay);
619 return -1 + (int)(diff/TimeSpan.TicksPerDay);
623 /// A protected method that gives the first day of the second week of
626 /// <param name="year">An integer that represents the year.</param>
627 /// <param name="rule">The
628 /// <see cref="T:System.Globalization.CalendarWeekRule"/>
629 /// to be used for the calculation.
631 /// <param name="firstDayOfWeek">
632 /// The <see cref="T:System.Globalization.DayOfWeek"/>
633 /// specifying the first day in a week.
635 /// <returns>The <see cref="T:System.DateTime"/> representing
636 /// the first day of the second week of the year.
638 internal DateTime M_GetFirstDayOfSecondWeekOfYear(
639 int year, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
641 DateTime d1 = ToDateTime(year, 1, 1, 0, 0, 0, 0);
642 int dow1 = (int)GetDayOfWeek(d1);
643 int fdow = (int)firstDayOfWeek;
647 case CalendarWeekRule.FirstDay:
652 d += fdow + M_DaysInWeek - dow1;
655 case CalendarWeekRule.FirstFullWeek:
661 d += fdow + M_DaysInWeek - dow1;
664 case CalendarWeekRule.FirstFourDayWeek:
665 int dow4 = (dow1 + 3)%M_DaysInWeek;
672 d += fdow + M_DaysInWeek - dow4;
677 return AddDays(d1, d);
681 /// A virtual method that gives the number of the week in the year.
683 /// <param name="time">A
684 /// <see cref="T:System.DateTime"/> representing the date.
686 /// <param name="rule">The
687 /// <see cref="T:System.Globalization.CalendarWeekRule"/>
688 /// to be used for the calculation.
690 /// <param name="firstDayOfWeek">
691 /// The <see cref="T:System.Globalization.DayOfWeek"/>
692 /// specifying the first day in a week.
694 /// <returns>An integer representing the number of the week in the
695 /// year, starting with 1.
697 public virtual int GetWeekOfYear(DateTime time,
698 CalendarWeekRule rule,
699 DayOfWeek firstDayOfWeek)
701 if (firstDayOfWeek < DayOfWeek.Sunday ||
702 DayOfWeek.Saturday < firstDayOfWeek)
704 throw new ArgumentOutOfRangeException("firstDayOfWeek",
705 "Value is not a valid day of week.");
707 int year = GetYear(time);
712 DateTime secondWeek = M_GetFirstDayOfSecondWeekOfYear(
713 year, rule, firstDayOfWeek);
714 days = M_DiffDays(time, secondWeek) + M_DaysInWeek;
720 return 1 + days/M_DaysInWeek;
724 /// When overridden gives the number of the year of the specified
727 /// <param name="time">The
728 /// <see cref="T:System.DateTime"/> that specifies a
731 /// <returns>An integer representing the year,
732 /// starting with 1.</returns>
733 public abstract int GetYear(DateTime time);
736 /// A virtual method that tells whether the given day in the
737 /// <see cref="M:CurrentEra"/> is a leap day.
739 /// <param name="year">An integer that specifies the year in the
742 /// <param name="month">An integer that specifies the month.
744 /// <param name="day">An integer that specifies the day.
746 /// <returns>A boolean that tells whether the given day is a leap
749 /// <exception cref="T:System.ArgumentOutOfRangeException">
750 /// The exception is thrown, if the year, month or day is not valid
753 public virtual bool IsLeapDay(int year, int month, int day) {
754 return IsLeapDay(year, month, day, CurrentEra);
758 /// Tells when overridden whether the given day
761 /// <param name="year">An integer that specifies the year in the
764 /// <param name="month">An integer that specifies the month.
766 /// <param name="day">An integer that specifies the day.
768 /// <param name="era">An integer that specifies the era.
770 /// <returns>A boolean that tells whether the given day is a leap
773 /// <exception cref="T:System.ArgumentOutOfRangeException">
774 /// The exception is thrown, if the year, month, day, or era is not
777 public abstract bool IsLeapDay(int year, int month, int day, int era);
780 /// A virtual method that tells whether the given month of the
781 /// specified year in the
782 /// <see cref="M:CurrentEra"/> is a leap month.
784 /// <param name="year">An integer that specifies the year in the
787 /// <param name="month">An integer that specifies the month.
789 /// <returns>A boolean that tells whether the given month is a leap
792 /// <exception cref="T:System.ArgumentOutOfRangeException">
793 /// The exception is thrown, if the year or month is not valid
796 public virtual bool IsLeapMonth(int year, int month) {
797 return IsLeapMonth(year, month, CurrentEra);
801 /// Tells when overridden whether the given month
804 /// <param name="year">An integer that specifies the year in the
807 /// <param name="month">An integer that specifies the month.
809 /// <param name="era">An integer that specifies the era.
811 /// <returns>A boolean that tells whether the given month is a leap
814 /// <exception cref="T:System.ArgumentOutOfRangeException">
815 /// The exception is thrown, if the year, month, or era is not
818 public abstract bool IsLeapMonth(int year, int month, int era);
821 /// A virtual method that tells whether the given year
823 /// <see cref="M:CurrentEra"/> is a leap year.
825 /// <param name="year">An integer that specifies the year in the
828 /// <returns>A boolean that tells whether the given year is a leap
831 /// <exception cref="T:System.ArgumentOutOfRangeException">
832 /// The exception is thrown, if the year is not valid
835 public virtual bool IsLeapYear(int year) {
836 return IsLeapYear(year, CurrentEra);
840 /// Tells when overridden whether the given year
843 /// <param name="year">An integer that specifies the year in the
846 /// <param name="era">An integer that specifies the era.
848 /// <returns>A boolean that tells whether the given year is a leap
851 /// <exception cref="T:System.ArgumentOutOfRangeException">
852 /// The exception is thrown, if the year or era is not
855 public abstract bool IsLeapYear(int year, int era);
858 /// A virtual method that creates the
859 /// <see cref="T:System.DateTime"/> from the parameters.
861 /// <param name="year">An integer that gives the year in the
862 /// <see cref="M:CurrentEra"/>.
864 /// <param name="month">An integer that specifies the month.
866 /// <param name="day">An integer that specifies the day.
868 /// <param name="hour">An integer that specifies the hour.
870 /// <param name="minute">An integer that specifies the minute.
872 /// <param name="second">An integer that gives the second.
874 /// <param name="milliseconds">An integer that gives the
878 /// <see cref="T:system.DateTime"/> representig the date and time.
880 /// <exception cref="T:System.ArgumentOutOfRangeException">
881 /// The exception is thrown, if at least one of the parameters
884 public virtual DateTime ToDateTime(int year, int month, int day,
885 int hour, int minute, int second, int millisecond)
887 return ToDateTime (year, month, day, hour, minute, second,
888 millisecond, CurrentEra);
893 /// When overridden creates the
894 /// <see cref="T:System.DateTime"/> from the parameters.
896 /// <param name="year">An integer that gives the year in the
897 /// <paramref name="era"/>.
899 /// <param name="month">An integer that specifies the month.
901 /// <param name="day">An integer that specifies the day.
903 /// <param name="hour">An integer that specifies the hour.
905 /// <param name="minute">An integer that specifies the minute.
907 /// <param name="second">An integer that gives the second.
909 /// <param name="milliseconds">An integer that gives the
912 /// <param name="era">An integer that specifies the era.
915 /// <see cref="T:system.DateTime"/> representig the date and time.
917 /// <exception cref="T:System.ArgumentOutOfRangeException">
918 /// The exception is thrown, if at least one of the parameters
921 public abstract DateTime ToDateTime(int year, int month, int day,
922 int hour, int minute, int second, int millisecond,
926 /// A virtual method that converts a two-digit year to a four-digit
927 /// year. It uses the <see cref="M:TwoDigitYearMax"/> property.
929 /// <param name="year">An integer that gives the two-digit year.
931 /// <returns>An integer giving the four digit year.
933 /// <exception cref="T:System.ArgumentOutOfRangeException">
934 /// The exception is thrown if the year is negative or the resulting
937 public virtual int ToFourDigitYear(int year) {
939 throw new ArgumentOutOfRangeException(
940 "year", "Non-negative number required.");
941 /* seems not to be the right thing to do, but .NET is
945 int year2 = TwoDigitYearMax%100;
946 int d = year - year2;
947 year = TwoDigitYearMax + d + (d <= 0 ? 0 : -100);
949 int era = CurrentEra;
950 M_CheckYE(year, ref era);
954 // TwoDigitYearMax: Windows reads it from the Registry, we
955 // should have an XML file with the defaults
957 /// The default constructor, is sets the TwoDigitYearMax to 2029.
960 /// The .NET framework reads the value from the registry.
961 /// We should implement it here. Currently I set the default values
962 /// in the ctors of the derived classes, if it is 99.
964 protected Calendar() {
965 twoDigitYearMax = 99;
968 /// <summary>Protected field storing the abbreviated era names.
971 internal string[] M_AbbrEraNames;
972 /// <summary>Protected field storing the era names.
975 internal string[] M_EraNames;
978 /// The property stores the era names. It might be overwritten by
981 internal string[] AbbreviatedEraNames {
983 if (M_AbbrEraNames == null ||
984 M_AbbrEraNames.Length != Eras.Length)
986 "Internal: M_AbbrEraNames " +
987 "wrong initialized!");
988 return (string[])M_AbbrEraNames.Clone();
992 if (value.Length != Eras.Length) {
993 StringWriter sw = new StringWriter();
994 sw.Write("Array length must be equal Eras " +
995 "length {0}.", Eras.Length);
996 throw new ArgumentException(
999 M_AbbrEraNames = (string[])value.Clone();
1004 /// The property stores the era names. It might be overwritten by
1007 internal string[] EraNames {
1009 if (M_EraNames == null || M_EraNames.Length != Eras.Length)
1010 throw new Exception ("Internal: M_EraNames not initialized!");
1016 if (value.Length != Eras.Length) {
1017 StringWriter sw = new StringWriter();
1018 sw.Write("Array length must be equal Eras " +
1019 "length {0}.", Eras.Length);
1020 throw new ArgumentException(
1023 M_EraNames = (string[])value.Clone();
1027 #pragma warning disable 649
1028 internal int m_currentEraValue; // Unused, by MS serializes this
1029 #pragma warning restore 649