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