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 {
35 /// The class serves as a base class for calendar classes.
38 public abstract class Calendar
43 /// <value>An protected integer property that gives the number of
44 /// days in a week. It might be overridden.</value>
45 internal virtual int M_DaysInWeek
51 /// The protected method creates the string used in the
52 /// <see cref="T:System.ArgumentOutOfRangeException"/>
54 /// <param name="a">An object that represents the smallest
55 /// allowable value.</param>
56 /// <param name="b">An object that represents the greatest allowable
58 /// <returns>The string used in the
59 /// <see cref="T:System.ArgumentOutOfRangeException"/>
61 internal string M_ValidValues(object a, object b)
63 StringWriter sw = new StringWriter();
64 sw.Write("Valid values are between {0} and {1}, inclusive.",
70 /// The protected method checks wether the parameter
71 /// <paramref name="arg"/> is in the allowed range.
73 /// <param name="param">A string that gives the name of the
74 /// parameter to check.</param>
75 /// <param name="arg">An integer that gives the value to check.
77 /// <param name="a">An integer that represents the smallest allowed
79 /// <param name="b">An integer that represents the greatest allowed
81 /// <exception cref="T:System.ArgumentOutOfRangeException">
82 /// The exception is thrown, if the <paramref name="arg"/> is outside
83 /// the allowed range.
85 internal void M_ArgumentInRange(string param, int arg, int a, int b)
87 if (a <= arg && arg <= b)
89 throw new ArgumentOutOfRangeException(param, M_ValidValues(a, b));
93 /// The protected method, that checks whether
94 /// <paramref name="hour"/>, <paramref name="minute"/>,
95 /// <paramref name="second"/>, and <parameref name="millisecond"/>
96 /// are in their valid ranges
98 /// <param name="hour">An integer that represents a hour,
99 /// should be between 0 and 23.</param>
100 /// <param name="minute">An integer that represents a minute,
101 /// should be between 0 and 59.</param>
102 /// <param name="second">An integer that represents a second,
103 /// should be between 0 and 59.</param>
104 /// <param name="milliseconds">An integer that represents a number
105 /// of milliseconds, should be between 0 and 999999.</param>
106 /// <exception cref="T:System.ArgumentOutOfRangeException">
107 /// The Exception is thrown, if one of the parameter is outside the
108 /// allowed the range.
110 internal void M_CheckHMSM(int hour, int minute, int second,
113 M_ArgumentInRange("hour", hour, 0, 23);
114 M_ArgumentInRange("minute", minute, 0, 59);
115 M_ArgumentInRange("second", second, 0, 59);
116 M_ArgumentInRange("milliseconds", milliseconds, 0, 999999);
120 /// A represantation of the CurrentEra.
122 public const int CurrentEra = 0;
124 /// <value>When overridden gives the eras supported by the
125 /// calendar as an array of integers.
127 public abstract int[] Eras { get; }
133 [System.Runtime.InteropServices.ComVisible(false)]
134 public virtual CalendarAlgorithmType AlgorithmType {
136 return CalendarAlgorithmType.Unknown;
140 [System.Runtime.InteropServices.ComVisible(false)]
141 public virtual DateTime MaxSupportedDateTime {
143 return DateTime.MaxValue;
147 [System.Runtime.InteropServices.ComVisible(false)]
148 public virtual DateTime MinSupportedDateTime {
150 return DateTime.MinValue;
154 // LAMESPEC: huh, why not Calendar but Object?
155 public virtual object Clone ()
157 Calendar c = (Calendar) MemberwiseClone ();
158 c.is_readonly = false;
164 public bool IsReadOnly {
165 get { return is_readonly; }
168 public static Calendar ReadOnly (Calendar source)
170 if (source.is_readonly)
172 Calendar c = (Calendar) source.Clone ();
173 c.is_readonly = true;
177 internal bool IsReadOnly {
178 get { return false; }
181 internal static Calendar ReadOnly (Calendar source)
187 internal void CheckReadOnly ()
190 throw new InvalidOperationException ("This Calendar is read-only.");
194 /// The protected member stores the value for the
195 /// <see cref="P:TwoDigitYearMax"/>
199 internal int M_TwoDigitYearMax;
203 /// Private field containing the maximum year for the calendar.
206 private int M_MaxYearValue = 0;
209 /// Get-only property returing the maximum allowed year for this
212 internal virtual int M_MaxYear {
214 if (M_MaxYearValue == 0) {
215 M_MaxYearValue = GetYear(DateTime.MaxValue);
217 return M_MaxYearValue;
222 /// Checks whether the year is the era is valid, if era = CurrentEra
223 /// the right value is set.
225 /// <param name="year">The year to check.</param>
226 /// <param name="era">The era to check.</Param>
227 /// <exception cref="T:ArgumentOutOfRangeException">
228 /// The exception will be thrown, if the year is not valid.
230 internal abstract void M_CheckYE(int year, ref int era);
233 /// <para>The property gives the maximum value for years with two
234 /// digits. If the property has the value 2029, than the two-digit
235 /// integer 29 results in the year 2029 and 30 in the
236 /// year 1930.</para>
237 /// <para>It might be overridden.</para>
239 public virtual int TwoDigitYearMax {
240 get { return M_TwoDigitYearMax; }
243 M_ArgumentInRange("year", value, 100, M_MaxYear);
244 int era = CurrentEra;
245 M_CheckYE(value, ref era);
246 M_TwoDigitYearMax = value;
251 /// The virtual method adds days to a given date.
253 /// <param name="time">The
254 /// <see cref="T:System.DateTime"/> to which to add
257 /// <param name="days">The number of days to add.</param>
258 /// <returns>A new <see cref="T:System.DateTime"/> value, that
259 /// results from adding <paramref name="days"/> to the specified
260 /// DateTime.</returns>
261 public virtual DateTime AddDays(DateTime time, int days) {
262 return time.Add(TimeSpan.FromDays(days));
266 /// The virtual method adds hours to a given date.
268 /// <param name="time">The
269 /// <see cref="T:System.DateTime"/> to which to add
272 /// <param name="hours">The number of hours to add.</param>
273 /// <returns>A new <see cref="T:System.DateTime"/> value, that
274 /// results from adding <paramref name="hours"/> to the specified
275 /// DateTime.</returns>
276 public virtual DateTime AddHours(DateTime time, int hours) {
277 return time.Add(TimeSpan.FromHours(hours));
281 /// The virtual method adds milliseconds to a given date.
283 /// <param name="time">The
284 /// <see cref="T:System.DateTime"/> to which to add
287 /// <param name="milliseconds">The number of milliseconds given as
288 /// double to add. Keep in mind the 100 nanosecond resolution of
289 /// <see cref="T:System.DateTime"/>.
291 /// <returns>A new <see cref="T:System.DateTime"/> value, that
292 /// results from adding <paramref name="milliseconds"/> to the specified
293 /// DateTime.</returns>
294 public virtual DateTime AddMilliseconds(DateTime time,
297 return time.Add(TimeSpan.FromMilliseconds(milliseconds));
301 /// The virtual method adds minutes to a given date.
303 /// <param name="time">The
304 /// <see cref="T:System.DateTime"/> to which to add
307 /// <param name="minutes">The number of minutes to add.</param>
308 /// <returns>A new <see cref="T:System.DateTime"/> value, that
309 /// results from adding <paramref name="minutes"/> to the specified
310 /// DateTime.</returns>
311 public virtual DateTime AddMinutes(DateTime time, int minutes) {
312 return time.Add(TimeSpan.FromMinutes(minutes));
316 /// When overrideden adds months to a given date.
318 /// <param name="time">The
319 /// <see cref="T:System.DateTime"/> to which to add
322 /// <param name="months">The number of months to add.</param>
323 /// <returns>A new <see cref="T:System.DateTime"/> value, that
324 /// results from adding <paramref name="months"/> to the specified
325 /// DateTime.</returns>
326 public abstract DateTime AddMonths(DateTime time, int months);
329 /// The virtual method adds seconds to a given date.
331 /// <param name="time">The
332 /// <see cref="T:System.DateTime"/> to which to add
335 /// <param name="seconds">The number of seconds to add.</param>
336 /// <returns>A new <see cref="T:System.DateTime"/> value, that
337 /// results from adding <paramref name="seconds"/> to the specified
338 /// DateTime.</returns>
339 public virtual DateTime AddSeconds(DateTime time, int seconds) {
340 return time.Add(TimeSpan.FromSeconds(seconds));
344 /// A wirtual method that adds weeks to a given date.
346 /// <param name="time">The
347 /// <see cref="T:System.DateTime"/> to which to add
350 /// <param name="weeks">The number of weeks to add.</param>
351 /// <returns>A new <see cref="T:System.DateTime"/> value, that
352 /// results from adding <paramref name="weeks"/> to the specified
353 /// DateTime.</returns>
354 public virtual DateTime AddWeeks(DateTime time, int weeks) {
355 return time.AddDays(weeks * M_DaysInWeek);
359 /// When overrideden adds years to a given date.
361 /// <param name="time">The
362 /// <see cref="T:System.DateTime"/> to which to add
365 /// <param name="years">The number of years to add.</param>
366 /// <returns>A new <see cref="T:System.DateTime"/> value, that
367 /// results from adding <paramref name="years"/> to the specified
368 /// DateTime.</returns>
369 public abstract DateTime AddYears(DateTime time, int years);
372 /// When overriden gets the day of the month from
373 /// <paramref name="time"/>.
375 /// <param name="time">The
376 /// <see cref="T:System.DateTime"/> that specifies a
379 /// <returns>An integer giving the day of months, starting with 1.
381 public abstract int GetDayOfMonth(DateTime time);
384 /// When overriden gets the day of the week from the specified date.
386 /// <param name="time">The
387 /// <see cref="T:System.DateTime"/> that specifies a
390 /// <returns>An integer giving the day of months, starting with 1.
392 public abstract DayOfWeek GetDayOfWeek(DateTime time);
395 /// When overridden gives the number of the day in the year.
397 /// <param name="time">The
398 /// <see cref="T:System.DateTime"/> that specifies a
401 /// <returns>An integer representing the day of the year,
402 /// starting with 1.</returns>
403 public abstract int GetDayOfYear(DateTime time);
406 /// A virtual method that gives the number of days of the specified
407 /// month of the <paramref name="year"/> and the
408 /// <see cref="P:CurrentEra"/>.
410 /// <param name="year">An integer that gives the year in the current
412 /// <param name="month">An integer that gives the month, starting
414 /// <returns>An integer that gives the number of days of the
415 /// specified month.</returns>
416 /// <exception cref="T:System.ArgumentOutOfRangeException">
417 /// The exception is thrown, if <paramref name="month"/> or
418 /// <paramref name="year"/> is outside the allowed range.
420 public virtual int GetDaysInMonth(int year, int month) {
421 return GetDaysInMonth(year, month, CurrentEra);
425 /// When overridden gives the number of days in the specified month
426 /// of the given year and era.
428 /// <param name="year">An integer that gives the year.
430 /// <param name="month">An integer that gives the month, starting
432 /// <param name="era">An intger that gives the era of the specified
434 /// <returns>An integer that gives the number of days of the
435 /// specified month.</returns>
436 /// <exception cref="T:System.ArgumentOutOfRangeException">
437 /// The exception is thrown, if <paramref name="month"/>,
438 /// <paramref name="year"/> ,or <paramref name="era"/> is outside
439 /// the allowed range.
441 public abstract int GetDaysInMonth(int year, int month, int era);
444 /// A virtual method that gives the number of days of the specified
445 /// year of the <see cref="P:CurrentEra"/>.
447 /// <param name="year">An integer that gives the year in the current
449 /// <returns>An integer that gives the number of days of the
450 /// specified year.</returns>
451 /// <exception cref="T:System.ArgumentOutOfRangeException">
452 /// The exception is thrown, if
453 /// <paramref name="year"/> is outside the allowed range.
455 public virtual int GetDaysInYear(int year) {
456 return GetDaysInYear(year, CurrentEra);
460 /// When overridden gives the number of days of the specified
461 /// year of the given era..
463 /// <param name="year">An integer that specifies the year.
465 /// <param name="era">An ineger that specifies the era.
467 /// <returns>An integer that gives the number of days of the
468 /// specified year.</returns>
469 /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
470 /// The exception is thrown, if
471 /// <paramref name="year"/> is outside the allowed range.
473 public abstract int GetDaysInYear(int year, int era);
476 /// When overridden gives the era of the specified date.
478 /// <param name="time">The
479 /// <see cref="T:System.DateTime"/> that specifies a
482 /// <returns>An integer representing the era of the calendar.
484 public abstract int GetEra(DateTime time);
487 /// Virtual method that gives the hour of the specified time.
489 /// <param name="time">The
490 /// <see cref="T:System.DateTime"/> that specifies the
493 /// <returns>An integer that gives the hour of the specified time,
494 /// starting with 0.</returns>
495 public virtual int GetHour(DateTime time) {
496 return time.TimeOfDay.Hours;
500 /// Virtual method that gives the milliseconds in the current second
501 /// of the specified time.
503 /// <param name="time">The
504 /// <see cref="T:System.DateTime"/> that specifies the
507 /// <returns>An integer that gives the milliseconds in the seconds
508 /// of the specified time, starting with 0.</returns>
509 public virtual double GetMilliseconds(DateTime time) {
510 return time.TimeOfDay.Milliseconds;
514 /// Virtual method that gives the minute of the specified time.
516 /// <param name="time">The
517 /// <see cref="T:System.DateTime"/> that specifies the
520 /// <returns>An integer that gives the minute of the specified time,
521 /// starting with 0.</returns>
522 public virtual int GetMinute(DateTime time) {
523 return time.TimeOfDay.Minutes;
527 /// When overridden gives the number of the month of the specified
530 /// <param name="time">The
531 /// <see cref="T:System.DateTime"/> that specifies a
534 /// <returns>An integer representing the month,
535 /// starting with 1.</returns>
536 public abstract int GetMonth(DateTime time);
539 /// Virtual method that gives the number of months of the specified
540 /// year of the <see cref="M:CurrentEra"/>.
542 /// <param name="year">An integer that specifies the year in the
545 /// <returns>An integer that gives the number of the months in the
546 /// specified year.</returns>
547 /// <exception cref="T:System.ArgumentOutOfRangeException">
548 /// The exception is thrown, if the year is not allowed in the
551 public virtual int GetMonthsInYear(int year) {
552 return GetMonthsInYear(year, CurrentEra);
556 /// When overridden gives the number of months in the specified year
559 /// <param name="year">An integer that specifies the year.
561 /// <param name="era">An integer that specifies the era.
563 /// <returns>An integer that gives the number of the months in the
564 /// specified year.</returns>
565 /// <exception cref="T:System.ArgumentOutOfRangeException">
566 /// The exception is thrown, if the year or the era are not valid.
568 public abstract int GetMonthsInYear(int year, int era);
571 /// Virtual method that gives the second of the specified time.
573 /// <param name="time">The
574 /// <see cref="T:System.DateTime"/> that specifies the
577 /// <returns>An integer that gives the second of the specified time,
578 /// starting with 0.</returns>
579 public virtual int GetSecond(DateTime time) {
580 return time.TimeOfDay.Seconds;
584 /// A protected method to calculate the number of days between two
587 /// <param name="timeA">A <see cref="T:System.DateTime"/>
588 /// representing the first date.
590 /// <param name="timeB">A <see cref="T:System.DateTime"/>
591 /// representing the second date.
593 /// <returns>An integer that represents the difference of days
594 /// between <paramref name="timeA"/> and <paramref name="timeB"/>.
596 internal int M_DiffDays(DateTime timeA, DateTime timeB) {
597 long diff = timeA.Ticks - timeB.Ticks;
600 return (int)(diff/TimeSpan.TicksPerDay);
604 return -1 + (int)(diff/TimeSpan.TicksPerDay);
608 /// A protected method that gives the first day of the second week of
611 /// <param name="year">An integer that represents the year.</param>
612 /// <param name="rule">The
613 /// <see cref="T:System.Globalization.CalendarWeekRule"/>
614 /// to be used for the calculation.
616 /// <param name="firstDayOfWeek">
617 /// The <see cref="T:System.Globalization.DayOfWeek"/>
618 /// specifying the first day in a week.
620 /// <returns>The <see cref="T:System.DateTime"/> representing
621 /// the first day of the second week of the year.
623 internal DateTime M_GetFirstDayOfSecondWeekOfYear(
624 int year, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
626 DateTime d1 = ToDateTime(year, 1, 1, 0, 0, 0, 0);
627 int dow1 = (int)GetDayOfWeek(d1);
628 int fdow = (int)firstDayOfWeek;
632 case CalendarWeekRule.FirstDay:
637 d += fdow + M_DaysInWeek - dow1;
640 case CalendarWeekRule.FirstFullWeek:
646 d += fdow + M_DaysInWeek - dow1;
649 case CalendarWeekRule.FirstFourDayWeek:
650 int dow4 = (dow1 + 3)%M_DaysInWeek;
657 d += fdow + M_DaysInWeek - dow4;
662 return AddDays(d1, d);
666 /// A virtual method that gives the number of the week in the year.
668 /// <param name="time">A
669 /// <see cref="T:System.DateTime"/> representing the date.
671 /// <param name="rule">The
672 /// <see cref="T:System.Globalization.CalendarWeekRule"/>
673 /// to be used for the calculation.
675 /// <param name="firstDayOfWeek">
676 /// The <see cref="T:System.Globalization.DayOfWeek"/>
677 /// specifying the first day in a week.
679 /// <returns>An integer representing the number of the week in the
680 /// year, starting with 1.
682 public virtual int GetWeekOfYear(DateTime time,
683 CalendarWeekRule rule,
684 DayOfWeek firstDayOfWeek)
686 if (firstDayOfWeek < DayOfWeek.Sunday ||
687 DayOfWeek.Saturday < firstDayOfWeek)
689 throw new ArgumentOutOfRangeException("firstDayOfWeek",
690 "Value is not a valid day of week.");
692 int year = GetYear(time);
697 DateTime secondWeek = M_GetFirstDayOfSecondWeekOfYear(
698 year, rule, firstDayOfWeek);
699 days = M_DiffDays(time, secondWeek) + M_DaysInWeek;
705 return 1 + days/M_DaysInWeek;
709 /// When overridden gives the number of the year of the specified
712 /// <param name="time">The
713 /// <see cref="T:System.DateTime"/> that specifies a
716 /// <returns>An integer representing the year,
717 /// starting with 1.</returns>
718 public abstract int GetYear(DateTime time);
721 /// A virtual method that tells whether the given day in the
722 /// <see cref="M:CurrentEra"/> is a leap day.
724 /// <param name="year">An integer that specifies the year in the
727 /// <param name="month">An integer that specifies the month.
729 /// <param name="day">An integer that specifies the day.
731 /// <returns>A boolean that tells whether the given day is a leap
734 /// <exception cref="T:System.ArgumentOutOfRangeException">
735 /// The exception is thrown, if the year, month or day is not valid
738 public virtual bool IsLeapDay(int year, int month, int day) {
739 return IsLeapDay(year, month, day, CurrentEra);
743 /// Tells when overridden whether the given day
746 /// <param name="year">An integer that specifies the year in the
749 /// <param name="month">An integer that specifies the month.
751 /// <param name="day">An integer that specifies the day.
753 /// <param name="era">An integer that specifies the era.
755 /// <returns>A boolean that tells whether the given day is a leap
758 /// <exception cref="T:System.ArgumentOutOfRangeException">
759 /// The exception is thrown, if the year, month, day, or era is not
762 public abstract bool IsLeapDay(int year, int month, int day, int era);
765 /// A virtual method that tells whether the given month of the
766 /// specified year in the
767 /// <see cref="M:CurrentEra"/> is a leap month.
769 /// <param name="year">An integer that specifies the year in the
772 /// <param name="month">An integer that specifies the month.
774 /// <returns>A boolean that tells whether the given month is a leap
777 /// <exception cref="T:System.ArgumentOutOfRangeException">
778 /// The exception is thrown, if the year or month is not valid
781 public virtual bool IsLeapMonth(int year, int month) {
782 return IsLeapMonth(year, month, CurrentEra);
786 /// Tells when overridden whether the given month
789 /// <param name="year">An integer that specifies the year in the
792 /// <param name="month">An integer that specifies the month.
794 /// <param name="era">An integer that specifies the era.
796 /// <returns>A boolean that tells whether the given month is a leap
799 /// <exception cref="T:System.ArgumentOutOfRangeException">
800 /// The exception is thrown, if the year, month, or era is not
803 public abstract bool IsLeapMonth(int year, int month, int era);
806 /// A virtual method that tells whether the given year
808 /// <see cref="M:CurrentEra"/> is a leap year.
810 /// <param name="year">An integer that specifies the year in the
813 /// <returns>A boolean that tells whether the given year is a leap
816 /// <exception cref="T:System.ArgumentOutOfRangeException">
817 /// The exception is thrown, if the year is not valid
820 public virtual bool IsLeapYear(int year) {
821 return IsLeapYear(year, CurrentEra);
825 /// Tells when overridden whether the given year
828 /// <param name="year">An integer that specifies the year in the
831 /// <param name="era">An integer that specifies the era.
833 /// <returns>A boolean that tells whether the given year is a leap
836 /// <exception cref="T:System.ArgumentOutOfRangeException">
837 /// The exception is thrown, if the year or era is not
840 public abstract bool IsLeapYear(int year, int era);
843 /// A virtual method that creates the
844 /// <see cref="T:System.DateTime"/> from the parameters.
846 /// <param name="year">An integer that gives the year in the
847 /// <see cref="M:CurrentEra"/>.
849 /// <param name="month">An integer that specifies the month.
851 /// <param name="day">An integer that specifies the day.
853 /// <param name="hour">An integer that specifies the hour.
855 /// <param name="minute">An integer that specifies the minute.
857 /// <param name="second">An integer that gives the second.
859 /// <param name="milliseconds">An integer that gives the
863 /// <see cref="T:system.DateTime"/> representig the date and time.
865 /// <exception cref="T:System.ArgumentOutOfRangeException">
866 /// The exception is thrown, if at least one of the parameters
869 public virtual DateTime ToDateTime(int year, int month, int day,
870 int hour, int minute, int second, int milliseconds)
872 return ToDateTime(year, month, day, hour, minute, second,
873 milliseconds, CurrentEra);
878 /// When overridden creates the
879 /// <see cref="T:System.DateTime"/> from the parameters.
881 /// <param name="year">An integer that gives the year in the
882 /// <paramref name="era"/>.
884 /// <param name="month">An integer that specifies the month.
886 /// <param name="day">An integer that specifies the day.
888 /// <param name="hour">An integer that specifies the hour.
890 /// <param name="minute">An integer that specifies the minute.
892 /// <param name="second">An integer that gives the second.
894 /// <param name="milliseconds">An integer that gives the
897 /// <param name="era">An integer that specifies the era.
900 /// <see cref="T:system.DateTime"/> representig the date and time.
902 /// <exception cref="T:System.ArgumentOutOfRangeException">
903 /// The exception is thrown, if at least one of the parameters
906 public abstract DateTime ToDateTime(int year, int month, int day,
907 int hour, int minute, int second, int milliseconds,
911 /// A virtual method that converts a two-digit year to a four-digit
912 /// year. It uses the <see cref="M:TwoDigitYearMax"/> property.
914 /// <param name="year">An integer that gives the two-digit year.
916 /// <returns>An integer giving the four digit year.
918 /// <exception cref="T:System.ArgumentOutOfRangeException">
919 /// The exception is thrown if the year is negative or the resulting
922 public virtual int ToFourDigitYear(int year) {
924 throw new ArgumentOutOfRangeException(
925 "year", "Non-negative number required.");
926 /* seems not to be the right thing to do, but .NET is
930 int year2 = TwoDigitYearMax%100;
931 int d = year - year2;
932 year = TwoDigitYearMax + d + (d <= 0 ? 0 : -100);
934 int era = CurrentEra;
935 M_CheckYE(year, ref era);
939 // TwoDigitYearMax: Windows reads it from the Registry, we
940 // should have an XML file with the defaults
942 /// The default constructor, is sets the TwoDigitYearMax to 2029.
945 /// The .NET framework reads the value from the registry.
946 /// We should implement it here. Currently I set the default values
947 /// in the ctors of the derived classes, if it is 99.
949 protected Calendar() {
950 M_TwoDigitYearMax = 99;
953 /// <summary>Protected field storing the abbreviated era names.
956 internal string[] M_AbbrEraNames;
957 /// <summary>Protected field storing the era names.
960 internal string[] M_EraNames;
963 /// The property stores the era names. It might be overwritten by
966 internal string[] AbbreviatedEraNames {
968 if (M_AbbrEraNames == null ||
969 M_AbbrEraNames.Length != Eras.Length)
971 "Internal: M_AbbrEraNames " +
972 "wrong initialized!");
973 return (string[])M_AbbrEraNames.Clone();
977 if (value.Length != Eras.Length) {
978 StringWriter sw = new StringWriter();
979 sw.Write("Array length must be equal Eras " +
980 "length {0}.", Eras.Length);
981 throw new ArgumentException(
984 M_AbbrEraNames = (string[])value.Clone();
989 /// The property stores the era names. It might be overwritten by
992 internal string[] EraNames {
994 if (M_EraNames == null ||
995 M_EraNames.Length != Eras.Length)
997 "Internal: M_EraNames " +
999 return (string[])M_EraNames.Clone();
1003 if (value.Length != Eras.Length) {
1004 StringWriter sw = new StringWriter();
1005 sw.Write("Array length must be equal Eras " +
1006 "length {0}.", Eras.Length);
1007 throw new ArgumentException(
1010 M_EraNames = (string[])value.Clone();
1015 } // namespace System.Globalization