HebrewCalendar.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. // HebrewCalendar.cs
  2. //
  3. // (C) Ulrich Kunitz 2002
  4. //
  5. namespace System.Globalization {
  6. using System;
  7. using System.IO;
  8. /// <summary>
  9. /// This is the Hebrew calendar.
  10. /// </summary>
  11. /// <remarks>
  12. /// <para>The Hebrew calendar supports only years between 5343 A.M. and
  13. /// 6000 A.M. This has been done to be compatible with .NET.
  14. /// </para>
  15. /// <para>The implementation uses the
  16. /// <see cref="N:CalendricalCalculations"/> namespace.
  17. /// </para>
  18. /// </remarks>
  19. [Serializable]
  20. public class HebrewCalendar : Calendar {
  21. /// <summary>
  22. /// Constructor.
  23. /// </summary>
  24. public HebrewCalendar() {
  25. M_AbbrEraNames = new string[] {"A.M."};
  26. M_EraNames = new string[] {"Anno Mundi"};
  27. if (M_TwoDigitYearMax == 99)
  28. M_TwoDigitYearMax = 5790;
  29. }
  30. /// <summary>
  31. /// The era number for the Anno Mundi (A.M.) era, called
  32. /// plain HebrewEra.
  33. /// </summary>
  34. public static readonly int HebrewEra = 1;
  35. /// <summary>
  36. /// The
  37. /// <see cref="T:System.DateTime"/> ticks for first day of year
  38. /// 5343 A.M.
  39. /// </summary>
  40. internal const long M_MinTicks = 499147488000000000L;
  41. /// <summary>
  42. /// The number of
  43. /// <see cref="T:System.DateTime"/> ticks for the last day of year
  44. /// 6000 A.M.
  45. /// </summary>
  46. internal const long M_MaxTicks = 706783967999999999L;
  47. /// <summary>
  48. /// The minimum year in the A.M. era supported.
  49. /// </summary>
  50. internal const int M_MinYear = 5343;
  51. /// <summary>
  52. /// The maximum year supported in the A.M. era.
  53. /// </summary>
  54. internal override int M_MaxYear {
  55. get { return 6000; }
  56. }
  57. /// <value>Overridden. Gives the eras supported by the Gregorian
  58. /// calendar as an array of integers.
  59. /// </value>
  60. public override int[] Eras {
  61. get {
  62. return new int[] { HebrewEra };
  63. }
  64. }
  65. [MonoTODO]
  66. public override int TwoDigitYearMax
  67. {
  68. get {
  69. throw new NotImplementedException();
  70. }
  71. set {
  72. throw new NotImplementedException();
  73. }
  74. }
  75. /// <summary>
  76. /// A protected member checking a
  77. /// <see cref="T:System.DateTime"/> value.
  78. /// </summary>
  79. /// <param name="time">The
  80. /// <see cref="T:System.DateTime"/>
  81. /// to check.
  82. /// </param>
  83. /// <exception cref="T:System.ArgumentOutOfRangeException">
  84. /// The exception is thrown if the
  85. /// <see cref="T:System.DateTime"/> parameter is not in the years
  86. /// between 5343 A.M. and 6000 A.M., inclusive.
  87. /// </exception>
  88. internal void M_CheckDateTime(DateTime time) {
  89. if (time.Ticks < M_MinTicks || time.Ticks > M_MaxTicks)
  90. throw new ArgumentOutOfRangeException(
  91. "time",
  92. "Only hebrew years between 5343 and 6000," +
  93. " inclusive, are supported.");
  94. }
  95. /// <summary>
  96. /// A protected method checking the era number.
  97. /// </summary>
  98. /// <param name="era">The era number.</param>
  99. /// <exception name="T:System.ArgumentException">
  100. /// The exception is thrown if the era is not equal
  101. /// <see cref="F:HebrewEra"/>.
  102. /// </exception>
  103. internal void M_CheckEra(ref int era) {
  104. if (era == CurrentEra)
  105. era = HebrewEra;
  106. if (era != HebrewEra)
  107. throw new ArgumentException("Era value was not valid.");
  108. }
  109. /// <summary>
  110. /// A protected method checking calendar year and the era number.
  111. /// </summary>
  112. /// <param name="year">An integer representing the calendar year.
  113. /// </param>
  114. /// <param name="era">The era number.</param>
  115. /// <exception cref="T:System.ArgumentException">
  116. /// The exception is thrown if the era is not equal
  117. /// <see cref="F:HebrewEra"/>.
  118. /// </exception>
  119. /// <exception cref="T:System.ArgumentOutOfRangeException">
  120. /// The exception is thrown if the calendar year is outside of
  121. /// the allowed range.
  122. /// </exception>
  123. internal override void M_CheckYE(int year, ref int era) {
  124. M_CheckEra(ref era);
  125. if (year < M_MinYear || year > M_MaxYear)
  126. throw new ArgumentOutOfRangeException(
  127. "year",
  128. "Only hebrew years between 5343 and 6000," +
  129. " inclusive, are supported.");
  130. }
  131. /// <summary>
  132. /// A protected method checking the calendar year, month, and
  133. /// era number.
  134. /// </summary>
  135. /// <param name="year">An integer representing the calendar year.
  136. /// </param>
  137. /// <param name="month">An integer giving the calendar month.
  138. /// </param>
  139. /// <param name="era">The era number.</param>
  140. /// <exception cref="T:System.ArgumentException">
  141. /// The exception is thrown if the era is not equal
  142. /// <see cref="F:HebrewEra"/>.
  143. /// </exception>
  144. /// <exception cref="T:System.ArgumentOutOfRangeException">
  145. /// The exception is thrown if the calendar year or month is
  146. /// outside of the allowed range.
  147. /// </exception>
  148. internal void M_CheckYME(int year, int month, ref int era) {
  149. M_CheckYE(year, ref era);
  150. int l = CCHebrewCalendar.last_month_of_year(year);
  151. if (month < 1 || month > l) {
  152. StringWriter sw = new StringWriter();
  153. sw.Write("Month must be between 1 and {0}.", l);
  154. throw new ArgumentOutOfRangeException("month",
  155. sw.ToString());
  156. }
  157. }
  158. /// <summary>
  159. /// A protected method checking the calendar day, month, and year
  160. /// and the era number.
  161. /// </summary>
  162. /// <param name="year">An integer representing the calendar year.
  163. /// </param>
  164. /// <param name="month">An integer giving the calendar month.
  165. /// </param>
  166. /// <param name="day">An integer giving the calendar day.
  167. /// </param>
  168. /// <param name="era">The era number.</param>
  169. /// <exception cref="T:System.ArgumentException">
  170. /// The exception is thrown if the era is not equal
  171. /// <see cref="F:HebrewEra"/>.
  172. /// </exception>
  173. /// <exception cref="T:System.ArgumentOutOfRangeException">
  174. /// The exception is thrown if the calendar year, month, or day is
  175. /// outside of the allowed range.
  176. /// </exception>
  177. internal void M_CheckYMDE(int year, int month, int day,
  178. ref int era)
  179. {
  180. M_CheckYME(year, month, ref era);
  181. M_ArgumentInRange("day", day, 1, GetDaysInMonth(year, month,
  182. era));
  183. }
  184. /// <summary>
  185. /// Overridden. Adds days to a given date.
  186. /// </summary>
  187. /// <param name="time">The
  188. /// <see cref="T:System.DateTime"/> to which to add
  189. /// days.
  190. /// </param>
  191. /// <param name="days">The number of days to add.</param>
  192. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  193. /// results from adding <paramref name="days"/> to the specified
  194. /// DateTime.</returns>
  195. /// <exception cref="T:System.ArgumentOutOfRangeException">
  196. /// The exception is thrown if the
  197. /// <see cref="T:System.DateTime"/> return value is not in the years
  198. /// between 5343 A.M. and 6000 A.M., inclusive.
  199. /// </exception>
  200. public override DateTime AddDays(DateTime time, int days) {
  201. DateTime t = base.AddDays(time, days);
  202. M_CheckDateTime(t);
  203. return t;
  204. }
  205. /// <summary>
  206. /// Overridden. Adds hours to a given date.
  207. /// </summary>
  208. /// <param name="time">The
  209. /// <see cref="T:System.DateTime"/> to which to add
  210. /// hours.
  211. /// </param>
  212. /// <param name="hours">The number of hours to add.</param>
  213. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  214. /// results from adding <paramref name="hours"/> to the specified
  215. /// DateTime.</returns>
  216. /// <exception cref="T:System.ArgumentOutOfRangeException">
  217. /// The exception is thrown if the
  218. /// <see cref="T:System.DateTime"/> return value is not in the years
  219. /// between 5343 A.M. and 6000 A.M., inclusive.
  220. /// </exception>
  221. public override DateTime AddHours(DateTime time, int hours) {
  222. DateTime t = base.AddHours(time, hours);
  223. M_CheckDateTime(t);
  224. return t;
  225. }
  226. /// <summary>
  227. /// Overridden. Adds milliseconds to a given date.
  228. /// </summary>
  229. /// <param name="time">The
  230. /// <see cref="T:System.DateTime"/> to which to add
  231. /// milliseconds.
  232. /// </param>
  233. /// <param name="milliseconds">The number of milliseconds given as
  234. /// double to add. Keep in mind the 100 nanosecond resolution of
  235. /// <see cref="T:System.DateTime"/>.
  236. /// </param>
  237. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  238. /// results from adding <paramref name="milliseconds"/> to the specified
  239. /// DateTime.</returns>
  240. /// <exception cref="T:System.ArgumentOutOfRangeException">
  241. /// The exception is thrown if the
  242. /// <see cref="T:System.DateTime"/> return value is not in the years
  243. /// between 5343 A.M. and 6000 A.M., inclusive.
  244. /// </exception>
  245. public override DateTime AddMilliseconds(DateTime time,
  246. double milliseconds)
  247. {
  248. DateTime t = base.AddMilliseconds(time, milliseconds);
  249. M_CheckDateTime(t);
  250. return t;
  251. }
  252. /// <summary>
  253. /// Overridden. Adds minutes to a given date.
  254. /// </summary>
  255. /// <param name="time">The
  256. /// <see cref="T:System.DateTime"/> to which to add
  257. /// minutes.
  258. /// </param>
  259. /// <param name="minutes">The number of minutes to add.</param>
  260. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  261. /// results from adding <paramref name="minutes"/> to the specified
  262. /// DateTime.</returns>
  263. /// <exception cref="T:System.ArgumentOutOfRangeException">
  264. /// The exception is thrown if the
  265. /// <see cref="T:System.DateTime"/> return value is not in the years
  266. /// between 5343 A.M. and 6000 A.M., inclusive.
  267. /// </exception>
  268. public override DateTime AddMinutes(DateTime time, int minutes) {
  269. DateTime t = base.AddMinutes(time, minutes);
  270. M_CheckDateTime(t);
  271. return t;
  272. }
  273. /// <summary>
  274. /// Overridden. Adds seconds to a given date.
  275. /// </summary>
  276. /// <param name="time">The
  277. /// <see cref="T:System.DateTime"/> to which to add
  278. /// seconds.
  279. /// </param>
  280. /// <param name="seconds">The number of seconds to add.</param>
  281. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  282. /// results from adding <paramref name="seconds"/> to the specified
  283. /// DateTime.</returns>
  284. /// <exception cref="T:System.ArgumentOutOfRangeException">
  285. /// The exception is thrown if the
  286. /// <see cref="T:System.DateTime"/> return value is not in the years
  287. /// between 5343 A.M. and 6000 A.M., inclusive.
  288. /// </exception>
  289. public override DateTime AddSeconds(DateTime time, int seconds) {
  290. DateTime t = base.AddSeconds(time, seconds);
  291. M_CheckDateTime(t);
  292. return t;
  293. }
  294. /// <summary>
  295. /// Overridden. Adds weeks to a given date.
  296. /// </summary>
  297. /// <param name="time">The
  298. /// <see cref="T:System.DateTime"/> to which to add
  299. /// weeks.
  300. /// </param>
  301. /// <param name="weeks">The number of weeks to add.</param>
  302. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  303. /// results from adding <paramref name="weeks"/> to the specified
  304. /// DateTime.</returns>
  305. /// <exception cref="T:System.ArgumentOutOfRangeException">
  306. /// The exception is thrown if the
  307. /// <see cref="T:System.DateTime"/> return value is not in the years
  308. /// between 5343 A.M. and 6000 A.M., inclusive.
  309. /// </exception>
  310. public override DateTime AddWeeks(DateTime time, int weeks) {
  311. DateTime t = base.AddWeeks(time, weeks);
  312. M_CheckDateTime(t);
  313. return t;
  314. }
  315. /// <summary>
  316. /// Overridden. Gives the hour of the specified time.
  317. /// </summary>
  318. /// <param name="time">The
  319. /// <see cref="T:System.DateTime"/> that specifies the
  320. /// time.
  321. /// </param>
  322. /// <returns>An integer that gives the hour of the specified time,
  323. /// starting with 0.</returns>
  324. /// <exception cref="T:System.ArgumentOutOfRangeException">
  325. /// The exception is thrown if the
  326. /// <see cref="T:System.DateTime"/> parameter is not in the years
  327. /// between 5343 A.M. and 6000 A.M., inclusive.
  328. /// </exception>
  329. public override int GetHour(DateTime time) {
  330. M_CheckDateTime(time);
  331. return base.GetHour(time);
  332. }
  333. /// <summary>
  334. /// Overridden. Gives the milliseconds in the current second
  335. /// of the specified time.
  336. /// </summary>
  337. /// <param name="time">The
  338. /// <see cref="T:System.DateTime"/> that specifies the
  339. /// time.
  340. /// </param>
  341. /// <returns>An integer that gives the milliseconds in the seconds
  342. /// of the specified time, starting with 0.</returns>
  343. /// <exception cref="T:System.ArgumentOutOfRangeException">
  344. /// The exception is thrown if the
  345. /// <see cref="T:System.DateTime"/> parameter is not in the years
  346. /// between 5343 A.M. and 6000 A.M., inclusive.
  347. /// </exception>
  348. public override double GetMilliseconds(DateTime time) {
  349. M_CheckDateTime(time);
  350. return base.GetMilliseconds(time);
  351. }
  352. /// <summary>
  353. /// Overridden. Gives the minute of the specified time.
  354. /// </summary>
  355. /// <param name="time">The
  356. /// <see cref="T:System.DateTime"/> that specifies the
  357. /// time.
  358. /// </param>
  359. /// <returns>An integer that gives the minute of the specified time,
  360. /// starting with 0.</returns>
  361. /// <exception cref="T:System.ArgumentOutOfRangeException">
  362. /// The exception is thrown if the
  363. /// <see cref="T:System.DateTime"/> parameter is not in the years
  364. /// between 5343 A.M. and 6000 A.M., inclusive.
  365. /// </exception>
  366. public override int GetMinute(DateTime time) {
  367. M_CheckDateTime(time);
  368. return base.GetMinute(time);
  369. }
  370. /// <summary>
  371. /// Overridden. Gives the second of the specified time.
  372. /// </summary>
  373. /// <param name="time">The
  374. /// <see cref="T:System.DateTime"/> that specifies the
  375. /// time.
  376. /// </param>
  377. /// <returns>An integer that gives the second of the specified time,
  378. /// starting with 0.</returns>
  379. /// <exception cref="T:System.ArgumentOutOfRangeException">
  380. /// The exception is thrown if the
  381. /// <see cref="T:System.DateTime"/> parameter is not in the years
  382. /// between 5343 A.M. and 6000 A.M., inclusive.
  383. /// </exception>
  384. public override int GetSecond(DateTime time) {
  385. M_CheckDateTime(time);
  386. return base.GetMinute(time);
  387. }
  388. /// <summary>
  389. /// Overrideden. Adds months to a given date.
  390. /// </summary>
  391. /// <param name="time">The
  392. /// <see cref="T:System.DateTime"/> to which to add
  393. /// months.
  394. /// </param>
  395. /// <param name="months">The number of months to add.</param>
  396. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  397. /// results from adding <paramref name="months"/> to the specified
  398. /// DateTime.</returns>
  399. /// <exception cref="T:System.ArgumentOutOfRangeException">
  400. /// The exception is thrown if the
  401. /// <see cref="T:System.DateTime"/> return value is not in the years
  402. /// between 5343 A.M. and 6000 A.M., inclusive.
  403. /// </exception>
  404. public override DateTime AddMonths(DateTime time, int months) {
  405. int y, m, d;
  406. DateTime t;
  407. if (months == 0) {
  408. t = time;
  409. } else {
  410. int rd = CCFixed.FromDateTime(time);
  411. CCHebrewCalendar.dmy_from_fixed(
  412. out d, out m, out y, rd);
  413. m = M_Month(m, y);
  414. if (months < 0) {
  415. while (months < 0) {
  416. if (m+months > 0) {
  417. m += months;
  418. months = 0;
  419. } else {
  420. months += m;
  421. y -= 1;
  422. m = GetMonthsInYear(y);
  423. }
  424. }
  425. }
  426. else {
  427. while (months > 0) {
  428. int my = GetMonthsInYear(y);
  429. if (m+months <= my) {
  430. m += months;
  431. months = 0;
  432. } else {
  433. months -= my-m+1;
  434. m = 1;
  435. y += 1;
  436. }
  437. }
  438. }
  439. t = ToDateTime(y, m, d, 0, 0, 0, 0);
  440. t = t.Add(time.TimeOfDay);
  441. }
  442. M_CheckDateTime(t);
  443. return t;
  444. }
  445. /// <summary>
  446. /// Overridden. Adds years to a given date.
  447. /// </summary>
  448. /// <param name="time">The
  449. /// <see cref="T:System.DateTime"/> to which to add
  450. /// years.
  451. /// </param>
  452. /// <param name="years">The number of years to add.</param>
  453. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  454. /// results from adding <paramref name="years"/> to the specified
  455. /// DateTime.</returns>
  456. /// <exception cref="T:System.ArgumentOutOfRangeException">
  457. /// The exception is thrown if the
  458. /// <see cref="T:System.DateTime"/> return value is not in the years
  459. /// between 5343 A.M. and 6000 A.M., inclusive.
  460. /// </exception>
  461. public override DateTime AddYears(DateTime time, int years) {
  462. int rd = CCFixed.FromDateTime(time);
  463. int day, month, year;
  464. CCHebrewCalendar.dmy_from_fixed(
  465. out day, out month, out year, rd);
  466. year += years;
  467. rd = CCHebrewCalendar.fixed_from_dmy(day, month, year);
  468. DateTime t = CCFixed.ToDateTime(rd);
  469. t = t.Add(time.TimeOfDay);
  470. M_CheckDateTime(t);
  471. return t;
  472. }
  473. /// <summary>
  474. /// Overriden. Gets the day of the month from
  475. /// <paramref name="time"/>.
  476. /// </summary>
  477. /// <param name="time">The
  478. /// <see cref="T:System.DateTime"/> that specifies a
  479. /// date.
  480. /// </param>
  481. /// <returns>An integer giving the day of months, starting with 1.
  482. /// </returns>
  483. /// <exception cref="T:System.ArgumentOutOfRangeException">
  484. /// The exception is thrown if the
  485. /// <see cref="T:System.DateTime"/> parameter is not in the years
  486. /// between 5343 A.M. and 6000 A.M., inclusive.
  487. /// </exception>
  488. public override int GetDayOfMonth(DateTime time) {
  489. M_CheckDateTime(time);
  490. int rd = CCFixed.FromDateTime(time);
  491. return CCHebrewCalendar.day_from_fixed(rd);
  492. }
  493. /// <summary>
  494. /// Overriden. Gets the day of the week from the specified date.
  495. /// </summary>
  496. /// <param name="time">The
  497. /// <see cref="T:System.DateTime"/> that specifies a
  498. /// date.
  499. /// </param>
  500. /// <returns>An integer giving the day of months, starting with 1.
  501. /// </returns>
  502. /// <exception cref="T:System.ArgumentOutOfRangeException">
  503. /// The exception is thrown if the
  504. /// <see cref="T:System.DateTime"/> parameter is not in the years
  505. /// between 5343 A.M. and 6000 A.M., inclusive.
  506. /// </exception>
  507. public override DayOfWeek GetDayOfWeek(DateTime time) {
  508. M_CheckDateTime(time);
  509. int rd = CCFixed.FromDateTime(time);
  510. return (DayOfWeek)CCFixed.day_of_week(rd);
  511. }
  512. /// <summary>
  513. /// Overridden. Gives the number of the day in the year.
  514. /// </summary>
  515. /// <param name="time">The
  516. /// <see cref="T:System.DateTime"/> that specifies a
  517. /// date.
  518. /// </param>
  519. /// <returns>An integer representing the day of the year,
  520. /// starting with 1.</returns>
  521. /// <exception cref="T:System.ArgumentOutOfRangeException">
  522. /// The exception is thrown if the
  523. /// <see cref="T:System.DateTime"/> parameter is not in the years
  524. /// between 5343 A.M. and 6000 A.M., inclusive.
  525. /// </exception>
  526. public override int GetDayOfYear(DateTime time) {
  527. M_CheckDateTime(time);
  528. int rd = CCFixed.FromDateTime(time);
  529. int year = CCHebrewCalendar.year_from_fixed(rd);
  530. int rd1_7 = CCHebrewCalendar.fixed_from_dmy(1, 7, year);
  531. return rd - rd1_7 + 1;
  532. }
  533. /// <summary>
  534. /// The method maps a .NET Hebrew month to a Calencdrical
  535. /// Calculations Hebrew month.
  536. /// </summary>
  537. /// <param name="month">An integer representing a month in .NET
  538. /// counting (starting with Tishri).
  539. /// </param>
  540. /// <param name="year">An integer representing the Hebrew year.
  541. /// </param>
  542. /// <returns>The Hebrew month in Calendrical Calculations counting,
  543. /// staring with the Hebrew month Nisan.
  544. /// </returns>
  545. /// <remarks>
  546. /// <para>
  547. /// In .NET the month counting starts with the Hebrew month Tishri.
  548. /// Calendrical Calculations starts with the month Tisan. So we must
  549. /// map here.
  550. /// </para>
  551. /// </remarks>
  552. internal int M_CCMonth(int month, int year) {
  553. if (month <= 6) {
  554. return 6+month;
  555. }
  556. else {
  557. int l = CCHebrewCalendar.last_month_of_year(year);
  558. if (l == 12) {
  559. return month-6;
  560. }
  561. else {
  562. return month <= 7 ? 6+month : month-7;
  563. }
  564. }
  565. }
  566. /// <summary>
  567. /// The method maps a Calendrical Calculations Hebrew month
  568. /// to a .NET Hebrew month.
  569. /// </summary>
  570. /// <param name="ccmonth">An integer representing a month in
  571. /// Calendrical Calculations counting, starting with Nisan.
  572. /// </param>
  573. /// <param name="year">An integer representing the Hebrew year.
  574. /// </param>
  575. /// <returns>The Hebrew month in .NET counting,
  576. /// staring with the Hebrew month Tishri.
  577. /// </returns>
  578. /// <remarks>
  579. /// <para>
  580. /// In .NET the month counting starts with the Hebrew month Tishri.
  581. /// Calendrical Calculations starts with the month Tisan. So we must
  582. /// map here.
  583. /// </para>
  584. /// </remarks>
  585. internal int M_Month(int ccmonth, int year) {
  586. if (ccmonth >= 7) {
  587. return ccmonth - 6;
  588. } else {
  589. int l = CCHebrewCalendar.last_month_of_year(year);
  590. return ccmonth + (l == 12 ? 6 : 7);
  591. }
  592. }
  593. /// <summary>
  594. /// Overridden. Gives the number of days in the specified month
  595. /// of the given year and era.
  596. /// </summary>
  597. /// <param name="year">An integer that gives the year.
  598. /// </param>
  599. /// <param name="month">An integer that gives the month, starting
  600. /// with 1.</param>
  601. /// <param name="era">An integer that gives the era of the specified
  602. /// year.</param>
  603. /// <returns>An integer that gives the number of days of the
  604. /// specified month.</returns>
  605. /// <exception cref="T:System.ArgumentOutOfRangeException">
  606. /// The exception is thrown, if <paramref name="month"/>,
  607. /// <paramref name="year"/> ,or <paramref name="era"/> is outside
  608. /// the allowed range.
  609. /// </exception>
  610. public override int GetDaysInMonth(int year, int month, int era) {
  611. M_CheckYME(year, month, ref era);
  612. int ccmonth = M_CCMonth(month, year);
  613. int rd1 = CCHebrewCalendar.fixed_from_dmy(1, ccmonth, year);
  614. int rd2 = CCHebrewCalendar.fixed_from_dmy(1, ccmonth+1, year);
  615. return rd2 - rd1;
  616. }
  617. /// <summary>
  618. /// Overridden. Gives the number of days of the specified
  619. /// year of the given era.
  620. /// </summary>
  621. /// <param name="year">An integer that specifies the year.
  622. /// </param>
  623. /// <param name="era">An ineger that specifies the era.
  624. /// </param>
  625. /// <returns>An integer that gives the number of days of the
  626. /// specified year.</returns>
  627. /// <exception cref="T:System.ArgumentOutOfRangeExceiption">
  628. /// The exception is thrown, if
  629. /// <paramref name="year"/> or <paramref name="era"/> are outside the
  630. /// allowed range.
  631. /// </exception>
  632. public override int GetDaysInYear(int year, int era) {
  633. M_CheckYE(year, ref era);
  634. int rd1 = CCHebrewCalendar.fixed_from_dmy(1, 7, year);
  635. int rd2 = CCHebrewCalendar.fixed_from_dmy(1, 7, year+1);
  636. return rd2 - rd1;
  637. }
  638. /// <summary>
  639. /// Overridden. Gives the era of the specified date.
  640. /// </summary>
  641. /// <param name="time">The
  642. /// <see cref="T:System.DateTime"/> that specifies a
  643. /// date.
  644. /// </param>
  645. /// <returns>An integer representing the era of the calendar.
  646. /// </returns>
  647. /// <exception cref="T:System.ArgumentOutOfRangeException">
  648. /// The exception is thrown if the
  649. /// <see cref="T:System.DateTime"/> parameter is not in the years
  650. /// between 5343 A.M. and 6000 A.M., inclusive.
  651. /// </exception>
  652. public override int GetEra(DateTime time) {
  653. M_CheckDateTime(time);
  654. return HebrewEra;
  655. }
  656. /// <summary>
  657. /// Overridden. Gives the number of the month of the specified
  658. /// date.
  659. /// </summary>
  660. /// <param name="time">The
  661. /// <see cref="T:System.DateTime"/> that specifies a
  662. /// date.
  663. /// </param>
  664. /// <returns>An integer representing the month,
  665. /// starting with 1.</returns>
  666. /// <exception cref="T:System.ArgumentOutOfRangeException">
  667. /// The exception is thrown if the
  668. /// <see cref="T:System.DateTime"/> parameter is not in the years
  669. /// between 5343 A.M. and 6000 A.M., inclusive.
  670. /// </exception>
  671. public override int GetMonth(DateTime time) {
  672. M_CheckDateTime(time);
  673. int rd = CCFixed.FromDateTime(time);
  674. int ccmonth, year;
  675. CCHebrewCalendar.my_from_fixed(out ccmonth, out year, rd);
  676. return M_Month(ccmonth, year);
  677. }
  678. /// <summary>
  679. /// Overridden. Gives the number of months in the specified year
  680. /// and era.
  681. /// </summary>
  682. /// <param name="year">An integer that specifies the year.
  683. /// </param>
  684. /// <param name="era">An integer that specifies the era.
  685. /// </param>
  686. /// <returns>An integer that gives the number of the months in the
  687. /// specified year.</returns>
  688. /// <exception cref="T:System.ArgumentOutOfRangeException">
  689. /// The exception is thrown, if the year or the era are not valid.
  690. /// </exception>
  691. public override int GetMonthsInYear(int year, int era) {
  692. M_CheckYE(year, ref era);
  693. return CCHebrewCalendar.last_month_of_year(year);
  694. }
  695. /// <summary>
  696. /// Overridden. Gives the number of the year of the specified
  697. /// date.
  698. /// </summary>
  699. /// <param name="time">The
  700. /// <see cref="T:System.DateTime"/> that specifies a
  701. /// date.
  702. /// </param>
  703. /// <returns>An integer representing the year,
  704. /// starting with 1.</returns>
  705. /// <exception cref="T:System.ArgumentOutOfRangeException">
  706. /// The exception is thrown if the
  707. /// <see cref="T:System.DateTime"/> parameter is not in the years
  708. /// between 5343 A.M. and 6000 A.M., inclusive.
  709. /// </exception>
  710. public override int GetYear(DateTime time) {
  711. M_CheckDateTime(time);
  712. int rd = CCFixed.FromDateTime(time);
  713. return CCHebrewCalendar.year_from_fixed(rd);
  714. }
  715. /// <summary>
  716. /// Overridden. Tells whether the given day
  717. /// is a leap day.
  718. /// </summary>
  719. /// <param name="year">An integer that specifies the year in the
  720. /// given era.
  721. /// </param>
  722. /// <param name="month">An integer that specifies the month.
  723. /// </param>
  724. /// <param name="day">An integer that specifies the day.
  725. /// </param>
  726. /// <param name="era">An integer that specifies the era.
  727. /// </param>
  728. /// <returns>A boolean that tells whether the given day is a leap
  729. /// day.
  730. /// </returns>
  731. /// <exception cref="T:System.ArgumentOutOfRangeException">
  732. /// The exception is thrown, if the year, month, day, or era is not
  733. /// valid.
  734. /// </exception>
  735. /// <remarks>All days in Adar II are viewed as leap days and the
  736. /// last day of Adar I.
  737. /// </remarks>
  738. public override bool IsLeapDay(int year, int month, int day, int era)
  739. {
  740. M_CheckYMDE(year, month, day, ref era);
  741. return IsLeapYear(year) &&
  742. (month == 7 || (month == 6 && day == 30));
  743. }
  744. /// <summary>
  745. /// Overridden. Tells whether the given month
  746. /// is a leap month.
  747. /// </summary>
  748. /// <param name="year">An integer that specifies the year in the
  749. /// given era.
  750. /// </param>
  751. /// <param name="month">An integer that specifies the month.
  752. /// </param>
  753. /// <param name="era">An integer that specifies the era.
  754. /// </param>
  755. /// <returns>A boolean that tells whether the given month is a leap
  756. /// month.
  757. /// </returns>
  758. /// <exception cref="T:System.ArgumentOutOfRangeException">
  759. /// The exception is thrown, if the year, month, or era is not
  760. /// valid.
  761. /// </exception>
  762. /// <remarks>
  763. /// Adar II is viewed as leap month.
  764. /// </remarks>
  765. public override bool IsLeapMonth(int year, int month, int era) {
  766. M_CheckYME(year, month, ref era);
  767. return IsLeapYear(year) && month == 7;
  768. }
  769. /// <summary>
  770. /// Overridden. Tells whether the given year
  771. /// is a leap year.
  772. /// </summary>
  773. /// <param name="year">An integer that specifies the year in the
  774. /// given era.
  775. /// </param>
  776. /// <param name="era">An integer that specifies the era.
  777. /// </param>
  778. /// <returns>A boolean that tells whether the given year is a leap
  779. /// year.
  780. /// </returns>
  781. /// <exception cref="T:System.ArgumentOutOfRangeException">
  782. /// The exception is thrown, if the year or era is not
  783. /// valid.
  784. /// </exception>
  785. public override bool IsLeapYear(int year, int era) {
  786. M_CheckYE(year, ref era);
  787. return CCHebrewCalendar.is_leap_year(year);
  788. }
  789. /// <summary>
  790. /// Overridden. Creates the
  791. /// <see cref="T:System.DateTime"/> from the parameters.
  792. /// </summary>
  793. /// <param name="year">An integer that gives the year in the
  794. /// <paramref name="era"/>.
  795. /// </param>
  796. /// <param name="month">An integer that specifies the month.
  797. /// </param>
  798. /// <param name="day">An integer that specifies the day.
  799. /// </param>
  800. /// <param name="hour">An integer that specifies the hour.
  801. /// </param>
  802. /// <param name="minute">An integer that specifies the minute.
  803. /// </param>
  804. /// <param name="second">An integer that gives the second.
  805. /// </param>
  806. /// <param name="milliseconds">An integer that gives the
  807. /// milliseconds.
  808. /// </param>
  809. /// <param name="era">An integer that specifies the era.
  810. /// </param>
  811. /// <returns>A
  812. /// <see cref="T:system.DateTime"/> representig the date and time.
  813. /// </returns>
  814. /// <exception cref="T:System.ArgumentOutOfRangeException">
  815. /// The exception is thrown, if at least one of the parameters
  816. /// is out of range.
  817. /// </exception>
  818. public override DateTime ToDateTime(int year, int month, int day,
  819. int hour, int minute, int second, int milliseconds,
  820. int era)
  821. {
  822. M_CheckYMDE(year, month, day, ref era);
  823. M_CheckHMSM(hour, minute, second, milliseconds);
  824. int ccm = M_CCMonth(month, year);
  825. int rd = CCHebrewCalendar.fixed_from_dmy(day, ccm, year);
  826. return CCFixed.ToDateTime(rd,
  827. hour, minute, second, milliseconds);
  828. }
  829. [MonoTODO]
  830. public override int ToFourDigitYear(int year)
  831. {
  832. throw new NotImplementedException();
  833. }
  834. } // class HebrewCalendar
  835. } // namespace System.Globalization