2004-04-30 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / corlib / System.Globalization / GregorianCalendar.cs
1 // GregorianCalendar.cs
2 //
3 // (C) Ulrich Kunitz 2002
4 //
5
6 namespace System.Globalization {
7
8 using System;
9
10 /// <summary>
11 /// This is the Gregorian calendar.
12 /// </summary>
13 /// <remarks>
14 /// <para>The Gregorian calendar supports only the Common Era from
15 /// the Gregorian year 1 to the Gregorian year 9999.
16 /// </para>
17 /// <para>The implementation uses the
18 /// <see cref="N:CalendricalCalculations"/> namespace.
19 /// </para>
20 /// </remarks>
21 [Serializable]
22 public class GregorianCalendar : Calendar {
23         /// <summary>
24         /// The era number for the Common Era (C.E.) or Anno Domini (A.D.)
25         /// respective.
26         /// </summary>
27         public const int ADEra = 1;
28
29         /// <value>Overridden. Gives the eras supported by the Gregorian
30         /// calendar as an array of integers.
31         /// </value>
32         public override int[] Eras {
33                 get {
34                         return new int[] { ADEra }; 
35                 }
36         }
37
38         int twoDigitYearMax = 2029;
39
40         public override int TwoDigitYearMax 
41         {
42                 get {
43                         return twoDigitYearMax;
44                 }
45                 set {
46                         M_ArgumentInRange ("value", value, 100, M_MaxYear);
47
48                         twoDigitYearMax = value;
49                 }
50         }
51
52         /// <summary>
53         /// A protected member storing the
54         /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>.
55         /// </summary>
56         internal GregorianCalendarTypes M_CalendarType;
57
58         /// <value>
59         /// The property stores the 
60         /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>.
61         /// </value>
62         public virtual GregorianCalendarTypes CalendarType {
63                 get { return M_CalendarType; }
64                 set { 
65                         // mscorlib 1:0:33000:0 doesn't check anything here
66                         M_CalendarType = value;
67                 }
68         }
69
70         /// <summary>
71         /// A protected method checking the era number.
72         /// </summary>
73         /// <param name="era">The era number.</param>
74         /// <exception name="T:System.ArgumentException">
75         /// The exception is thrown if the era is not equal
76         /// <see cref="M:ADEra"/>.
77         /// </exception>
78         internal void M_CheckEra(ref int era) {
79                 if (era == CurrentEra)
80                         era = ADEra;
81                 if (era != ADEra)
82                         throw new ArgumentException("Era value was not valid.");
83         }
84
85         /// <summary>
86         /// A protected method checking calendar year and the era number.
87         /// </summary>
88         /// <param name="year">An integer representing the calendar year.
89         /// </param>
90         /// <param name="era">The era number.</param>
91         /// <exception cref="T:System.ArgumentException">
92         /// The exception is thrown if the era is not equal
93         /// <see cref="M:ADEra"/>.
94         /// </exception>
95         /// <exception cref="T:System.ArgumentOutOfRangeException">
96         /// The exception is thrown if the calendar year is outside of
97         /// the allowed range.
98         /// </exception>
99         internal override void M_CheckYE(int year, ref int era) {
100                 M_CheckEra(ref era);
101                 M_ArgumentInRange("year", year, 1, 9999);
102         }
103
104         /// <summary>
105         /// A protected method checking the calendar year, month, and
106         /// era number.
107         /// </summary>
108         /// <param name="year">An integer representing the calendar year.
109         /// </param>
110         /// <param name="month">An integer giving the calendar month.
111         /// </param>
112         /// <param name="era">The era number.</param>
113         /// <exception cref="T:System.ArgumentException">
114         /// The exception is thrown if the era is not equal
115         /// <see cref="M:ADEra"/>.
116         /// </exception>
117         /// <exception cref="T:System.ArgumentOutOfRangeException">
118         /// The exception is thrown if the calendar year or month is
119         /// outside of the allowed range.
120         /// </exception>
121         internal void M_CheckYME(int year, int month, ref int era) {
122                 M_CheckYE(year, ref era);
123                 if (month < 1 || month > 12)
124                         throw new ArgumentOutOfRangeException("month",
125                                 "Month must be between one and twelve.");
126         }
127
128         /// <summary>
129         /// A protected method checking the calendar day, month, and year
130         /// and the era number.
131         /// </summary>
132         /// <param name="year">An integer representing the calendar year.
133         /// </param>
134         /// <param name="month">An integer giving the calendar month.
135         /// </param>
136         /// <param name="day">An integer giving the calendar day.
137         /// </param>
138         /// <param name="era">The era number.</param>
139         /// <exception cref="T:System.ArgumentException">
140         /// The exception is thrown if the era is not equal
141         /// <see cref="M:ADEra"/>.
142         /// </exception>
143         /// <exception cref="T:System.ArgumentOutOfRangeException">
144         /// The exception is thrown if the calendar year, month, or day is
145         /// outside of the allowed range.
146         /// </exception>
147         internal void M_CheckYMDE(int year, int month, int day, ref int era)
148         {
149                 M_CheckYME(year, month, ref era);
150                 M_ArgumentInRange("day", day, 1,
151                         GetDaysInMonth(year, month, era));
152         }
153
154         /// <summary>
155         /// Overridden. Adds months to a given date.
156         /// </summary>
157         /// <param name="time">The
158         /// <see cref="T:System.DateTime"/> to which to add
159         /// months.
160         /// </param>
161         /// <param name="months">The number of months to add.</param>
162         /// <returns>A new <see cref="T:System.DateTime"/> value, that
163         /// results from adding <paramref name="months"/> to the specified
164         /// DateTime.</returns>
165         public override DateTime AddMonths(DateTime time, int months) {
166                 return CCGregorianCalendar.AddMonths(time, months);
167         }
168
169         [MonoTODO]
170         public override DateTime AddWeeks(DateTime time, int weeks) 
171         {
172                 throw new NotImplementedException();
173         }
174
175         /// <summary>
176         /// Overridden. Adds years to a given date.
177         /// </summary>
178         /// <param name="time">The
179         /// <see cref="T:System.DateTime"/> to which to add
180         /// years.
181         /// </param>
182         /// <param name="years">The number of years to add.</param>
183         /// <returns>A new <see cref="T:System.DateTime"/> value, that
184         /// results from adding <paramref name="years"/> to the specified
185         /// DateTime.</returns>
186         public override DateTime AddYears(DateTime time, int years) {
187                 return CCGregorianCalendar.AddYears(time, years);
188         }
189                 
190         /// <summary>
191         /// Overridden. Gets the day of the month from
192         /// <paramref name="time"/>.
193         /// </summary>
194         /// <param name="time">The
195         /// <see cref="T:System.DateTime"/> that specifies a
196         /// date.
197         /// </param>
198         /// <returns>An integer giving the day of months, starting with 1.
199         /// </returns>
200         public override int GetDayOfMonth(DateTime time) {
201                 return CCGregorianCalendar.GetDayOfMonth(time);
202         }
203
204         /// <summary>
205         /// Overridden. Gets the day of the week from the specified date.
206         /// </summary>
207         /// <param name="time">The
208         /// <see cref="T:System.DateTime"/> that specifies a
209         /// date.
210         /// </param>
211         /// <returns>An integer giving the day of months, starting with 1.
212         /// </returns>
213         public override DayOfWeek GetDayOfWeek(DateTime time) {
214                 int rd = CCFixed.FromDateTime(time);
215                 return (DayOfWeek)CCFixed.day_of_week(rd);
216         }
217
218         /// <summary>
219         /// Overridden. Gives the number of the day in the year.
220         /// </summary>
221         /// <param name="time">The
222         /// <see cref="T:System.DateTime"/> that specifies a
223         /// date.
224         /// </param>
225         /// <returns>An integer representing the day of the year,
226         /// starting with 1.</returns>
227         public override int GetDayOfYear(DateTime time) {
228                 return CCGregorianCalendar.GetDayOfYear(time);
229         }
230
231         /// <summary>
232         /// Overridden. Gives the number of days in the specified month
233         /// of the given year and era.
234         /// </summary>
235         /// <param name="year">An integer that gives the year.
236         /// </param>
237         /// <param name="month">An integer that gives the month, starting
238         /// with 1.</param>
239         /// <param name="era">An intger that gives the era of the specified
240         /// year.</param>
241         /// <returns>An integer that gives the number of days of the
242         /// specified month.</returns>
243         /// <exception cref="T:System.ArgumentOutOfRangeException">
244         /// The exception is thrown, if <paramref name="month"/>,
245         /// <paramref name="year"/> ,or <paramref name="era"/> is outside
246         /// the allowed range.
247         /// </exception>
248         public override int GetDaysInMonth(int year, int month, int era) {
249                 // mscorlib doesn't check year, probably a bug; we do
250                 M_CheckYME(year, month, ref era);
251                 return CCGregorianCalendar.GetDaysInMonth(year, month);
252         }
253
254         /// <summary>
255         /// Overridden. Gives the number of days of the specified
256         /// year of the given era. 
257         /// </summary>
258         /// <param name="year">An integer that specifies the year. 
259         /// </param>
260         /// <param name="era">An ineger that specifies the era.
261         /// </param>
262         /// <returns>An integer that gives the number of days of the
263         /// specified year.</returns>
264         /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
265         /// The exception is thrown, if
266         /// <paramref name="year"/> is outside the allowed range.
267         /// </exception>
268         public override int GetDaysInYear(int year, int era) {
269                 M_CheckYE(year, ref era);
270                 return CCGregorianCalendar.GetDaysInYear(year);
271         }
272                 
273
274         /// <summary>
275         /// Overridden. Gives the era of the specified date.
276         /// </summary>
277         /// <param name="time">The
278         /// <see cref="T:System.DateTime"/> that specifies a
279         /// date.
280         /// </param>
281         /// <returns>An integer representing the era of the calendar.
282         /// </returns>
283         public override int GetEra(DateTime time) {
284                 return ADEra;
285         }
286
287         /// <summary>
288         /// Overridden. Gives the number of the month of the specified
289         /// date.
290         /// </summary>
291         /// <param name="time">The
292         /// <see cref="T:System.DateTime"/> that specifies a
293         /// date.
294         /// </param>
295         /// <returns>An integer representing the month, 
296         /// starting with 1.</returns>
297         public override int GetMonth(DateTime time) {
298                 return CCGregorianCalendar.GetMonth(time);
299         }
300
301         /// <summary>
302         /// Overridden. Gives the number of months in the specified year 
303         /// and era.
304         /// </summary>
305         /// <param name="year">An integer that specifies the year.
306         /// </param>
307         /// <param name="era">An integer that specifies the era.
308         /// </param>
309         /// <returns>An integer that gives the number of the months in the
310         /// specified year.</returns>
311         /// <exception cref="T:System.ArgumentOutOfRangeException">
312         /// The exception is thrown, if the year or the era are not valid.
313         /// </exception>
314         public override int GetMonthsInYear(int year, int era) {
315                 M_CheckYE(year, ref era);
316                 return 12;
317         }
318
319         /// <summary>
320         /// Overridden. Gives the number of the year of the specified
321         /// date.
322         /// </summary>
323         /// <param name="time">The
324         /// <see cref="T:System.DateTime"/> that specifies a
325         /// date.
326         /// </param>
327         /// <returns>An integer representing the year, 
328         /// starting with 1.</returns>
329         public override int GetYear(DateTime time) {
330                 return CCGregorianCalendar.GetYear(time);
331         }
332
333         /// <summary>
334         /// Overridden. Tells whether the given day 
335         /// is a leap day.
336         /// </summary>
337         /// <param name="year">An integer that specifies the year in the
338         /// given era.
339         /// </param>
340         /// <param name="month">An integer that specifies the month.
341         /// </param>
342         /// <param name="day">An integer that specifies the day.
343         /// </param>
344         /// <param name="era">An integer that specifies the era.
345         /// </param>
346         /// <returns>A boolean that tells whether the given day is a leap
347         /// day.
348         /// </returns>
349         /// <exception cref="T:System.ArgumentOutOfRangeException">
350         /// The exception is thrown, if the year, month, day, or era is not
351         /// valid.
352         /// </exception>
353         public override bool IsLeapDay(int year, int month, int day, int era)
354         {
355                 M_CheckYMDE(year, month, day, ref era);
356                 return CCGregorianCalendar.IsLeapDay(year, month, day);
357         }
358
359
360         /// <summary>
361         /// Overridden. Tells whether the given month 
362         /// is a leap month.
363         /// </summary>
364         /// <param name="year">An integer that specifies the year in the
365         /// given era.
366         /// </param>
367         /// <param name="month">An integer that specifies the month.
368         /// </param>
369         /// <param name="era">An integer that specifies the era.
370         /// </param>
371         /// <returns>A boolean that tells whether the given month is a leap
372         /// month.
373         /// </returns>
374         /// <exception cref="T:System.ArgumentOutOfRangeException">
375         /// The exception is thrown, if the year, month, or era is not
376         /// valid.
377         /// </exception>
378         public override bool IsLeapMonth(int year, int month, int era) {
379                 M_CheckYME(year, month, ref era);
380                 return false;
381         }
382
383         /// <summary>
384         /// Overridden. Tells whether the given year
385         /// is a leap year.
386         /// </summary>
387         /// <param name="year">An integer that specifies the year in the
388         /// given era.
389         /// </param>
390         /// <param name="era">An integer that specifies the era.
391         /// </param>
392         /// <returns>A boolean that tells whether the given year is a leap
393         /// year.
394         /// </returns>
395         /// <exception cref="T:System.ArgumentOutOfRangeException">
396         /// The exception is thrown, if the year or era is not
397         /// valid.
398         /// </exception>
399         public override bool IsLeapYear(int year, int era) {
400                 M_CheckYE(year, ref era);
401                 return CCGregorianCalendar.is_leap_year(year);
402         }
403
404         /// <summary>
405         /// Overridden. Creates the
406         /// <see cref="T:System.DateTime"/> from the parameters.
407         /// </summary>
408         /// <param name="year">An integer that gives the year in the
409         /// <paramref name="era"/>.
410         /// </param>
411         /// <param name="month">An integer that specifies the month.
412         /// </param>
413         /// <param name="day">An integer that specifies the day.
414         /// </param>
415         /// <param name="hour">An integer that specifies the hour.
416         /// </param>
417         /// <param name="minute">An integer that specifies the minute.
418         /// </param>
419         /// <param name="second">An integer that gives the second.
420         /// </param>
421         /// <param name="milliseconds">An integer that gives the
422         /// milliseconds.
423         /// </param>
424         /// <param name="era">An integer that specifies the era.
425         /// </param>
426         /// <returns>
427         /// <see cref="T:system.DateTime"/> representig the date and time.
428         /// </returns>
429         /// <exception cref="T:System.ArgumentOutOfRangeException">
430         /// The exception is thrown, if at least one of the parameters
431         /// is out of range.
432         /// </exception>
433         public override DateTime ToDateTime(int year, int month, int day,
434                 int hour, int minute, int second, int milliseconds,
435                 int era)
436         {
437                 M_CheckYMDE(year, month, day, ref era);
438                 M_CheckHMSM(hour, minute, second, milliseconds);
439                 return CCGregorianCalendar.ToDateTime(
440                         year, month, day,
441                         hour, minute, second, milliseconds);
442         }
443
444         [MonoTODO]
445         public override int ToFourDigitYear(int year)
446         {
447                 throw new NotImplementedException();
448         }
449                                         
450         /// <summary>
451         /// Constructor that sets the
452         /// Gregorian calendar type (
453         /// <see cref="T:System.Globalization.GregorianCalendarTypes"/>).
454         /// </summary>
455         /// <param name="type">The parameter specifies the Gregorian 
456         /// calendar type.
457         /// </param>
458         public GregorianCalendar(GregorianCalendarTypes type) {
459                 CalendarType = type;
460                 M_AbbrEraNames = new string[] {"C.E."};
461                 M_EraNames = new string[] {"Common Era"};
462                 if (M_TwoDigitYearMax == 99)
463                         M_TwoDigitYearMax = 2029;
464         }
465         
466         /// <summary>
467         /// Default constructor. Sets the Gregorian calendar type to 
468         /// <see
469         /// cref="F:System.Globalization.GregorianCalendarTypes.Localized"/>.
470         /// </summary>
471         public GregorianCalendar() : this(GregorianCalendarTypes.Localized) {}
472 } // class GregorianCalendar
473         
474 } // namespace System.Globalization