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.
42 public abstract class Calendar
47 /// <value>An protected integer property that gives the number of
48 /// days in a week. It might be overridden.</value>
49 internal virtual int M_DaysInWeek
55 /// The protected method creates the string used in the
56 /// <see cref="T:System.ArgumentOutOfRangeException"/>
58 /// <param name="a">An object that represents the smallest
59 /// allowable value.</param>
60 /// <param name="b">An object that represents the greatest allowable
62 /// <returns>The string used in the
63 /// <see cref="T:System.ArgumentOutOfRangeException"/>
65 internal string M_ValidValues(object a, object b)
67 StringWriter sw = new StringWriter();
68 sw.Write("Valid values are between {0} and {1}, inclusive.",
74 /// The protected method checks wether the parameter
75 /// <paramref name="arg"/> is in the allowed range.
77 /// <param name="param">A string that gives the name of the
78 /// parameter to check.</param>
79 /// <param name="arg">An integer that gives the value to check.
81 /// <param name="a">An integer that represents the smallest allowed
83 /// <param name="b">An integer that represents the greatest allowed
85 /// <exception cref="T:System.ArgumentOutOfRangeException">
86 /// The exception is thrown, if the <paramref name="arg"/> is outside
87 /// the allowed range.
89 internal void M_ArgumentInRange(string param, int arg, int a, int b)
91 if (a <= arg && arg <= b)
93 throw new ArgumentOutOfRangeException(param, M_ValidValues(a, b));
97 /// The protected method, that checks whether
98 /// <paramref name="hour"/>, <paramref name="minute"/>,
99 /// <paramref name="second"/>, and <parameref name="millisecond"/>
100 /// are in their valid ranges
102 /// <param name="hour">An integer that represents a hour,
103 /// should be between 0 and 23.</param>
104 /// <param name="minute">An integer that represents a minute,
105 /// should be between 0 and 59.</param>
106 /// <param name="second">An integer that represents a second,
107 /// should be between 0 and 59.</param>
108 /// <param name="milliseconds">An integer that represents a number
109 /// of milliseconds, should be between 0 and 999999.</param>
110 /// <exception cref="T:System.ArgumentOutOfRangeException">
111 /// The Exception is thrown, if one of the parameter is outside the
112 /// allowed the range.
114 internal void M_CheckHMSM(int hour, int minute, int second,
117 M_ArgumentInRange("hour", hour, 0, 23);
118 M_ArgumentInRange("minute", minute, 0, 59);
119 M_ArgumentInRange("second", second, 0, 59);
120 M_ArgumentInRange("milliseconds", milliseconds, 0, 999999);
124 /// A represantation of the CurrentEra.
126 public const int CurrentEra = 0;
128 /// <value>When overridden gives the eras supported by the
129 /// calendar as an array of integers.
131 public abstract int[] Eras { get; }
137 [System.Runtime.InteropServices.ComVisible(false)]
138 public virtual CalendarAlgorithmType AlgorithmType {
140 return CalendarAlgorithmType.Unknown;
144 [System.Runtime.InteropServices.ComVisible(false)]
145 public virtual DateTime MaxSupportedDateTime {
147 return DateTime.MaxValue;
151 [System.Runtime.InteropServices.ComVisible(false)]
152 public virtual DateTime MinSupportedDateTime {
154 return DateTime.MinValue;
158 // LAMESPEC: huh, why not Calendar but Object?
160 public virtual object Clone ()
162 Calendar c = (Calendar) MemberwiseClone ();
163 c.m_isReadOnly = false;
169 public virtual int GetLeapMonth (int year)
171 throw new NotImplementedException ();
176 public virtual int GetLeapMonth (int year, int era)
178 throw new NotImplementedException ();
184 public bool IsReadOnly {
185 get { return m_isReadOnly; }
189 public static Calendar ReadOnly (Calendar source)
191 if (source.m_isReadOnly)
193 Calendar c = (Calendar) source.Clone ();
194 c.m_isReadOnly = true;
198 internal bool IsReadOnly {
199 get { return false; }
202 internal static Calendar ReadOnly (Calendar source)
208 internal void CheckReadOnly ()
211 throw new InvalidOperationException ("This Calendar is read-only.");
215 /// The protected member stores the value for the
216 /// <see cref="P:TwoDigitYearMax"/>
220 internal int twoDigitYearMax;
224 /// Private field containing the maximum year for the calendar.
227 private int M_MaxYearValue = 0;
230 /// Get-only property returing the maximum allowed year for this
233 internal virtual int M_MaxYear {
235 if (M_MaxYearValue == 0) {
236 M_MaxYearValue = GetYear(DateTime.MaxValue);
238 return M_MaxYearValue;
243 /// Checks whether the year is the era is valid, if era = CurrentEra
244 /// the right value is set.
246 /// <param name="year">The year to check.</param>
247 /// <param name="era">The era to check.</Param>
248 /// <exception cref="T:ArgumentOutOfRangeException">
249 /// The exception will be thrown, if the year is not valid.
251 internal abstract void M_CheckYE(int year, ref int era);
254 /// <para>The property gives the maximum value for years with two
255 /// digits. If the property has the value 2029, than the two-digit
256 /// integer 29 results in the year 2029 and 30 in the
257 /// year 1930.</para>
258 /// <para>It might be overridden.</para>
260 public virtual int TwoDigitYearMax {
261 get { return twoDigitYearMax; }
264 M_ArgumentInRange("year", value, 100, M_MaxYear);
265 int era = CurrentEra;
266 M_CheckYE(value, ref era);
267 twoDigitYearMax = value;
272 /// The virtual method adds days to a given date.
274 /// <param name="time">The
275 /// <see cref="T:System.DateTime"/> to which to add
278 /// <param name="days">The number of days to add.</param>
279 /// <returns>A new <see cref="T:System.DateTime"/> value, that
280 /// results from adding <paramref name="days"/> to the specified
281 /// DateTime.</returns>
282 public virtual DateTime AddDays(DateTime time, int days) {
283 return time.Add(TimeSpan.FromDays(days));
287 /// The virtual method adds hours to a given date.
289 /// <param name="time">The
290 /// <see cref="T:System.DateTime"/> to which to add
293 /// <param name="hours">The number of hours to add.</param>
294 /// <returns>A new <see cref="T:System.DateTime"/> value, that
295 /// results from adding <paramref name="hours"/> to the specified
296 /// DateTime.</returns>
297 public virtual DateTime AddHours(DateTime time, int hours) {
298 return time.Add(TimeSpan.FromHours(hours));
302 /// The virtual method adds milliseconds to a given date.
304 /// <param name="time">The
305 /// <see cref="T:System.DateTime"/> to which to add
308 /// <param name="milliseconds">The number of milliseconds given as
309 /// double to add. Keep in mind the 100 nanosecond resolution of
310 /// <see cref="T:System.DateTime"/>.
312 /// <returns>A new <see cref="T:System.DateTime"/> value, that
313 /// results from adding <paramref name="milliseconds"/> to the specified
314 /// DateTime.</returns>
315 public virtual DateTime AddMilliseconds(DateTime time,
318 return time.Add(TimeSpan.FromMilliseconds(milliseconds));
322 /// The virtual method adds minutes to a given date.
324 /// <param name="time">The
325 /// <see cref="T:System.DateTime"/> to which to add
328 /// <param name="minutes">The number of minutes to add.</param>
329 /// <returns>A new <see cref="T:System.DateTime"/> value, that
330 /// results from adding <paramref name="minutes"/> to the specified
331 /// DateTime.</returns>
332 public virtual DateTime AddMinutes(DateTime time, int minutes) {
333 return time.Add(TimeSpan.FromMinutes(minutes));
337 /// When overrideden adds months to a given date.
339 /// <param name="time">The
340 /// <see cref="T:System.DateTime"/> to which to add
343 /// <param name="months">The number of months to add.</param>
344 /// <returns>A new <see cref="T:System.DateTime"/> value, that
345 /// results from adding <paramref name="months"/> to the specified
346 /// DateTime.</returns>
347 public abstract DateTime AddMonths(DateTime time, int months);
350 /// The virtual method adds seconds to a given date.
352 /// <param name="time">The
353 /// <see cref="T:System.DateTime"/> to which to add
356 /// <param name="seconds">The number of seconds to add.</param>
357 /// <returns>A new <see cref="T:System.DateTime"/> value, that
358 /// results from adding <paramref name="seconds"/> to the specified
359 /// DateTime.</returns>
360 public virtual DateTime AddSeconds(DateTime time, int seconds) {
361 return time.Add(TimeSpan.FromSeconds(seconds));
365 /// A wirtual method that adds weeks to a given date.
367 /// <param name="time">The
368 /// <see cref="T:System.DateTime"/> to which to add
371 /// <param name="weeks">The number of weeks to add.</param>
372 /// <returns>A new <see cref="T:System.DateTime"/> value, that
373 /// results from adding <paramref name="weeks"/> to the specified
374 /// DateTime.</returns>
375 public virtual DateTime AddWeeks(DateTime time, int weeks) {
376 return time.AddDays(weeks * M_DaysInWeek);
380 /// When overrideden adds years to a given date.
382 /// <param name="time">The
383 /// <see cref="T:System.DateTime"/> to which to add
386 /// <param name="years">The number of years to add.</param>
387 /// <returns>A new <see cref="T:System.DateTime"/> value, that
388 /// results from adding <paramref name="years"/> to the specified
389 /// DateTime.</returns>
390 public abstract DateTime AddYears(DateTime time, int years);
393 /// When overriden gets the day of the month from
394 /// <paramref name="time"/>.
396 /// <param name="time">The
397 /// <see cref="T:System.DateTime"/> that specifies a
400 /// <returns>An integer giving the day of months, starting with 1.
402 public abstract int GetDayOfMonth(DateTime time);
405 /// When overriden gets the day of the week from the specified date.
407 /// <param name="time">The
408 /// <see cref="T:System.DateTime"/> that specifies a
411 /// <returns>An integer giving the day of months, starting with 1.
413 public abstract DayOfWeek GetDayOfWeek(DateTime time);
416 /// When overridden gives the number of the day in the year.
418 /// <param name="time">The
419 /// <see cref="T:System.DateTime"/> that specifies a
422 /// <returns>An integer representing the day of the year,
423 /// starting with 1.</returns>
424 public abstract int GetDayOfYear(DateTime time);
427 /// A virtual method that gives the number of days of the specified
428 /// month of the <paramref name="year"/> and the
429 /// <see cref="P:CurrentEra"/>.
431 /// <param name="year">An integer that gives the year in the current
433 /// <param name="month">An integer that gives the month, starting
435 /// <returns>An integer that gives the number of days of the
436 /// specified month.</returns>
437 /// <exception cref="T:System.ArgumentOutOfRangeException">
438 /// The exception is thrown, if <paramref name="month"/> or
439 /// <paramref name="year"/> is outside the allowed range.
441 public virtual int GetDaysInMonth(int year, int month) {
442 return GetDaysInMonth(year, month, CurrentEra);
446 /// When overridden gives the number of days in the specified month
447 /// of the given year and era.
449 /// <param name="year">An integer that gives the year.
451 /// <param name="month">An integer that gives the month, starting
453 /// <param name="era">An intger that gives the era of the specified
455 /// <returns>An integer that gives the number of days of the
456 /// specified month.</returns>
457 /// <exception cref="T:System.ArgumentOutOfRangeException">
458 /// The exception is thrown, if <paramref name="month"/>,
459 /// <paramref name="year"/> ,or <paramref name="era"/> is outside
460 /// the allowed range.
462 public abstract int GetDaysInMonth(int year, int month, int era);
465 /// A virtual method that gives the number of days of the specified
466 /// year of the <see cref="P:CurrentEra"/>.
468 /// <param name="year">An integer that gives the year in the current
470 /// <returns>An integer that gives the number of days of the
471 /// specified year.</returns>
472 /// <exception cref="T:System.ArgumentOutOfRangeException">
473 /// The exception is thrown, if
474 /// <paramref name="year"/> is outside the allowed range.
476 public virtual int GetDaysInYear(int year) {
477 return GetDaysInYear(year, CurrentEra);
481 /// When overridden gives the number of days of the specified
482 /// year of the given era..
484 /// <param name="year">An integer that specifies the year.
486 /// <param name="era">An ineger that specifies the era.
488 /// <returns>An integer that gives the number of days of the
489 /// specified year.</returns>
490 /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
491 /// The exception is thrown, if
492 /// <paramref name="year"/> is outside the allowed range.
494 public abstract int GetDaysInYear(int year, int era);
497 /// When overridden gives the era of the specified date.
499 /// <param name="time">The
500 /// <see cref="T:System.DateTime"/> that specifies a
503 /// <returns>An integer representing the era of the calendar.
505 public abstract int GetEra(DateTime time);
508 /// Virtual method that gives the hour of the specified time.
510 /// <param name="time">The
511 /// <see cref="T:System.DateTime"/> that specifies the
514 /// <returns>An integer that gives the hour of the specified time,
515 /// starting with 0.</returns>
516 public virtual int GetHour(DateTime time) {
517 return time.TimeOfDay.Hours;
521 /// Virtual method that gives the milliseconds in the current second
522 /// of the specified time.
524 /// <param name="time">The
525 /// <see cref="T:System.DateTime"/> that specifies the
528 /// <returns>An integer that gives the milliseconds in the seconds
529 /// of the specified time, starting with 0.</returns>
530 public virtual double GetMilliseconds(DateTime time) {
531 return time.TimeOfDay.Milliseconds;
535 /// Virtual method that gives the minute of the specified time.
537 /// <param name="time">The
538 /// <see cref="T:System.DateTime"/> that specifies the
541 /// <returns>An integer that gives the minute of the specified time,
542 /// starting with 0.</returns>
543 public virtual int GetMinute(DateTime time) {
544 return time.TimeOfDay.Minutes;
548 /// When overridden gives the number of the month of the specified
551 /// <param name="time">The
552 /// <see cref="T:System.DateTime"/> that specifies a
555 /// <returns>An integer representing the month,
556 /// starting with 1.</returns>
557 public abstract int GetMonth(DateTime time);
560 /// Virtual method that gives the number of months of the specified
561 /// year of the <see cref="M:CurrentEra"/>.
563 /// <param name="year">An integer that specifies the year in the
566 /// <returns>An integer that gives the number of the months in the
567 /// specified year.</returns>
568 /// <exception cref="T:System.ArgumentOutOfRangeException">
569 /// The exception is thrown, if the year is not allowed in the
572 public virtual int GetMonthsInYear(int year) {
573 return GetMonthsInYear(year, CurrentEra);
577 /// When overridden gives the number of months in the specified year
580 /// <param name="year">An integer that specifies the year.
582 /// <param name="era">An integer that specifies the era.
584 /// <returns>An integer that gives the number of the months in the
585 /// specified year.</returns>
586 /// <exception cref="T:System.ArgumentOutOfRangeException">
587 /// The exception is thrown, if the year or the era are not valid.
589 public abstract int GetMonthsInYear(int year, int era);
592 /// Virtual method that gives the second of the specified time.
594 /// <param name="time">The
595 /// <see cref="T:System.DateTime"/> that specifies the
598 /// <returns>An integer that gives the second of the specified time,
599 /// starting with 0.</returns>
600 public virtual int GetSecond(DateTime time) {
601 return time.TimeOfDay.Seconds;
605 /// A protected method to calculate the number of days between two
608 /// <param name="timeA">A <see cref="T:System.DateTime"/>
609 /// representing the first date.
611 /// <param name="timeB">A <see cref="T:System.DateTime"/>
612 /// representing the second date.
614 /// <returns>An integer that represents the difference of days
615 /// between <paramref name="timeA"/> and <paramref name="timeB"/>.
617 internal int M_DiffDays(DateTime timeA, DateTime timeB) {
618 long diff = timeA.Ticks - timeB.Ticks;
621 return (int)(diff/TimeSpan.TicksPerDay);
625 return -1 + (int)(diff/TimeSpan.TicksPerDay);
629 /// A protected method that gives the first day of the second week of
632 /// <param name="year">An integer that represents the year.</param>
633 /// <param name="rule">The
634 /// <see cref="T:System.Globalization.CalendarWeekRule"/>
635 /// to be used for the calculation.
637 /// <param name="firstDayOfWeek">
638 /// The <see cref="T:System.Globalization.DayOfWeek"/>
639 /// specifying the first day in a week.
641 /// <returns>The <see cref="T:System.DateTime"/> representing
642 /// the first day of the second week of the year.
644 internal DateTime M_GetFirstDayOfSecondWeekOfYear(
645 int year, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
647 DateTime d1 = ToDateTime(year, 1, 1, 0, 0, 0, 0);
648 int dow1 = (int)GetDayOfWeek(d1);
649 int fdow = (int)firstDayOfWeek;
653 case CalendarWeekRule.FirstDay:
658 d += fdow + M_DaysInWeek - dow1;
661 case CalendarWeekRule.FirstFullWeek:
667 d += fdow + M_DaysInWeek - dow1;
670 case CalendarWeekRule.FirstFourDayWeek:
671 int dow4 = (dow1 + 3)%M_DaysInWeek;
678 d += fdow + M_DaysInWeek - dow4;
683 return AddDays(d1, d);
687 /// A virtual method that gives the number of the week in the year.
689 /// <param name="time">A
690 /// <see cref="T:System.DateTime"/> representing the date.
692 /// <param name="rule">The
693 /// <see cref="T:System.Globalization.CalendarWeekRule"/>
694 /// to be used for the calculation.
696 /// <param name="firstDayOfWeek">
697 /// The <see cref="T:System.Globalization.DayOfWeek"/>
698 /// specifying the first day in a week.
700 /// <returns>An integer representing the number of the week in the
701 /// year, starting with 1.
703 public virtual int GetWeekOfYear(DateTime time,
704 CalendarWeekRule rule,
705 DayOfWeek firstDayOfWeek)
707 if (firstDayOfWeek < DayOfWeek.Sunday ||
708 DayOfWeek.Saturday < firstDayOfWeek)
710 throw new ArgumentOutOfRangeException("firstDayOfWeek",
711 "Value is not a valid day of week.");
713 int year = GetYear(time);
718 DateTime secondWeek = M_GetFirstDayOfSecondWeekOfYear(
719 year, rule, firstDayOfWeek);
720 days = M_DiffDays(time, secondWeek) + M_DaysInWeek;
726 return 1 + days/M_DaysInWeek;
730 /// When overridden gives the number of the year of the specified
733 /// <param name="time">The
734 /// <see cref="T:System.DateTime"/> that specifies a
737 /// <returns>An integer representing the year,
738 /// starting with 1.</returns>
739 public abstract int GetYear(DateTime time);
742 /// A virtual method that tells whether the given day in the
743 /// <see cref="M:CurrentEra"/> is a leap day.
745 /// <param name="year">An integer that specifies the year in the
748 /// <param name="month">An integer that specifies the month.
750 /// <param name="day">An integer that specifies the day.
752 /// <returns>A boolean that tells whether the given day is a leap
755 /// <exception cref="T:System.ArgumentOutOfRangeException">
756 /// The exception is thrown, if the year, month or day is not valid
759 public virtual bool IsLeapDay(int year, int month, int day) {
760 return IsLeapDay(year, month, day, CurrentEra);
764 /// Tells when overridden whether the given day
767 /// <param name="year">An integer that specifies the year in the
770 /// <param name="month">An integer that specifies the month.
772 /// <param name="day">An integer that specifies the day.
774 /// <param name="era">An integer that specifies the era.
776 /// <returns>A boolean that tells whether the given day is a leap
779 /// <exception cref="T:System.ArgumentOutOfRangeException">
780 /// The exception is thrown, if the year, month, day, or era is not
783 public abstract bool IsLeapDay(int year, int month, int day, int era);
786 /// A virtual method that tells whether the given month of the
787 /// specified year in the
788 /// <see cref="M:CurrentEra"/> is a leap month.
790 /// <param name="year">An integer that specifies the year in the
793 /// <param name="month">An integer that specifies the month.
795 /// <returns>A boolean that tells whether the given month is a leap
798 /// <exception cref="T:System.ArgumentOutOfRangeException">
799 /// The exception is thrown, if the year or month is not valid
802 public virtual bool IsLeapMonth(int year, int month) {
803 return IsLeapMonth(year, month, CurrentEra);
807 /// Tells when overridden whether the given month
810 /// <param name="year">An integer that specifies the year in the
813 /// <param name="month">An integer that specifies the month.
815 /// <param name="era">An integer that specifies the era.
817 /// <returns>A boolean that tells whether the given month is a leap
820 /// <exception cref="T:System.ArgumentOutOfRangeException">
821 /// The exception is thrown, if the year, month, or era is not
824 public abstract bool IsLeapMonth(int year, int month, int era);
827 /// A virtual method that tells whether the given year
829 /// <see cref="M:CurrentEra"/> is a leap year.
831 /// <param name="year">An integer that specifies the year in the
834 /// <returns>A boolean that tells whether the given year is a leap
837 /// <exception cref="T:System.ArgumentOutOfRangeException">
838 /// The exception is thrown, if the year is not valid
841 public virtual bool IsLeapYear(int year) {
842 return IsLeapYear(year, CurrentEra);
846 /// Tells when overridden whether the given year
849 /// <param name="year">An integer that specifies the year in the
852 /// <param name="era">An integer that specifies the era.
854 /// <returns>A boolean that tells whether the given year is a leap
857 /// <exception cref="T:System.ArgumentOutOfRangeException">
858 /// The exception is thrown, if the year or era is not
861 public abstract bool IsLeapYear(int year, int era);
864 /// A virtual method that creates the
865 /// <see cref="T:System.DateTime"/> from the parameters.
867 /// <param name="year">An integer that gives the year in the
868 /// <see cref="M:CurrentEra"/>.
870 /// <param name="month">An integer that specifies the month.
872 /// <param name="day">An integer that specifies the day.
874 /// <param name="hour">An integer that specifies the hour.
876 /// <param name="minute">An integer that specifies the minute.
878 /// <param name="second">An integer that gives the second.
880 /// <param name="milliseconds">An integer that gives the
884 /// <see cref="T:system.DateTime"/> representig the date and time.
886 /// <exception cref="T:System.ArgumentOutOfRangeException">
887 /// The exception is thrown, if at least one of the parameters
890 public virtual DateTime ToDateTime(int year, int month, int day,
891 int hour, int minute, int second, int milliseconds)
893 return ToDateTime(year, month, day, hour, minute, second,
894 milliseconds, CurrentEra);
899 /// When overridden creates the
900 /// <see cref="T:System.DateTime"/> from the parameters.
902 /// <param name="year">An integer that gives the year in the
903 /// <paramref name="era"/>.
905 /// <param name="month">An integer that specifies the month.
907 /// <param name="day">An integer that specifies the day.
909 /// <param name="hour">An integer that specifies the hour.
911 /// <param name="minute">An integer that specifies the minute.
913 /// <param name="second">An integer that gives the second.
915 /// <param name="milliseconds">An integer that gives the
918 /// <param name="era">An integer that specifies the era.
921 /// <see cref="T:system.DateTime"/> representig the date and time.
923 /// <exception cref="T:System.ArgumentOutOfRangeException">
924 /// The exception is thrown, if at least one of the parameters
927 public abstract DateTime ToDateTime(int year, int month, int day,
928 int hour, int minute, int second, int milliseconds,
932 /// A virtual method that converts a two-digit year to a four-digit
933 /// year. It uses the <see cref="M:TwoDigitYearMax"/> property.
935 /// <param name="year">An integer that gives the two-digit year.
937 /// <returns>An integer giving the four digit year.
939 /// <exception cref="T:System.ArgumentOutOfRangeException">
940 /// The exception is thrown if the year is negative or the resulting
943 public virtual int ToFourDigitYear(int year) {
945 throw new ArgumentOutOfRangeException(
946 "year", "Non-negative number required.");
947 /* seems not to be the right thing to do, but .NET is
951 int year2 = TwoDigitYearMax%100;
952 int d = year - year2;
953 year = TwoDigitYearMax + d + (d <= 0 ? 0 : -100);
955 int era = CurrentEra;
956 M_CheckYE(year, ref era);
960 // TwoDigitYearMax: Windows reads it from the Registry, we
961 // should have an XML file with the defaults
963 /// The default constructor, is sets the TwoDigitYearMax to 2029.
966 /// The .NET framework reads the value from the registry.
967 /// We should implement it here. Currently I set the default values
968 /// in the ctors of the derived classes, if it is 99.
970 protected Calendar() {
971 twoDigitYearMax = 99;
974 /// <summary>Protected field storing the abbreviated era names.
977 internal string[] M_AbbrEraNames;
978 /// <summary>Protected field storing the era names.
981 internal string[] M_EraNames;
984 /// The property stores the era names. It might be overwritten by
987 internal string[] AbbreviatedEraNames {
989 if (M_AbbrEraNames == null ||
990 M_AbbrEraNames.Length != Eras.Length)
992 "Internal: M_AbbrEraNames " +
993 "wrong initialized!");
994 return (string[])M_AbbrEraNames.Clone();
998 if (value.Length != Eras.Length) {
999 StringWriter sw = new StringWriter();
1000 sw.Write("Array length must be equal Eras " +
1001 "length {0}.", Eras.Length);
1002 throw new ArgumentException(
1005 M_AbbrEraNames = (string[])value.Clone();
1010 /// The property stores the era names. It might be overwritten by
1013 internal string[] EraNames {
1015 if (M_EraNames == null ||
1016 M_EraNames.Length != Eras.Length)
1017 throw new Exception(
1018 "Internal: M_EraNames " +
1019 "not initialized!");
1020 return (string[])M_EraNames.Clone();
1024 if (value.Length != Eras.Length) {
1025 StringWriter sw = new StringWriter();
1026 sw.Write("Array length must be equal Eras " +
1027 "length {0}.", Eras.Length);
1028 throw new ArgumentException(
1031 M_EraNames = (string[])value.Clone();
1036 internal int m_currentEraValue; // Unused, by MS serializes this
1041 } // namespace System.Globalization