Calendar.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. // ::MONO
  2. //
  3. // System.Globalization.Calendar.cs
  4. //
  5. // Copyright (C) Wictor Wilén 2001 ([email protected])
  6. //
  7. // Contributors: Marcel Narings, Wictor Wilén
  8. //
  9. // Revisions
  10. // 2001-09-14: First draft
  11. // 2001-09-15: First release
  12. //
  13. //
  14. // TODO: testing
  15. //
  16. //
  17. using System;
  18. namespace System.Globalization
  19. {
  20. /// <summary>
  21. /// Implmentation of the System.Globalization.Calendar class
  22. /// </summary>
  23. public abstract class Calendar
  24. {
  25. /// <summary>
  26. /// The Calendar Constructor
  27. /// </summary>
  28. protected Calendar ()
  29. {
  30. _MaxDateTime = DateTime.MaxValue;
  31. _MinDateTime = DateTime.MinValue;
  32. }
  33. protected int _TwoDigitYearMax;
  34. protected static int[] _DaysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  35. protected static int[] _DaysInMonthLeap = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  36. // these can be overridden, for example using "new protected const int _MinYear = 1;"
  37. protected const int _MinYear = 1;
  38. protected const int _MaxYear = 9999;
  39. protected const int _MinDay = 0;
  40. protected const int _MinMonth = 1;
  41. protected const int _MaxMonth = 12;
  42. protected const int _MinHour = 0;
  43. protected const int _MaxHour = 23;
  44. protected const int _MinMinute = 0;
  45. protected const int _MaxMinute = 59;
  46. protected const int _MinSecond = 0;
  47. protected const int _MaxSecond = 59;
  48. protected const int _MinMillisecond = 0;
  49. protected const int _MaxMillisecond = 999;
  50. private const long _TicksPerMillisecond = 10000;
  51. private const long _TicksPerSecond = 10000000;
  52. private const long _TicksPerMinute = 600000000;
  53. private const long _TicksPerHour = 36000000000;
  54. private const long _TicksPerDay = 864000000000;
  55. private const long _TicksPerWeek = 6048000000000;
  56. protected DateTime _MaxDateTime;
  57. protected DateTime _MinDateTime;
  58. /// <summary>
  59. /// The Currentera constant
  60. /// </summary>
  61. public const int CurrentEra = 0;
  62. /// <summary>
  63. /// Returns an array of the available eras
  64. /// </summary>
  65. public abstract int[] Eras {get;}
  66. // DONE!
  67. /// <summary>
  68. /// The Two digit max
  69. /// </summary>
  70. public virtual int TwoDigitYearMax
  71. {
  72. get
  73. {
  74. return _TwoDigitYearMax;
  75. }
  76. set
  77. {
  78. _TwoDigitYearMax = value;
  79. }
  80. }
  81. // DONE!
  82. public virtual DateTime AddDays ( DateTime time, int days )
  83. {
  84. return new DateTime(time.Ticks).AddTicks(_TicksPerDay*days);
  85. }
  86. // DONE!
  87. public virtual DateTime AddHours ( DateTime time, int hours )
  88. {
  89. return new DateTime(time.Ticks).AddTicks(_TicksPerHour*hours);
  90. }
  91. // DONE!
  92. public virtual DateTime AddMilliseconds ( DateTime time, double milliseconds )
  93. {
  94. DateTime t = new DateTime(time.Ticks);
  95. return t.AddMilliseconds(milliseconds);
  96. }
  97. // DONE!
  98. public virtual DateTime AddMinutes ( DateTime time, int minutes )
  99. {
  100. return new DateTime(time.Ticks).AddTicks(_TicksPerMinute * minutes);
  101. }
  102. // DONE!
  103. /// <summary>
  104. /// Returns a DateTime that is the specified number of months away from the specified DateTime
  105. /// </summary>
  106. /// <param name="time"></param>
  107. /// <param name="months"></param>
  108. /// <returns></returns>
  109. /// <remarks>Calculates correct comapared to .NET Beta 2</remarks>
  110. public virtual DateTime AddMonths ( DateTime time, int months )
  111. {
  112. DateTime t = new DateTime(time.Ticks);
  113. return t.AddMonths(months);
  114. }
  115. // DONE!
  116. public virtual DateTime AddSeconds ( DateTime time, int seconds )
  117. {
  118. return new DateTime(time.Ticks).AddTicks(_TicksPerSecond * seconds);
  119. }
  120. // DONE!
  121. public virtual DateTime AddWeeks ( DateTime time, int weeks )
  122. {
  123. return new DateTime(time.Ticks).AddTicks(_TicksPerWeek * weeks);
  124. }
  125. // DONE!
  126. public virtual DateTime AddYears ( DateTime time, int years )
  127. {
  128. DateTime t = new DateTime(time.Ticks);
  129. return t.AddYears(years);
  130. }
  131. // DONE!
  132. public abstract int GetDayOfMonth ( DateTime time );
  133. // DONE!
  134. public abstract DayOfWeek GetDayOfWeek ( DateTime time );
  135. // DONE!
  136. public abstract int GetDayOfYear ( DateTime time );
  137. // DONE!
  138. public virtual int GetDaysInMonth ( int year, int month )
  139. {
  140. if(year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
  141. throw new System.ArgumentOutOfRangeException();
  142. if(this.IsLeapYear(year))
  143. return _DaysInMonthLeap[month];
  144. else
  145. return _DaysInMonth[month];
  146. }
  147. // DONE!
  148. public abstract int GetDaysInMonth ( int year, int month, int era );
  149. // DONE!
  150. public virtual int GetDaysInYear ( int year)
  151. {
  152. if( year < _MinYear || year > _MaxYear)
  153. throw new System.ArgumentOutOfRangeException();
  154. if(this.IsLeapYear(year))
  155. return 366;
  156. else
  157. return 365;
  158. }
  159. // DONE!
  160. public abstract int GetDaysInYear ( int year, int era );
  161. // DONE!
  162. public abstract int GetEra ( DateTime time );
  163. // DONE!
  164. public virtual int GetHour ( DateTime time )
  165. {
  166. return time.Hour;
  167. }
  168. // DONE!
  169. public virtual double GetMilliseconds ( DateTime time )
  170. {
  171. return time.Millisecond;
  172. }
  173. // DONE!
  174. public virtual int GetMinute ( DateTime time )
  175. {
  176. return time.Minute;
  177. }
  178. // DONE!
  179. public abstract int GetMonth ( DateTime time );
  180. // DONE!
  181. public virtual int GetMonthsInYear ( int year )
  182. {
  183. if( year < _MinYear || year > _MaxYear)
  184. throw new System.ArgumentException();
  185. return _MaxMonth;
  186. }
  187. // DONE!
  188. public abstract int GetMonthsInYear ( int year, int era );
  189. // DONE!
  190. public virtual int GetSecond ( DateTime time )
  191. {
  192. return time.Second;
  193. }
  194. // DONE!
  195. /// <summary>
  196. /// Gets the week of the year that includes the date in the specified DateTime
  197. /// </summary>
  198. /// <param name="time"></param>
  199. /// <param name="rule"></param>
  200. /// <param name="firstDayOfWeek"></param>
  201. /// <returns></returns>
  202. /// <remarks>.NET beta 2 calculates this erroneous, but this one is ok(? I think...)</remarks>
  203. public virtual int GetWeekOfYear ( DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek )
  204. {
  205. if( firstDayOfWeek < DayOfWeek.Sunday || firstDayOfWeek > DayOfWeek.Saturday)
  206. throw new System.ArgumentOutOfRangeException();
  207. int week;
  208. int days = 0;
  209. int[] dim;
  210. if(this.IsLeapYear(time.Year))
  211. dim = _DaysInMonthLeap;
  212. else
  213. dim = _DaysInMonth;
  214. DateTime jan1 = new DateTime(time.Year, 1, 1);
  215. for( int i = 0; i < time.Month-1; i++)
  216. days += dim[i];
  217. days += time.Day;
  218. switch(rule)
  219. {
  220. case CalendarWeekRule.FirstDay:
  221. while(jan1.DayOfWeek != firstDayOfWeek)
  222. {
  223. days--;
  224. jan1 = jan1.AddTicks(_TicksPerDay);
  225. }
  226. break;
  227. case CalendarWeekRule.FirstFourDayWeek:
  228. while(jan1.DayOfWeek < firstDayOfWeek)
  229. {
  230. days--;
  231. jan1 = jan1.AddTicks(_TicksPerDay);
  232. }
  233. break;
  234. case CalendarWeekRule.FirstFullWeek:
  235. if(jan1.DayOfWeek != firstDayOfWeek)
  236. {
  237. do
  238. {
  239. days--;
  240. jan1 = jan1.AddTicks(_TicksPerDay);
  241. }
  242. while(jan1.DayOfWeek != firstDayOfWeek);
  243. }
  244. break;
  245. default:
  246. throw new System.ArgumentOutOfRangeException();
  247. }
  248. if(days <= 0)
  249. week = GetWeekOfYear(new DateTime(time.Year-1,12,31), rule, firstDayOfWeek);
  250. else
  251. week = (--days / 7) + 1;
  252. return week;
  253. }
  254. // DONE!
  255. public abstract int GetYear ( DateTime time );
  256. // DONE!
  257. // TODO: verify this for the Calendar Class
  258. public virtual bool IsLeapDay ( int year, int month, int day )
  259. {
  260. int dim;
  261. if(day < _MinDay || month < _MinMonth || month > _MaxMonth)
  262. throw new System.ArgumentOutOfRangeException();
  263. if(this.IsLeapYear(year))
  264. dim = _DaysInMonthLeap[month-1];
  265. else
  266. dim = _DaysInMonth[month-1];
  267. if( day > dim)
  268. throw new System.ArgumentOutOfRangeException();
  269. if( month == 2 && day == 29)
  270. return true;
  271. return false;
  272. }
  273. // DONE!
  274. public abstract bool IsLeapDay ( int year, int month, int day, int era );
  275. // DONE!
  276. public virtual bool IsLeapMonth ( int year, int month )
  277. {
  278. if( year < _MinYear || year > _MaxYear || month < _MinMonth || month > _MaxMonth)
  279. throw new System.ArgumentOutOfRangeException();
  280. if(this.IsLeapYear(year))
  281. {
  282. return true;
  283. }
  284. else
  285. return false;
  286. }
  287. // DONE!
  288. public abstract bool IsLeapMonth ( int year, int month, int era );
  289. public virtual bool IsLeapYear ( int year )
  290. {
  291. if(year < _MinYear || year > _MaxYear )
  292. throw new System.ArgumentOutOfRangeException();
  293. if(year % 4 == 0) // TODO: verify this for the Calendar class!
  294. return true;
  295. return false;
  296. }
  297. // DONE!
  298. public abstract bool IsLeapYear ( int year, int era );
  299. // DONE!
  300. public virtual DateTime ToDateTime ( int year, int month, int day, int hour, int minute, int second, int millisecond )
  301. {
  302. int dim;
  303. dim = GetDaysInMonth(year,month);
  304. if( day < _MinDay || day > dim ||
  305. hour < _MinHour || hour > _MaxHour ||
  306. minute < _MinMinute || minute > _MaxMinute ||
  307. second < _MinSecond || second > _MaxSecond ||
  308. millisecond < _MinMillisecond || millisecond > _MaxMillisecond)
  309. throw new System.ArgumentOutOfRangeException();
  310. return new DateTime(year,month,day,hour,minute,second,millisecond,this);
  311. }
  312. // DONE!
  313. public abstract DateTime ToDateTime ( int year, int month, int date, int hour, int minute, int second, int millisecond, int era );
  314. // DONE!
  315. public virtual int ToFourDigitYear ( int year )
  316. {
  317. int i = year - ( _TwoDigitYearMax % 100 );
  318. if( year > 0 )
  319. return _TwoDigitYearMax - 100 + year;
  320. else
  321. return _TwoDigitYearMax + year;
  322. }
  323. }
  324. }