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