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