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