3 // System.Globalization.Calendar.cs
5 // Copyright (C) Wictor Wilén 2001 (wictor@iBizkit.se)
7 // Contributors: Marcel Narings, Wictor Wilén
10 // 2001-09-14: First draft
11 // 2001-09-15: First release
20 namespace System.Globalization
23 /// Implmentation of the System.Globalization.Calendar class
25 public abstract class Calendar
28 /// The Calendar Constructor
32 _MaxDateTime = DateTime.MaxValue;
33 _MinDateTime = DateTime.MinValue;
35 protected int _TwoDigitYearMax;
37 protected static int[] _DaysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
38 protected static int[] _DaysInMonthLeap = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
41 // these can be overridden, for example using "new protected const int _MinYear = 1;"
42 protected const int _MinYear = 1;
43 protected const int _MaxYear = 9999;
44 protected const int _MinDay = 0;
45 protected const int _MinMonth = 1;
46 protected const int _MaxMonth = 12;
47 protected const int _MinHour = 0;
48 protected const int _MaxHour = 23;
49 protected const int _MinMinute = 0;
50 protected const int _MaxMinute = 59;
51 protected const int _MinSecond = 0;
52 protected const int _MaxSecond = 59;
53 protected const int _MinMillisecond = 0;
54 protected const int _MaxMillisecond = 999;
56 private const long _TicksPerMillisecond = 10000;
57 private const long _TicksPerSecond = 10000000;
58 private const long _TicksPerMinute = 600000000;
59 private const long _TicksPerHour = 36000000000;
60 private const long _TicksPerDay = 864000000000;
61 private const long _TicksPerWeek = 6048000000000;
63 protected DateTime _MaxDateTime;
64 protected DateTime _MinDateTime;
68 /// The Currentera constant
70 public const int CurrentEra = 0;
73 /// Returns an array of the available eras
75 public abstract int[] Eras {get;}
81 public virtual int TwoDigitYearMax
85 return _TwoDigitYearMax;
89 _TwoDigitYearMax = value;
94 public virtual DateTime AddDays ( DateTime time, int days )
96 return new DateTime(time.Ticks).AddTicks(_TicksPerDay*days);
100 public virtual DateTime AddHours ( DateTime time, int hours )
102 return new DateTime(time.Ticks).AddTicks(_TicksPerHour*hours);
106 public virtual DateTime AddMilliseconds ( DateTime time, double milliseconds )
108 DateTime t = new DateTime(time.Ticks);
109 return t.AddMilliseconds(milliseconds);
113 public virtual DateTime AddMinutes ( DateTime time, int minutes )
115 return new DateTime(time.Ticks).AddTicks(_TicksPerMinute * minutes);
120 /// Returns a DateTime that is the specified number of months away from the specified DateTime
122 /// <param name="time"></param>
123 /// <param name="months"></param>
124 /// <returns></returns>
125 /// <remarks>Calculates correct comapared to .NET Beta 2</remarks>
126 public virtual DateTime AddMonths ( DateTime time, int months )
128 DateTime t = new DateTime(time.Ticks);
129 return t.AddMonths(months);
133 public virtual DateTime AddSeconds ( DateTime time, int seconds )
135 return new DateTime(time.Ticks).AddTicks(_TicksPerSecond * seconds);
139 public virtual DateTime AddWeeks ( DateTime time, int weeks )
141 return new DateTime(time.Ticks).AddTicks(_TicksPerWeek * weeks);
145 public virtual DateTime AddYears ( DateTime time, int years )
147 DateTime t = new DateTime(time.Ticks);
148 return t.AddYears(years);
154 public abstract int GetDayOfMonth ( DateTime time );
157 public abstract DayOfWeek GetDayOfWeek ( DateTime time );
160 public abstract int GetDayOfYear ( DateTime time );
163 public virtual int GetDaysInMonth ( int year, int month )
165 if(year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
166 throw new System.ArgumentOutOfRangeException();
168 if(this.IsLeapYear(year))
169 return _DaysInMonthLeap[month];
171 return _DaysInMonth[month];
175 public abstract int GetDaysInMonth ( int year, int month, int era );
178 public virtual int GetDaysInYear ( int year)
180 if( year < _MinYear || year > _MaxYear)
181 throw new System.ArgumentOutOfRangeException();
183 if(this.IsLeapYear(year))
190 public abstract int GetDaysInYear ( int year, int era );
193 public abstract int GetEra ( DateTime time );
196 public virtual int GetHour ( DateTime time )
201 public virtual double GetMilliseconds ( DateTime time )
203 return time.Millisecond;
206 public virtual int GetMinute ( DateTime time )
212 public abstract int GetMonth ( DateTime time );
215 public virtual int GetMonthsInYear ( int year )
217 if( year < _MinYear || year > _MaxYear)
218 throw new System.ArgumentException();
224 public abstract int GetMonthsInYear ( int year, int era );
227 public virtual int GetSecond ( DateTime time )
234 /// Gets the week of the year that includes the date in the specified DateTime
236 /// <param name="time"></param>
237 /// <param name="rule"></param>
238 /// <param name="firstDayOfWeek"></param>
239 /// <returns></returns>
240 /// <remarks>.NET beta 2 calculates this erroneous, but this one is ok(? I think...)</remarks>
241 public virtual int GetWeekOfYear ( DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek )
243 if( firstDayOfWeek < DayOfWeek.Sunday || firstDayOfWeek > DayOfWeek.Saturday)
244 throw new System.ArgumentOutOfRangeException();
250 if(this.IsLeapYear(time.Year))
251 dim = _DaysInMonthLeap;
255 DateTime jan1 = new DateTime(time.Year, 1, 1);
257 for( int i = 0; i < time.Month-1; i++)
263 case CalendarWeekRule.FirstDay:
264 while(jan1.DayOfWeek != firstDayOfWeek)
267 jan1 = jan1.AddTicks(_TicksPerDay);
270 case CalendarWeekRule.FirstFourDayWeek:
271 while(jan1.DayOfWeek < firstDayOfWeek)
274 jan1 = jan1.AddTicks(_TicksPerDay);
277 case CalendarWeekRule.FirstFullWeek:
278 if(jan1.DayOfWeek != firstDayOfWeek)
283 jan1 = jan1.AddTicks(_TicksPerDay);
285 while(jan1.DayOfWeek != firstDayOfWeek);
289 throw new System.ArgumentOutOfRangeException();
293 week = GetWeekOfYear(new DateTime(time.Year-1,12,31), rule, firstDayOfWeek);
295 week = (--days / 7) + 1;
301 public abstract int GetYear ( DateTime time );
304 // TODO: verify this for the Calendar Class
305 public virtual bool IsLeapDay ( int year, int month, int day )
309 if(day < _MinDay || month < _MinMonth || month > _MaxMonth)
310 throw new System.ArgumentOutOfRangeException();
312 if(this.IsLeapYear(year))
313 dim = _DaysInMonthLeap[month-1];
315 dim = _DaysInMonth[month-1];
318 throw new System.ArgumentOutOfRangeException();
320 if( month == 2 && day == 29)
327 public abstract bool IsLeapDay ( int year, int month, int day, int era );
330 public virtual bool IsLeapMonth ( int year, int month )
332 if( year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
333 throw new System.ArgumentOutOfRangeException();
335 if(this.IsLeapYear(year))
344 public abstract bool IsLeapMonth ( int year, int month, int era );
346 public virtual bool IsLeapYear ( int year )
348 if(year < _MinYear || year > _MaxYear )
349 throw new System.ArgumentOutOfRangeException();
350 if(year % 4 == 0) // TODO: verify this for the Calendar class!
356 public abstract bool IsLeapYear ( int year, int era );
359 public virtual DateTime ToDateTime ( int year, int month, int day, int hour, int minute, int second, int millisecond )
362 dim = GetDaysInMonth(year,month);
363 if( day < _MinDay || day > dim ||
364 hour < _MinHour || hour > _MaxHour ||
365 minute < _MinMinute || minute > _MaxMinute ||
366 second < _MinSecond || second > _MaxSecond ||
367 millisecond < _MinMillisecond || millisecond > _MaxMillisecond)
368 throw new System.ArgumentOutOfRangeException();
370 return new DateTime(year,month,day,hour,minute,second,millisecond,this);
374 public abstract DateTime ToDateTime ( int year, int month, int date, int hour, int minute, int second, int millisecond, int era );
377 public virtual int ToFourDigitYear ( int year )
379 int i = year - ( _TwoDigitYearMax % 100 );
381 return _TwoDigitYearMax - 100 + year;
383 return _TwoDigitYearMax + year;