2006-03-02 Peter Dennis Bartok <pbartok@novell.com>
[mono.git] / mcs / class / corlib / System.Globalization / GregorianCalendar.cs
1 // GregorianCalendar.cs
2 //
3 // (C) Ulrich Kunitz 2002
4 //
5
6 //
7 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 namespace System.Globalization {
30
31 using System;
32
33 /// <summary>
34 /// This is the Gregorian calendar.
35 /// </summary>
36 /// <remarks>
37 /// <para>The Gregorian calendar supports only the Common Era from
38 /// the Gregorian year 1 to the Gregorian year 9999.
39 /// </para>
40 /// <para>The implementation uses the
41 /// <see cref="N:CalendricalCalculations"/> namespace.
42 /// </para>
43 /// </remarks>
44 [Serializable]
45 [MonoTODO ("Fix serialization compatibility with MS.NET")]
46 public class GregorianCalendar : Calendar {
47         /// <summary>
48         /// The era number for the Common Era (C.E.) or Anno Domini (A.D.)
49         /// respective.
50         /// </summary>
51         public const int ADEra = 1;
52
53         /// <value>Overridden. Gives the eras supported by the Gregorian
54         /// calendar as an array of integers.
55         /// </value>
56         public override int[] Eras {
57                 get {
58                         return new int[] { ADEra }; 
59                 }
60         }
61
62         [NonSerialized]
63         int twoDigitYearMax = 2029;
64
65         public override int TwoDigitYearMax 
66         {
67                 get {
68                         return twoDigitYearMax;
69                 }
70                 set {
71                         CheckReadOnly ();
72                         M_ArgumentInRange ("value", value, 100, M_MaxYear);
73
74                         twoDigitYearMax = value;
75                 }
76         }
77
78         /// <summary>
79         /// A protected member storing the
80         /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>.
81         /// </summary>
82         [NonSerialized]
83         internal GregorianCalendarTypes M_CalendarType;
84
85         /// <value>
86         /// The property stores the 
87         /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>.
88         /// </value>
89         public virtual GregorianCalendarTypes CalendarType {
90                 get { return M_CalendarType; }
91                 set { 
92                         CheckReadOnly ();
93                         // mscorlib 1:0:3300:0 doesn't check anything here
94                         M_CalendarType = value;
95                 }
96         }
97
98         /// <summary>
99         /// A protected method checking the era number.
100         /// </summary>
101         /// <param name="era">The era number.</param>
102         /// <exception name="T:System.ArgumentException">
103         /// The exception is thrown if the era is not equal
104         /// <see cref="M:ADEra"/>.
105         /// </exception>
106         internal void M_CheckEra(ref int era) {
107                 if (era == CurrentEra)
108                         era = ADEra;
109                 if (era != ADEra)
110                         throw new ArgumentException("Era value was not valid.");
111         }
112
113         /// <summary>
114         /// A protected method checking calendar year and the era number.
115         /// </summary>
116         /// <param name="year">An integer representing the calendar year.
117         /// </param>
118         /// <param name="era">The era number.</param>
119         /// <exception cref="T:System.ArgumentException">
120         /// The exception is thrown if the era is not equal
121         /// <see cref="M:ADEra"/>.
122         /// </exception>
123         /// <exception cref="T:System.ArgumentOutOfRangeException">
124         /// The exception is thrown if the calendar year is outside of
125         /// the allowed range.
126         /// </exception>
127         internal override void M_CheckYE(int year, ref int era) {
128                 M_CheckEra(ref era);
129                 M_ArgumentInRange("year", year, 1, 9999);
130         }
131
132         /// <summary>
133         /// A protected method checking the calendar year, month, and
134         /// era number.
135         /// </summary>
136         /// <param name="year">An integer representing the calendar year.
137         /// </param>
138         /// <param name="month">An integer giving the calendar month.
139         /// </param>
140         /// <param name="era">The era number.</param>
141         /// <exception cref="T:System.ArgumentException">
142         /// The exception is thrown if the era is not equal
143         /// <see cref="M:ADEra"/>.
144         /// </exception>
145         /// <exception cref="T:System.ArgumentOutOfRangeException">
146         /// The exception is thrown if the calendar year or month is
147         /// outside of the allowed range.
148         /// </exception>
149         internal void M_CheckYME(int year, int month, ref int era) {
150                 M_CheckYE(year, ref era);
151                 if (month < 1 || month > 12)
152                         throw new ArgumentOutOfRangeException("month",
153                                 "Month must be between one and twelve.");
154         }
155
156         /// <summary>
157         /// A protected method checking the calendar day, month, and year
158         /// and the era number.
159         /// </summary>
160         /// <param name="year">An integer representing the calendar year.
161         /// </param>
162         /// <param name="month">An integer giving the calendar month.
163         /// </param>
164         /// <param name="day">An integer giving the calendar day.
165         /// </param>
166         /// <param name="era">The era number.</param>
167         /// <exception cref="T:System.ArgumentException">
168         /// The exception is thrown if the era is not equal
169         /// <see cref="M:ADEra"/>.
170         /// </exception>
171         /// <exception cref="T:System.ArgumentOutOfRangeException">
172         /// The exception is thrown if the calendar year, month, or day is
173         /// outside of the allowed range.
174         /// </exception>
175         internal void M_CheckYMDE(int year, int month, int day, ref int era)
176         {
177                 M_CheckYME(year, month, ref era);
178                 M_ArgumentInRange("day", day, 1,
179                         GetDaysInMonth(year, month, era));
180         }
181
182         /// <summary>
183         /// Overridden. Adds months to a given date.
184         /// </summary>
185         /// <param name="time">The
186         /// <see cref="T:System.DateTime"/> to which to add
187         /// months.
188         /// </param>
189         /// <param name="months">The number of months to add.</param>
190         /// <returns>A new <see cref="T:System.DateTime"/> value, that
191         /// results from adding <paramref name="months"/> to the specified
192         /// DateTime.</returns>
193         public override DateTime AddMonths(DateTime time, int months) {
194                 return CCGregorianCalendar.AddMonths(time, months);
195         }
196
197         /// <summary>
198         /// Overridden. Adds years to a given date.
199         /// </summary>
200         /// <param name="time">The
201         /// <see cref="T:System.DateTime"/> to which to add
202         /// years.
203         /// </param>
204         /// <param name="years">The number of years to add.</param>
205         /// <returns>A new <see cref="T:System.DateTime"/> value, that
206         /// results from adding <paramref name="years"/> to the specified
207         /// DateTime.</returns>
208         public override DateTime AddYears(DateTime time, int years) {
209                 return CCGregorianCalendar.AddYears(time, years);
210         }
211                 
212         /// <summary>
213         /// Overridden. Gets the day of the month from
214         /// <paramref name="time"/>.
215         /// </summary>
216         /// <param name="time">The
217         /// <see cref="T:System.DateTime"/> that specifies a
218         /// date.
219         /// </param>
220         /// <returns>An integer giving the day of months, starting with 1.
221         /// </returns>
222         public override int GetDayOfMonth(DateTime time) {
223                 return CCGregorianCalendar.GetDayOfMonth(time);
224         }
225
226         /// <summary>
227         /// Overridden. Gets the day of the week from the specified date.
228         /// </summary>
229         /// <param name="time">The
230         /// <see cref="T:System.DateTime"/> that specifies a
231         /// date.
232         /// </param>
233         /// <returns>An integer giving the day of months, starting with 1.
234         /// </returns>
235         public override DayOfWeek GetDayOfWeek(DateTime time) {
236                 int rd = CCFixed.FromDateTime(time);
237                 return (DayOfWeek)CCFixed.day_of_week(rd);
238         }
239
240         /// <summary>
241         /// Overridden. Gives the number of the day in the year.
242         /// </summary>
243         /// <param name="time">The
244         /// <see cref="T:System.DateTime"/> that specifies a
245         /// date.
246         /// </param>
247         /// <returns>An integer representing the day of the year,
248         /// starting with 1.</returns>
249         public override int GetDayOfYear(DateTime time) {
250                 return CCGregorianCalendar.GetDayOfYear(time);
251         }
252
253         /// <summary>
254         /// Overridden. Gives the number of days in the specified month
255         /// of the given year and era.
256         /// </summary>
257         /// <param name="year">An integer that gives the year.
258         /// </param>
259         /// <param name="month">An integer that gives the month, starting
260         /// with 1.</param>
261         /// <param name="era">An intger that gives the era of the specified
262         /// year.</param>
263         /// <returns>An integer that gives the number of days of the
264         /// specified month.</returns>
265         /// <exception cref="T:System.ArgumentOutOfRangeException">
266         /// The exception is thrown, if <paramref name="month"/>,
267         /// <paramref name="year"/> ,or <paramref name="era"/> is outside
268         /// the allowed range.
269         /// </exception>
270         public override int GetDaysInMonth(int year, int month, int era) {
271                 // mscorlib doesn't check year, probably a bug; we do
272                 M_CheckYME(year, month, ref era);
273                 return CCGregorianCalendar.GetDaysInMonth(year, month);
274         }
275
276         /// <summary>
277         /// Overridden. Gives the number of days of the specified
278         /// year of the given era. 
279         /// </summary>
280         /// <param name="year">An integer that specifies the year. 
281         /// </param>
282         /// <param name="era">An ineger that specifies the era.
283         /// </param>
284         /// <returns>An integer that gives the number of days of the
285         /// specified year.</returns>
286         /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
287         /// The exception is thrown, if
288         /// <paramref name="year"/> is outside the allowed range.
289         /// </exception>
290         public override int GetDaysInYear(int year, int era) {
291                 M_CheckYE(year, ref era);
292                 return CCGregorianCalendar.GetDaysInYear(year);
293         }
294                 
295
296         /// <summary>
297         /// Overridden. Gives the era of the specified date.
298         /// </summary>
299         /// <param name="time">The
300         /// <see cref="T:System.DateTime"/> that specifies a
301         /// date.
302         /// </param>
303         /// <returns>An integer representing the era of the calendar.
304         /// </returns>
305         public override int GetEra(DateTime time) {
306                 return ADEra;
307         }
308
309         /// <summary>
310         /// Overridden. Gives the number of the month of the specified
311         /// date.
312         /// </summary>
313         /// <param name="time">The
314         /// <see cref="T:System.DateTime"/> that specifies a
315         /// date.
316         /// </param>
317         /// <returns>An integer representing the month, 
318         /// starting with 1.</returns>
319         public override int GetMonth(DateTime time) {
320                 return CCGregorianCalendar.GetMonth(time);
321         }
322
323         /// <summary>
324         /// Overridden. Gives the number of months in the specified year 
325         /// and era.
326         /// </summary>
327         /// <param name="year">An integer that specifies the year.
328         /// </param>
329         /// <param name="era">An integer that specifies the era.
330         /// </param>
331         /// <returns>An integer that gives the number of the months in the
332         /// specified year.</returns>
333         /// <exception cref="T:System.ArgumentOutOfRangeException">
334         /// The exception is thrown, if the year or the era are not valid.
335         /// </exception>
336         public override int GetMonthsInYear(int year, int era) {
337                 M_CheckYE(year, ref era);
338                 return 12;
339         }
340
341         /// <summary>
342         /// Overridden. Gives the number of the year of the specified
343         /// date.
344         /// </summary>
345         /// <param name="time">The
346         /// <see cref="T:System.DateTime"/> that specifies a
347         /// date.
348         /// </param>
349         /// <returns>An integer representing the year, 
350         /// starting with 1.</returns>
351         public override int GetYear(DateTime time) {
352                 return CCGregorianCalendar.GetYear(time);
353         }
354
355         /// <summary>
356         /// Overridden. Tells whether the given day 
357         /// is a leap day.
358         /// </summary>
359         /// <param name="year">An integer that specifies the year in the
360         /// given era.
361         /// </param>
362         /// <param name="month">An integer that specifies the month.
363         /// </param>
364         /// <param name="day">An integer that specifies the day.
365         /// </param>
366         /// <param name="era">An integer that specifies the era.
367         /// </param>
368         /// <returns>A boolean that tells whether the given day is a leap
369         /// day.
370         /// </returns>
371         /// <exception cref="T:System.ArgumentOutOfRangeException">
372         /// The exception is thrown, if the year, month, day, or era is not
373         /// valid.
374         /// </exception>
375         public override bool IsLeapDay(int year, int month, int day, int era)
376         {
377                 M_CheckYMDE(year, month, day, ref era);
378                 return CCGregorianCalendar.IsLeapDay(year, month, day);
379         }
380
381
382         /// <summary>
383         /// Overridden. Tells whether the given month 
384         /// is a leap month.
385         /// </summary>
386         /// <param name="year">An integer that specifies the year in the
387         /// given era.
388         /// </param>
389         /// <param name="month">An integer that specifies the month.
390         /// </param>
391         /// <param name="era">An integer that specifies the era.
392         /// </param>
393         /// <returns>A boolean that tells whether the given month is a leap
394         /// month.
395         /// </returns>
396         /// <exception cref="T:System.ArgumentOutOfRangeException">
397         /// The exception is thrown, if the year, month, or era is not
398         /// valid.
399         /// </exception>
400         public override bool IsLeapMonth(int year, int month, int era) {
401                 M_CheckYME(year, month, ref era);
402                 return false;
403         }
404
405         /// <summary>
406         /// Overridden. Tells whether the given year
407         /// is a leap year.
408         /// </summary>
409         /// <param name="year">An integer that specifies the year in the
410         /// given era.
411         /// </param>
412         /// <param name="era">An integer that specifies the era.
413         /// </param>
414         /// <returns>A boolean that tells whether the given year is a leap
415         /// year.
416         /// </returns>
417         /// <exception cref="T:System.ArgumentOutOfRangeException">
418         /// The exception is thrown, if the year or era is not
419         /// valid.
420         /// </exception>
421         public override bool IsLeapYear(int year, int era) {
422                 M_CheckYE(year, ref era);
423                 return CCGregorianCalendar.is_leap_year(year);
424         }
425
426         /// <summary>
427         /// Overridden. Creates the
428         /// <see cref="T:System.DateTime"/> from the parameters.
429         /// </summary>
430         /// <param name="year">An integer that gives the year in the
431         /// <paramref name="era"/>.
432         /// </param>
433         /// <param name="month">An integer that specifies the month.
434         /// </param>
435         /// <param name="day">An integer that specifies the day.
436         /// </param>
437         /// <param name="hour">An integer that specifies the hour.
438         /// </param>
439         /// <param name="minute">An integer that specifies the minute.
440         /// </param>
441         /// <param name="second">An integer that gives the second.
442         /// </param>
443         /// <param name="milliseconds">An integer that gives the
444         /// milliseconds.
445         /// </param>
446         /// <param name="era">An integer that specifies the era.
447         /// </param>
448         /// <returns>
449         /// <see cref="T:system.DateTime"/> representig the date and time.
450         /// </returns>
451         /// <exception cref="T:System.ArgumentOutOfRangeException">
452         /// The exception is thrown, if at least one of the parameters
453         /// is out of range.
454         /// </exception>
455         public override DateTime ToDateTime(int year, int month, int day,
456                 int hour, int minute, int second, int milliseconds,
457                 int era)
458         {
459                 M_CheckYMDE(year, month, day, ref era);
460                 M_CheckHMSM(hour, minute, second, milliseconds);
461                 return CCGregorianCalendar.ToDateTime(
462                         year, month, day,
463                         hour, minute, second, milliseconds);
464         }
465
466         [MonoTODO]
467         public override int ToFourDigitYear(int year)
468         {
469                 throw new NotImplementedException();
470         }
471                                         
472         /// <summary>
473         /// Constructor that sets the
474         /// Gregorian calendar type (
475         /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>).
476         /// </summary>
477         /// <param name="type">The parameter specifies the Gregorian 
478         /// calendar type.
479         /// </param>
480         public GregorianCalendar(GregorianCalendarTypes type) {
481                 CalendarType = type;
482                 M_AbbrEraNames = new string[] {"C.E."};
483                 M_EraNames = new string[] {"Common Era"};
484                 if (M_TwoDigitYearMax == 99)
485                         M_TwoDigitYearMax = 2029;
486         }
487         
488 #if NET_2_0
489         public override CalendarAlgorithmType AlgorithmType {
490                 get {
491                         return CalendarAlgorithmType.SolarCalendar;
492                 }
493         }
494
495         static DateTime Min = new DateTime (1, 1, 1, 0, 0, 0);
496         static DateTime Max = new DateTime (9999, 12, 31, 11, 59, 59);
497                 
498         public override DateTime MinSupportedDateTime {
499                 get {
500                         return Min;
501                 }
502         }
503
504         public override DateTime MaxSupportedDateTime {
505                 get {
506                         return Max;
507                 }
508         }
509 #endif
510         
511         /// <summary>
512         /// Default constructor. Sets the Gregorian calendar type to 
513         /// <see
514         /// cref="F:System.Globalization.GregorianCalendarTypes.Localized"/>.
515         /// </summary>
516         public GregorianCalendar() : this(GregorianCalendarTypes.Localized) {}
517 } // class GregorianCalendar
518         
519 } // namespace System.Globalization