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