PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/corlib/System.Globalization/CalendricalCalculations.cs

https://bitbucket.org/cosi2/dotnetanywhere-wb
C# | 2393 lines | 202 code | 47 blank | 2144 comment | 17 complexity | 3b4b49966bd35704c8a23efa5d5e1968 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. // CalendricalCalculations.cs
  2. //
  3. // (C) Ulrich Kunitz 2002
  4. //
  5. //
  6. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining
  9. // a copy of this software and associated documentation files (the
  10. // "Software"), to deal in the Software without restriction, including
  11. // without limitation the rights to use, copy, modify, merge, publish,
  12. // distribute, sublicense, and/or sell copies of the Software, and to
  13. // permit persons to whom the Software is furnished to do so, subject to
  14. // the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be
  17. // included in all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  23. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  24. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  25. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. //
  27. namespace System.Globalization {
  28. //using System.Collections;
  29. /*
  30. /// <summary>A class that provides mathematical functions.</summary>
  31. /// <remarks>
  32. /// <para>
  33. /// We are breaking the .Net
  34. /// naming conventions to be compatible to the "Calendrical Calculations"
  35. /// bool.
  36. /// </para>
  37. /// </remarks>
  38. internal class CCMath {
  39. /// <summary>
  40. /// A static method which rounds a double value.
  41. /// </summary>
  42. /// <param name="x">The double value to round.</param>
  43. /// <returns>The rounded double.</returns>
  44. public static double round(double x) {
  45. return System.Math.Floor(x+0.5);
  46. }
  47. /// <summary>
  48. /// A static method that computes the remainder of the division
  49. /// of two doubles.
  50. /// </summary>
  51. /// <param name="x">The double value which is divided.</param>
  52. /// <param name="y">The divisor.</param>
  53. /// <returns>The remainder as double value.</returns>
  54. public static double mod(double x, double y) {
  55. return x - y * System.Math.Floor(x/y);
  56. }
  57. /// <summary>
  58. /// The static method divides two integers.
  59. /// </summary>
  60. /// <param name="x">The integer x value.</param>
  61. /// <param name="y">The integer y value.</param>
  62. /// <returns>The qotient of x and y defined by floor(x/y).
  63. /// </returns>
  64. /// <remarks>
  65. /// Please notify that the function is not compatible to the standard
  66. /// integer divide operation /.
  67. /// </remarks>
  68. public static int div(int x, int y) {
  69. return (int)System.Math.Floor((double)x/(double)y);
  70. }
  71. /// <summary>
  72. /// The static method computes the remainder of two integers.
  73. /// </summary>
  74. /// <param name="x">The integer value which will be divided.</param>
  75. /// <param name="y">The divisor integer value.</param>
  76. /// <returns> The remainder as integer value.</returns>
  77. /// <remarks>
  78. /// Please notify that the method is not compatible to the C#
  79. /// remainder operation %.
  80. /// </remarks>
  81. public static int mod(int x, int y) {
  82. return x - y * div(x, y);
  83. }
  84. /// <summary>
  85. /// A static method that combines integer division and remainder
  86. /// computation.
  87. /// </summary>
  88. /// <param name="remainder">Remainder integer output value.
  89. /// </param>
  90. /// <param name="x">Integer to be divided.</param>
  91. /// <param name="y">Divisor integer value.</param>
  92. /// <returns>The quotient as integer.</returns>
  93. /// <seealso cref="M:div"/>
  94. /// <seealso cref="M:mod"/>
  95. public static int div_mod(out int remainder, int x, int y) {
  96. int d = div(x, y);
  97. remainder = x - y * d;
  98. return d;
  99. }
  100. /// <summary>
  101. /// A static method returning the sign of the argument.
  102. /// </summary>
  103. /// <param name="x">The double argument.</param>
  104. /// <returns>An integer value: -1 for a negative argument;
  105. /// 0 for a zero argument, and 1 for a positive argument.
  106. /// </returns>
  107. public static int signum(double x) {
  108. if (x < 0.0)
  109. return -1;
  110. if (x == 0.0)
  111. return 0;
  112. return 1;
  113. }
  114. /// <summary>
  115. /// A static method returning the sign of the integer
  116. /// argument.
  117. /// </summary>
  118. /// <param name="x">The integer argument.</param>
  119. /// <returns>An integer value: -1 for a negative argument;
  120. /// 0 for a zero argument, and 1 for a positive argument.
  121. /// </returns>
  122. public static int signum(int x) {
  123. if (x < 0)
  124. return -1;
  125. if (x == 0)
  126. return 0;
  127. return 1;
  128. }
  129. /// <summary>
  130. /// An adjusted remainder function as defined in "Calendrical
  131. /// Calculations".
  132. /// </summary>
  133. /// <param name="x">The double x argument.</param>
  134. /// <param name="y">The double y argument, the divisor.</param>
  135. /// <returns>A double value representing remainder; but instead 0.0
  136. /// the divisor y is returned.
  137. /// </returns>
  138. public static double amod(double x, double y) {
  139. double d = mod(x, y);
  140. return (d == 0.0) ? y : d;
  141. }
  142. /// <summary>
  143. /// The adjusted remainder functions for integers as defined in
  144. /// "Calendrical Calculations".
  145. /// </summary>
  146. /// <param name="x">The integer argument to be divided.</param>
  147. /// <param name="y">The integer divisor argument.</param>
  148. /// <returns>The remainder as an integer; however instead 0
  149. /// is the divisor y returned.
  150. /// </returns>
  151. public static int amod(int x, int y) {
  152. int i = mod(x, y);
  153. return (i == 0) ? y : i;
  154. }
  155. }
  156. */
  157. /// <summary>The class implements methods to handle the fixed date value from
  158. /// the "Calendrical Calculations" books.
  159. /// </summary>
  160. /// <remarks>
  161. /// <para>
  162. /// For implementing the Calendar classes I used the algorithms from the
  163. /// book "Calendrical Calculations" by Nachum Dershowitz and Edward M.
  164. /// Rheingold, second reprint 1998. Trying to prevent the introduction of new
  165. /// bugs, I implemented their algorithms in the
  166. /// <see cref="N:CalendricalCalculations"/>
  167. /// namespace and wrapped it in the calendar classes.
  168. /// </para>
  169. /// <para>
  170. /// The fixed day number is also known as R.D. - rata die.
  171. /// Midnight at the onset of Monday,
  172. /// January 1, year 1 (Gregorian) is R.D. 1.
  173. /// </para>
  174. /// <para>Here are all my references:</para>
  175. /// <list type="table">
  176. /// <item><description>
  177. /// [1] Nachum Dershowitz and Edward M. Rheingold: "Calendrical Calculations";
  178. /// Cambridge University Press; second reprint 1998.
  179. /// </description></item>
  180. /// <item><description>
  181. /// [2] P. Kenneth Seidelmann (ed.): "Explanatory Supplement to the Astronomical
  182. /// Almanac"; University Science Books, Sausalito; 1992
  183. /// </description></item>
  184. /// <item><description>
  185. /// [3] F. Richard Stephenson: "Historical Eclipses and Earth Rotation";
  186. /// Cambridge University Press; 1997
  187. /// </description></item>
  188. /// </list>
  189. /// </remarks>
  190. internal class CCFixed {
  191. /// <summary>The method computes the
  192. /// <see cref="T:System.DateTime"/>
  193. /// from a fixed day number.
  194. /// </summary>
  195. /// <param name="date">A integer representing the fixed day number.
  196. /// </param>
  197. /// <returns>The <see cref="T:System.DateTime"/> representing
  198. /// the date.
  199. /// </returns>
  200. public static System.DateTime ToDateTime(int date) {
  201. long ticks = (date - 1) * System.TimeSpan.TicksPerDay;
  202. return new System.DateTime(ticks);
  203. }
  204. /// <summary>The method computes the
  205. /// <see cref="T:System.DateTime"/>
  206. /// from a fixed day number and time arguments.
  207. /// </summary>
  208. /// <param name="date">An integer representing the fixed day number.
  209. /// </param>
  210. /// <param name="hour">An integer argument specifying the hour.
  211. /// </param>
  212. /// <param name="minute">An integer argument specifying the minute.
  213. /// </param>
  214. /// <param name="second">An integer argument giving the second.
  215. /// </param>
  216. /// <param name="milliseconds">An double argument specifying
  217. /// the milliseconds. Notice that
  218. /// <see cref="T:System.DateTime"/> has 100 nanosecond resolution.
  219. /// </param>
  220. /// <returns>The <see cref="T:System.DateTime"/> representing
  221. /// the date.
  222. /// </returns>
  223. public static System.DateTime ToDateTime(int date,
  224. int hour, int minute, int second, double milliseconds)
  225. {
  226. System.DateTime time = ToDateTime(date);
  227. time = time.AddHours(hour);
  228. time = time.AddMinutes(minute);
  229. time = time.AddSeconds(second);
  230. return time.AddMilliseconds(milliseconds);
  231. }
  232. /// <summary>
  233. /// A static method computing the fixed day number from a
  234. /// <see cref="T:System.DateTime"/> value.
  235. /// </summary>
  236. /// <param name="time">A
  237. /// <see cref="T:System.DateTime"/> value representing the date.
  238. /// </param>
  239. /// <returns>The fixed day number as integer representing the date.
  240. /// </returns>
  241. public static int FromDateTime(System.DateTime time) {
  242. return 1 + (int)(time.Ticks / System.TimeSpan.TicksPerDay);
  243. }
  244. /// <summary>
  245. /// The static method computes the <see cref="T:DayOfWeek"/>.
  246. /// </summary>
  247. /// <param name="date">An integer representing the fixed day number.
  248. /// </param>
  249. /// <returns>The day of week.</returns>
  250. public static DayOfWeek day_of_week(int date) {
  251. return (DayOfWeek)(date % 7);//CCMath.mod(date, 7);
  252. }
  253. /// <summary>
  254. /// The static method computes the date of a day of week on or before
  255. /// a particular date.
  256. /// </summary>
  257. /// <param name="date">An integer representing the date as
  258. /// fixed day number.
  259. /// </param>
  260. /// <param name="k">An integer representing the day of the week,
  261. /// starting with 0 for sunday.
  262. /// </param>
  263. /// <returns>The fixed day number of the day of week specified by k
  264. /// on or before the given date.
  265. /// </returns>
  266. public static int kday_on_or_before(int date, int k) {
  267. return date - (int)day_of_week(date-k);
  268. }
  269. /// <summary>
  270. /// The static method computes the date of a day of week on or after
  271. /// a particular date.
  272. /// </summary>
  273. /// <param name="date">An integer representing the date as
  274. /// fixed day number.
  275. /// </param>
  276. /// <param name="k">An integer representing the day of the week,
  277. /// starting with 0 for sunday.
  278. /// </param>
  279. /// <returns>The fixed day number of the day of week specified by k
  280. /// on or after the given date.
  281. /// </returns>
  282. public static int kday_on_or_after(int date, int k) {
  283. return kday_on_or_before(date+6, k);
  284. }
  285. /// <summary>
  286. /// The static method computes the date of a day of week that is
  287. /// nearest to a particular date.
  288. /// </summary>
  289. /// <param name="date">An integer representing the date as
  290. /// fixed day number.
  291. /// </param>
  292. /// <param name="k">An integer representing the day of the week,
  293. /// starting with 0 for sunday.
  294. /// </param>
  295. /// <returns>The fixed day number of the day of week neares to the
  296. /// given date.
  297. /// </returns>
  298. public static int kd_nearest(int date, int k) {
  299. return kday_on_or_before(date+3, k);
  300. }
  301. /// <summary>
  302. /// The static method computes the date of a day of week after
  303. /// a particular date.
  304. /// </summary>
  305. /// <param name="date">An integer representing the date as
  306. /// fixed day number.
  307. /// </param>
  308. /// <param name="k">An integer representing the day of the week,
  309. /// starting with 0 for sunday.
  310. /// </param>
  311. /// <returns>The fixed day number of the day of week specified by k
  312. /// after the given date.
  313. /// </returns>
  314. public static int kday_after(int date, int k) {
  315. return kday_on_or_before(date+7, k);
  316. }
  317. /// <summary>
  318. /// The static method computes the date of a day of week before
  319. /// a particular date.
  320. /// </summary>
  321. /// <param name="date">An integer representing the date as
  322. /// fixed day number.
  323. /// </param>
  324. /// <param name="k">An integer representing the day of the week,
  325. /// starting with 0 for sunday.
  326. /// </param>
  327. /// <returns>The fixed day number of the day of week specified by k
  328. /// before the given date.
  329. /// </returns>
  330. public static int kday_before(int date, int k) {
  331. return kday_on_or_before(date-1, k);
  332. }
  333. } // class CCFixed
  334. /// <summary>
  335. /// A class encapsulating the functions of the Gregorian calendar as static
  336. /// methods.
  337. /// </summary>
  338. /// <remarks>
  339. /// <para>
  340. /// This class is not compatible to
  341. /// <see cref="T:System.Globalization.GregorianCalendar"/>.
  342. /// </para>
  343. /// <para>
  344. /// The fixed day number is also known as R.D. - rata die.
  345. /// Midnight at the onset of Monday,
  346. /// January 1, year 1 (Gregorian) is R.D. 1.
  347. /// </para>
  348. /// <seealso cref="T:CCFixed"/>
  349. /// </remarks>
  350. internal class CCGregorianCalendar {
  351. /// <summary>An integer defining the epoch of the Gregorian calendar
  352. /// as fixed day number.</summary>
  353. /// <remarks>The epoch is January 3, 1 C.E. (Julian).</remarks>
  354. const int epoch = 1;
  355. /// <summary>The enumeration defines the months of the Gregorian
  356. /// calendar.
  357. /// </summary>
  358. public enum Month {
  359. /// <summary>
  360. /// January.
  361. /// </summary>
  362. january = 1,
  363. /// <summary>
  364. /// February.
  365. /// </summary>
  366. february,
  367. /// <summary>
  368. /// March.
  369. /// </summary>
  370. march,
  371. /// <summary>
  372. /// April.
  373. /// </summary>
  374. april,
  375. /// <summary>
  376. /// May.
  377. /// </summary>
  378. may,
  379. /// <summary>
  380. /// June.
  381. /// </summary>
  382. june,
  383. /// <summary>
  384. /// July.
  385. /// </summary>
  386. july,
  387. /// <summary>
  388. /// August.
  389. /// </summary>
  390. august,
  391. /// <summary>
  392. /// September.
  393. /// </summary>
  394. september,
  395. /// <summary>
  396. /// October.
  397. /// </summary>
  398. october,
  399. /// <summary>
  400. /// November.
  401. /// </summary>
  402. november,
  403. /// <summary>
  404. /// December.
  405. /// </summary>
  406. december
  407. };
  408. /// <summary>
  409. /// The method tells whether the year is a leap year.
  410. /// </summary>
  411. /// <param name="year">An integer representing the Gregorian year.
  412. /// </param>
  413. /// <returns>A boolean which is true if <paramref name="year"/> is
  414. /// a leap year.
  415. /// </returns>
  416. public static bool is_leap_year(int year) {
  417. if (year % 4 != 0)
  418. return false;
  419. switch (year % 400) {
  420. case 100:
  421. return false;
  422. case 200:
  423. return false;
  424. case 300:
  425. return false;
  426. }
  427. return true;
  428. }
  429. /// <summary>
  430. /// The method returns the fixed day number of the given Gregorian
  431. /// date.
  432. /// </summary>
  433. /// <param name="day">An integer representing the day of the month,
  434. /// counting from 1.
  435. /// </param>
  436. /// <param name="month">An integer representing the month in the
  437. /// Gregorian year.
  438. /// </param>
  439. /// <param name="year">An integer representing the Gregorian year.
  440. /// Non-positive values are allowed also.
  441. /// </param>
  442. /// <returns>An integer value representing the fixed day number.
  443. /// </returns>
  444. public static int fixed_from_dmy(int day, int month, int year) {
  445. int k = epoch - 1;
  446. k += 365 * (year-1);
  447. //k += CCMath.div(year-1, 4);
  448. //k -= CCMath.div(year-1, 100);
  449. //k += CCMath.div(year-1, 400);
  450. //k += CCMath.div(367*month-362, 12);
  451. k += (year - 1) / 4;
  452. k -= (year - 1) / 100;
  453. k += (year - 1) / 400;
  454. k += (367 * month - 362) / 12;
  455. if (month > 2) {
  456. k -= is_leap_year(year) ? 1 : 2;
  457. }
  458. k += day;
  459. return k;
  460. }
  461. /// <summary>
  462. /// The method computes the Gregorian year from a fixed day number.
  463. /// </summary>
  464. /// <param name="date">The fixed day number.
  465. /// </param>
  466. /// <returns>An integer value giving the Gregorian year of the date.
  467. /// </returns>
  468. public static int year_from_fixed(int date) {
  469. int d = date - epoch;
  470. int n_400 = d / 146097;
  471. d %= 146097;
  472. int n_100 = d / 36524;
  473. d %= 36524;
  474. int n_4 = d / 1461;
  475. d %= 1461;
  476. int n_1 = d / 365;
  477. //int n_400 = CCMath.div_mod(out d, d, 146097);
  478. //int n_100 = CCMath.div_mod(out d, d, 36524);
  479. //int n_4 = CCMath.div_mod(out d, d, 1461);
  480. //int n_1 = CCMath.div(d, 365);
  481. int year = 400*n_400 + 100*n_100 + 4*n_4 + n_1;
  482. return (n_100 == 4 || n_1 == 4) ? year : year + 1;
  483. }
  484. /// <summary>
  485. /// The method computes the Gregorian year and month from a fixed day
  486. /// number.
  487. /// </summary>
  488. /// <param name="month">The output value giving the Gregorian month.
  489. /// </param>
  490. /// <param name="year">The output value giving the Gregorian year.
  491. /// </param>
  492. /// <param name="date">An integer value specifying the fixed day
  493. /// number.</param>
  494. public static void my_from_fixed(out int month, out int year,
  495. int date)
  496. {
  497. year = year_from_fixed(date);
  498. int prior_days = date - fixed_from_dmy(1, (int)Month.january,
  499. year);
  500. int correction;
  501. if (date < fixed_from_dmy(1, (int)Month.march, year)) {
  502. correction = 0;
  503. } else if (is_leap_year(year)) {
  504. correction = 1;
  505. } else {
  506. correction = 2;
  507. }
  508. //month = CCMath.div(12 * (prior_days + correction) + 373, 367);
  509. month = (12 * (prior_days + correction) + 373) / 367;
  510. }
  511. /// <summary>
  512. /// The method computes the Gregorian year, month, and day from a
  513. /// fixed day number.
  514. /// </summary>
  515. /// <param name="day">The output value returning the day of the
  516. /// month.
  517. /// </param>
  518. /// <param name="month">The output value giving the Gregorian month.
  519. /// </param>
  520. /// <param name="year">The output value giving the Gregorian year.
  521. /// </param>
  522. /// <param name="date">An integer value specifying the fixed day
  523. /// number.</param>
  524. public static void dmy_from_fixed(out int day, out int month,
  525. out int year,
  526. int date)
  527. {
  528. my_from_fixed(out month, out year, date);
  529. day = date - fixed_from_dmy(1, month, year) + 1;
  530. }
  531. /// <summary>A method computing the Gregorian month from a fixed
  532. /// day number.
  533. /// </summary>
  534. /// <param name="date">An integer specifying the fixed day number.
  535. /// </param>
  536. /// <returns>An integer value representing the Gregorian month.
  537. /// </returns>
  538. public static int month_from_fixed(int date) {
  539. int month, year;
  540. my_from_fixed(out month, out year, date);
  541. return month;
  542. }
  543. /// <summary>
  544. /// A method computing the day of the month from a fixed day number.
  545. /// </summary>
  546. /// <param name="date">An integer specifying the fixed day number.
  547. /// </param>
  548. /// <returns>An integer value representing the day of the month.
  549. /// </returns>
  550. public static int day_from_fixed(int date) {
  551. int day, month, year;
  552. dmy_from_fixed(out day, out month, out year, date);
  553. return day;
  554. }
  555. /// <summary>
  556. /// The method computes the difference between two Gregorian dates.
  557. /// </summary>
  558. /// <param name="dayA">The integer parameter gives the day of month
  559. /// of the first date.
  560. /// </param>
  561. /// <param name="monthA">The integer parameter gives the Gregorian
  562. /// month of the first date.
  563. /// </param>
  564. /// <param name="yearA">The integer parameter gives the Gregorian
  565. /// year of the first date.
  566. /// </param>
  567. /// <param name="dayB">The integer parameter gives the day of month
  568. /// of the second date.
  569. /// </param>
  570. /// <param name="monthB">The integer parameter gives the Gregorian
  571. /// month of the second date.
  572. /// </param>
  573. /// <param name="yearB">The integer parameter gives the Gregorian
  574. /// year of the second date.
  575. /// </param>
  576. /// <returns>An integer giving the difference of days from the first
  577. /// the second date.
  578. /// </returns>
  579. public static int date_difference(int dayA, int monthA, int yearA,
  580. int dayB, int monthB, int yearB)
  581. {
  582. return fixed_from_dmy(dayB, monthB, yearB) -
  583. fixed_from_dmy(dayA, monthA, yearA);
  584. }
  585. /// <summary>
  586. /// The method computes the number of the day in the year from
  587. /// a Gregorian date.
  588. /// </summary>
  589. /// <param name="day">An integer representing the day of the month,
  590. /// counting from 1.
  591. /// </param>
  592. /// <param name="month">An integer representing the month in the
  593. /// Gregorian year.
  594. /// </param>
  595. /// <param name="year">An integer representing the Gregorian year.
  596. /// Non-positive values are allowed also.
  597. /// </param>
  598. /// <returns>An integer value giving the number of the day in the
  599. /// Gregorian year, counting from 1.
  600. /// </returns>
  601. public static int day_number(int day, int month, int year) {
  602. return date_difference(31, (int)Month.december, year-1,
  603. day, month, year);
  604. }
  605. /// <summary>
  606. /// The method computes the days remaining in the given Gregorian
  607. /// year from a Gregorian date.
  608. /// </summary>
  609. /// <param name="day">An integer representing the day of the month,
  610. /// counting from 1.
  611. /// </param>
  612. /// <param name="month">An integer representing the month in the
  613. /// Gregorian year.
  614. /// </param>
  615. /// <param name="year">An integer representing the Gregorian year.
  616. /// Non-positive values are allowed also.
  617. /// </param>
  618. /// <returns>An integer value giving the number of days remaining in
  619. /// the Gregorian year.
  620. /// </returns>
  621. public static int days_remaining(int day, int month, int year) {
  622. return date_difference(day, month, year,
  623. 31, (int)Month.december, year);
  624. }
  625. // Helper functions for the Gregorian calendars.
  626. /// <summary>
  627. /// Adds months to the given date.
  628. /// </summary>
  629. /// <param name="time">The
  630. /// <see cref="T:System.DateTime"/> to which to add
  631. /// months.
  632. /// </param>
  633. /// <param name="months">The number of months to add.</param>
  634. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  635. /// results from adding <paramref name="months"/> to the specified
  636. /// DateTime.</returns>
  637. public static System.DateTime AddMonths(System.DateTime time,
  638. int months)
  639. {
  640. int rd = CCFixed.FromDateTime(time);
  641. int day, month, year;
  642. dmy_from_fixed(out day, out month, out year, rd);
  643. month += months;
  644. int maxday = GetDaysInMonth (year, month);
  645. if (day > maxday)
  646. day = maxday;
  647. rd = fixed_from_dmy(day, month, year);
  648. System.DateTime t = CCFixed.ToDateTime(rd);
  649. return t.Add(time.TimeOfDay);
  650. }
  651. /// <summary>
  652. /// Adds years to the given date.
  653. /// </summary>
  654. /// <param name="time">The
  655. /// <see cref="T:System.DateTime"/> to which to add
  656. /// months.
  657. /// </param>
  658. /// <param name="years">The number of years to add.</param>
  659. /// <returns>A new <see cref="T:System.DateTime"/> value, that
  660. /// results from adding <paramref name="years"/> to the specified
  661. /// DateTime.</returns>
  662. public static System.DateTime AddYears(System.DateTime time,
  663. int years)
  664. {
  665. int rd = CCFixed.FromDateTime(time);
  666. int day, month, year;
  667. dmy_from_fixed(out day, out month, out year, rd);
  668. year += years;
  669. int maxday = GetDaysInMonth (year, month);
  670. if (day > maxday)
  671. day = maxday;
  672. rd = fixed_from_dmy(day, month, year);
  673. System.DateTime t = CCFixed.ToDateTime(rd);
  674. return t.Add(time.TimeOfDay);
  675. }
  676. /// <summary>
  677. /// Gets the of the month from <paramref name="time"/>.
  678. /// </summary>
  679. /// <param name="time">The
  680. /// <see cref="T:System.DateTime"/> that specifies a
  681. /// date.
  682. /// </param>
  683. /// <returns>An integer giving the day of months, starting with 1.
  684. /// </returns>
  685. public static int GetDayOfMonth(System.DateTime time) {
  686. return day_from_fixed(CCFixed.FromDateTime(time));
  687. }
  688. /// <summary>
  689. /// The method gives the number of the day in the year.
  690. /// </summary>
  691. /// <param name="time">The
  692. /// <see cref="T:System.DateTime"/> that specifies a
  693. /// date.
  694. /// </param>
  695. /// <returns>An integer representing the day of the year,
  696. /// starting with 1.</returns>
  697. public static int GetDayOfYear(System.DateTime time) {
  698. int rd = CCFixed.FromDateTime(time);
  699. int year = year_from_fixed(rd);
  700. int rd1_1 = fixed_from_dmy(1, 1, year);
  701. return rd - rd1_1 + 1;
  702. }
  703. /// <summary>
  704. /// A method that gives the number of days of the specified
  705. /// month of the <paramref name="year"/>.
  706. /// </summary>
  707. /// <param name="year">An integer that gives the year in the current
  708. /// era.</param>
  709. /// <param name="month">An integer that gives the month, starting
  710. /// with 1.</param>
  711. /// <returns>An integer that gives the number of days of the
  712. /// specified month.</returns>
  713. public static int GetDaysInMonth(int year, int month) {
  714. int rd1 = fixed_from_dmy(1, month, year);
  715. int rd2 = fixed_from_dmy(1, month+1, year);
  716. return rd2 - rd1;
  717. }
  718. /// <summary>
  719. /// The method gives the number of days in the specified year.
  720. /// </summary>
  721. /// <param name="year">An integer that gives the year.
  722. /// </param>
  723. /// <returns>An integer that gives the number of days of the
  724. /// specified year.</returns>
  725. public static int GetDaysInYear(int year) {
  726. int rd1 = fixed_from_dmy(1, 1, year);
  727. int rd2 = fixed_from_dmy(1, 1, year+1);
  728. return rd2 - rd1;
  729. }
  730. /// <summary>
  731. /// The method gives the number of the month of the specified
  732. /// date.
  733. /// </summary>
  734. /// <param name="time">The
  735. /// <see cref="T:System.DateTime"/> that specifies a
  736. /// date.
  737. /// </param>
  738. /// <returns>An integer representing the month,
  739. /// starting with 1.</returns>
  740. public static int GetMonth(System.DateTime time) {
  741. return month_from_fixed(CCFixed.FromDateTime(time));
  742. }
  743. /// <summary>
  744. /// The method gives the number of the year of the specified
  745. /// date.
  746. /// </summary>
  747. /// <param name="time">The
  748. /// <see cref="T:System.DateTime"/> that specifies a
  749. /// date.
  750. /// </param>
  751. /// <returns>An integer representing the year.
  752. /// </returns>
  753. public static int GetYear(System.DateTime time) {
  754. return year_from_fixed(CCFixed.FromDateTime(time));
  755. }
  756. /// <summary>
  757. /// A virtual method that tells whether the given day
  758. /// is a leap day.
  759. /// </summary>
  760. /// <param name="year">An integer that specifies the year.
  761. /// </param>
  762. /// <param name="month">An integer that specifies the month.
  763. /// </param>
  764. /// <param name="day">An integer that specifies the day.
  765. /// </param>
  766. /// <returns>A boolean that tells whether the given day is a leap
  767. /// day.
  768. /// </returns>
  769. public static bool IsLeapDay(int year, int month, int day) {
  770. return is_leap_year(year) && month == 2 && day == 29;
  771. }
  772. /// <summary>
  773. /// A method that creates the
  774. /// <see cref="T:System.DateTime"/> from the parameters.
  775. /// </summary>
  776. /// <param name="year">An integer that gives the year
  777. /// </param>
  778. /// <param name="month">An integer that specifies the month.
  779. /// </param>
  780. /// <param name="day">An integer that specifies the day.
  781. /// </param>
  782. /// <param name="hour">An integer that specifies the hour.
  783. /// </param>
  784. /// <param name="minute">An integer that specifies the minute.
  785. /// </param>
  786. /// <param name="second">An integer that gives the second.
  787. /// </param>
  788. /// <param name="milliseconds">An integer that gives the
  789. /// milliseconds.
  790. /// </param>
  791. /// <returns>A
  792. /// <see cref="T:system.DateTime"/> representig the date and time.
  793. /// </returns>
  794. public static System.DateTime ToDateTime(int year, int month, int day,
  795. int hour, int minute, int second, int milliseconds)
  796. {
  797. return CCFixed.ToDateTime(fixed_from_dmy(day, month, year),
  798. hour, minute, second, milliseconds);
  799. }
  800. } // class CCGregorianCalendar
  801. /*
  802. /// <summary>
  803. /// A class encapsulating the functions of the Julian calendar as static
  804. /// methods.
  805. /// </summary>
  806. /// <remarks>
  807. /// <para>The algorithms don't support a year 0. Years before Common Era
  808. /// (B.C.E. or B.C.) are negative and years of Common Era (C.E. or A.D.)
  809. /// are positive.
  810. /// </para>
  811. /// <para>
  812. /// This class is not compatible to
  813. /// <see cref="T:System.Globalization.JulianCalendar"/>.
  814. /// </para>
  815. /// <seealso cref="T:CCFixed"/>
  816. /// </remarks>
  817. internal class CCJulianCalendar {
  818. /// <summary>An integer defining the epoch of the Julian calendar
  819. /// as fixed day number.</summary>
  820. /// <remarks>The epoch is December 30, 0 (Gregorian).</remarks>
  821. const int epoch = -1; // 30. 12. 0 Gregorian
  822. /// <summary>The enumeration defines the months of the Julian
  823. /// calendar.
  824. /// </summary>
  825. public enum Month {
  826. /// <summary>
  827. /// January.
  828. /// </summary>
  829. january = 1,
  830. /// <summary>
  831. /// February.
  832. /// </summary>
  833. february,
  834. /// <summary>
  835. /// March.
  836. /// </summary>
  837. march,
  838. /// <summary>
  839. /// April.
  840. /// </summary>
  841. april,
  842. /// <summary>
  843. /// May.
  844. /// </summary>
  845. may,
  846. /// <summary>
  847. /// June.
  848. /// </summary>
  849. june,
  850. /// <summary>
  851. /// July.
  852. /// </summary>
  853. july,
  854. /// <summary>
  855. /// August.
  856. /// </summary>
  857. august,
  858. /// <summary>
  859. /// September.
  860. /// </summary>
  861. september,
  862. /// <summary>
  863. /// October.
  864. /// </summary>
  865. october,
  866. /// <summary>
  867. /// November.
  868. /// </summary>
  869. november,
  870. /// <summary>
  871. /// December.
  872. /// </summary>
  873. december
  874. };
  875. /// <summary>
  876. /// The method tells whether the year is a leap year.
  877. /// </summary>
  878. /// <param name="year">An integer representing the Julian year.
  879. /// </param>
  880. /// <returns>A boolean which is true if <paramref name="year"/> is
  881. /// a leap year.
  882. /// </returns>
  883. public static bool is_leap_year(int year) {
  884. return CCMath.mod(year, 4) == (year > 0 ? 0 : 3);
  885. }
  886. /// <summary>
  887. /// The method returns the fixed day number of the given Julian
  888. /// date.
  889. /// </summary>
  890. /// <param name="day">An integer representing the day of the month,
  891. /// counting from 1.
  892. /// </param>
  893. /// <param name="month">An integer representing the month in the
  894. /// Julian year.
  895. /// </param>
  896. /// <param name="year">An integer representing the Julian year.
  897. /// Positive and Negative values are allowed.
  898. /// </param>
  899. /// <returns>An integer value representing the fixed day number.
  900. /// </returns>
  901. public static int fixed_from_dmy(int day, int month, int year) {
  902. int y = year < 0 ? year+1 : year;
  903. int k = epoch - 1;
  904. k += 365 * (y-1);
  905. k += CCMath.div(y-1, 4);
  906. k += CCMath.div(367*month-362, 12);
  907. if (month > 2) {
  908. k += is_leap_year(year) ? -1 : -2;
  909. }
  910. k += day;
  911. return k;
  912. }
  913. /// <summary>
  914. /// The method computes the Julian year from a fixed day number.
  915. /// </summary>
  916. /// <param name="date">The fixed day number.
  917. /// </param>
  918. /// <returns>An integer value giving the Julian year of the date.
  919. /// </returns>
  920. public static int year_from_fixed(int date) {
  921. int approx = CCMath.div(4*(date-epoch)+1464, 1461);
  922. return approx <= 0 ? approx - 1 : approx;
  923. }
  924. /// <summary>
  925. /// The method computes the Julian year and month from a fixed day
  926. /// number.
  927. /// </summary>
  928. /// <param name="month">The output value giving the Julian month.
  929. /// </param>
  930. /// <param name="year">The output value giving the Julian year.
  931. /// </param>
  932. /// <param name="date">An integer value specifying the fixed day
  933. /// number.</param>
  934. public static void my_from_fixed(out int month, out int year, int date)
  935. {
  936. year = year_from_fixed(date);
  937. int prior_days = date - fixed_from_dmy(1, (int)Month.january,
  938. year);
  939. int correction;
  940. if (date < fixed_from_dmy(1, (int)Month.march, year)) {
  941. correction = 0;
  942. } else if (is_leap_year(year)) {
  943. correction = 1;
  944. } else {
  945. correction = 2;
  946. }
  947. month = CCMath.div(12 * (prior_days + correction) + 373, 367);
  948. }
  949. /// <summary>
  950. /// The method computes the Julian year, month, and day from a
  951. /// fixed day number.
  952. /// </summary>
  953. /// <param name="day">The output value returning the day of the
  954. /// month.
  955. /// </param>
  956. /// <param name="month">The output value giving the Julian month.
  957. /// </param>
  958. /// <param name="year">The output value giving the Julian year.
  959. /// </param>
  960. /// <param name="date">An integer value specifying the fixed day
  961. /// number.</param>
  962. public static void dmy_from_fixed(out int day, out int month,
  963. out int year, int date)
  964. {
  965. my_from_fixed(out month, out year, date);
  966. day = date - fixed_from_dmy(1, month, year) + 1;
  967. }
  968. /// <summary>A method computing the Julian month from a fixed
  969. /// day number.
  970. /// </summary>
  971. /// <param name="date">An integer specifying the fixed day number.
  972. /// </param>
  973. /// <returns>An integer value representing the Julian month.
  974. /// </returns>
  975. public static int month_from_fixed(int date) {
  976. int month, year;
  977. my_from_fixed(out month, out year, date);
  978. return month;
  979. }
  980. /// <summary>
  981. /// A method computing the day of the month from a fixed day number.
  982. /// </summary>
  983. /// <param name="date">An integer specifying the fixed day number.
  984. /// </param>
  985. /// <returns>An integer value representing the day of the month.
  986. /// </returns>
  987. public static int day_from_fixed(int date) {
  988. int day;
  989. int month;
  990. int year;
  991. dmy_from_fixed(out day, out month, out year, date);
  992. return day;
  993. }
  994. /// <summary>
  995. /// The method computes the difference between two Julian dates.
  996. /// </summary>
  997. /// <param name="dayA">The integer parameter gives the day of month
  998. /// of the first date.
  999. /// </param>
  1000. /// <param name="monthA">The integer parameter gives the Julian
  1001. /// month of the first date.
  1002. /// </param>
  1003. /// <param name="yearA">The integer parameter gives the Julian
  1004. /// year of the first date.
  1005. /// </param>
  1006. /// <param name="dayB">The integer parameter gives the day of month
  1007. /// of the second date.
  1008. /// </param>
  1009. /// <param name="monthB">The integer parameter gives the Julian
  1010. /// month of the second date.
  1011. /// </param>
  1012. /// <param name="yearB">The integer parameter gives the Julian
  1013. /// year of the second date.
  1014. /// </param>
  1015. /// <returns>An integer giving the difference of days from the first
  1016. /// the second date.
  1017. /// </returns>
  1018. public static int date_difference(int dayA, int monthA, int yearA,
  1019. int dayB, int monthB, int yearB)
  1020. {
  1021. return fixed_from_dmy(dayB, monthB, yearB) -
  1022. fixed_from_dmy(dayA, monthA, yearA);
  1023. }
  1024. /// <summary>
  1025. /// The method computes the number of the day in the year from
  1026. /// a Julian date.
  1027. /// </summary>
  1028. /// <param name="day">An integer representing the day of the month,
  1029. /// counting from 1.
  1030. /// </param>
  1031. /// <param name="month">An integer representing the month in the
  1032. /// Julian year.
  1033. /// </param>
  1034. /// <param name="year">An integer representing the Julian year.
  1035. /// Negative values are allowed also.
  1036. /// </param>
  1037. /// <returns>An integer value giving the number of the day in the
  1038. /// Julian year, counting from 1.
  1039. /// </returns>
  1040. public static int day_number(int day, int month, int year) {
  1041. return date_difference(31, (int)Month.december, year-1,
  1042. day, month, year);
  1043. }
  1044. /// <summary>
  1045. /// The method computes the days remaining in the given Julian
  1046. /// year from a Julian date.
  1047. /// </summary>
  1048. /// <param name="day">An integer representing the day of the month,
  1049. /// counting from 1.
  1050. /// </param>
  1051. /// <param name="month">An integer representing the month in the
  1052. /// Julian year.
  1053. /// </param>
  1054. /// <param name="year">An integer representing the Julian year.
  1055. /// Negative values are allowed also.
  1056. /// </param>
  1057. /// <returns>An integer value giving the number of days remaining in
  1058. /// the Julian year.
  1059. /// </returns>
  1060. public static int days_remaining(int day, int month, int year) {
  1061. return date_difference(day, month, year,
  1062. 31, (int)Month.december, year);
  1063. }
  1064. } // class CCJulianCalendar
  1065. /// <summary>
  1066. /// A class encapsulating the functions of the Hebrew calendar as static
  1067. /// methods.
  1068. /// </summary>
  1069. /// <remarks>
  1070. /// <para>
  1071. /// This class is not compatible to
  1072. /// <see cref="T:System.Globalization.HebrewCalendar"/>.
  1073. /// </para>
  1074. /// <seealso cref="T:CCFixed"/>
  1075. /// </remarks>
  1076. internal class CCHebrewCalendar {
  1077. /// <summary>An integer defining the epoch of the Hebrew calendar
  1078. /// as fixed day number.</summary>
  1079. /// <remarks>The epoch is October 10, 3761 B.C.E. (Julian).</remarks>
  1080. const int epoch = -1373427;
  1081. /// <summary>The enumeration defines the months of the Gregorian
  1082. /// calendar.
  1083. /// </summary>
  1084. /// <remarks>
  1085. /// The enumaration differs from .NET which defines Tishri as month 1.
  1086. /// </remarks>
  1087. public enum Month {
  1088. /// <summary>
  1089. /// Nisan.
  1090. /// </summary>
  1091. nisan = 1,
  1092. /// <summary>
  1093. /// Iyyar.
  1094. /// </summary>
  1095. iyyar,
  1096. /// <summary>
  1097. /// Sivan.
  1098. /// </summary>
  1099. sivan,
  1100. /// <summary>
  1101. /// Tammuz.
  1102. /// </summary>
  1103. tammuz,
  1104. /// <summary>
  1105. /// Av.
  1106. /// </summary>
  1107. av,
  1108. /// <summary>
  1109. /// Elul.
  1110. /// </summary>
  1111. elul,
  1112. /// <summary>
  1113. /// Tishri.
  1114. /// </summary>
  1115. tishri,
  1116. /// <summary>
  1117. /// Heshvan.
  1118. /// </summary>
  1119. heshvan,
  1120. /// <summary>
  1121. /// Kislev.
  1122. /// </summary>
  1123. kislev,
  1124. /// <summary>
  1125. /// Teveth.
  1126. /// </summary>
  1127. teveth,
  1128. /// <summary>
  1129. /// Shevat.
  1130. /// </summary>
  1131. shevat,
  1132. /// <summary>
  1133. /// Adar.
  1134. /// </summary>
  1135. adar,
  1136. /// <summary>
  1137. /// Adar I. Only in years with Adar II.
  1138. /// </summary>
  1139. adar_I = 12,
  1140. /// <summary>
  1141. /// Adar II. Only in years wirh Adar I.
  1142. /// </summary>
  1143. adar_II = 13,
  1144. };
  1145. /// <summary>
  1146. /// The method tells whether the year is a leap year.
  1147. /// </summary>
  1148. /// <param name="year">An integer representing the Hebrew year.
  1149. /// </param>
  1150. /// <returns>A boolean which is true if <paramref name="year"/> is
  1151. /// a leap year.
  1152. /// </returns>
  1153. public static bool is_leap_year(int year) {
  1154. return CCMath.mod(7*year+1, 19) < 7;
  1155. }
  1156. /// <summary>
  1157. /// The Method gives the number of the last month in a year, which
  1158. /// is equal with the number of month in a Hebrew year.
  1159. /// </summary>
  1160. /// <param name="year">An integer representing the Hebrew year.
  1161. /// </param>
  1162. /// <returns>An integer giving the number of the last month of the
  1163. /// Hebrew year, which is the same as the numbers of month in the
  1164. /// year.
  1165. /// </returns>
  1166. public static int last_month_of_year(int year) {
  1167. return is_leap_year(year) ? 13 : 12;
  1168. }
  1169. /// <summary>The method is a helper function.</summary>
  1170. /// <param name="year">An integer specifying the Hebrew year.
  1171. /// </param>
  1172. /// <returns>An integer representing the number of elapsed days
  1173. /// until the Hebrew year.</returns>
  1174. public static int elapsed_days(int year) {
  1175. int months_elapsed = CCMath.div(235*year-234, 19);
  1176. int r;
  1177. int d = CCMath.div_mod(out r, months_elapsed, 1080);
  1178. int parts_elapsed = 204 + 793 * r;
  1179. int hours_elapsed = 11 + 12 * months_elapsed +
  1180. 793 * d + CCMath.div(parts_elapsed, 1080);
  1181. int day = 29*months_elapsed + CCMath.div(hours_elapsed, 24);
  1182. if (CCMath.mod(3*(day+1), 7) < 3) {
  1183. day += 1;
  1184. }
  1185. return day;
  1186. }
  1187. /// <summary>A method computing the delay of new year for the given
  1188. /// Hebrew year.
  1189. /// </summary>
  1190. /// <param name="year">An integer that gives the Hebrew year.
  1191. /// </param>
  1192. /// <returns>The new year delay in days of the given Hebrew year.
  1193. /// </returns>
  1194. public static int new_year_delay(int year) {
  1195. int ny1 = elapsed_days(year);
  1196. int ny2 = elapsed_days(year+1);
  1197. if (ny2 - ny1 == 356) {
  1198. return 2;
  1199. }
  1200. int ny0 = elapsed_days(year-1);
  1201. if (ny1 - ny0 == 382) {
  1202. return 1;
  1203. }
  1204. return 0;
  1205. }
  1206. /// <summary>
  1207. /// The method computes the last day of month (nummer of days in a
  1208. /// month) of the given Hebrew year.
  1209. /// </summary>
  1210. /// <param name="month">The Hebrew month, allowed value between
  1211. /// One and Thirteen.
  1212. /// </param>
  1213. /// <param name="year">An integer that gives the Hebrew year.
  1214. /// </param>
  1215. /// <returns>The number of the last day of the month of the given
  1216. /// Hebrew year, which gives automatically the number of days in the
  1217. /// month.
  1218. /// </returns>
  1219. /// <exception cref="T:System.ArgumentOutOfRange.Exception">
  1220. /// The exception is thrown if month not between One and Thirteen.
  1221. /// </exception>
  1222. public static int last_day_of_month(int month, int year) {
  1223. if (month < 1 || month > 13)
  1224. throw new System.ArgumentOutOfRangeException("month",
  1225. "Month should be between One and Thirteen.");
  1226. switch (month) {
  1227. case 2: return 29;
  1228. case 4: return 29;
  1229. case 6: return 29;
  1230. case 8:
  1231. if (!long_heshvan(year))
  1232. return 29;
  1233. break;
  1234. case 9:
  1235. if (short_kislev(year))
  1236. return 29;
  1237. break;
  1238. case 10: return 29;
  1239. case 12:
  1240. if (!is_leap_year(year))
  1241. return 29;
  1242. break;
  1243. case 13: return 29;
  1244. }
  1245. return 30;
  1246. }
  1247. /// <summary>
  1248. /// The functions checks whether the month Heshvan is a long one
  1249. /// in the given Hebrew year.
  1250. /// </summary>
  1251. /// <param name="year">An integer that gives the Hebrew year.
  1252. /// </param>
  1253. /// <returns>A boolean value: true if there is a long Heshvan
  1254. /// in the given Hebrew year; false otherwise.
  1255. /// </returns>
  1256. public static bool long_heshvan(int year) {
  1257. return CCMath.mod(days_in_year(year), 10) == 5;
  1258. }
  1259. /// <summary>
  1260. /// The functions checks whether the month Kislev is a short one
  1261. /// in the given Hebrew year.
  1262. /// </summary>
  1263. /// <param name="year">An integer that gives the Hebrew year.
  1264. /// </param>
  1265. /// <returns>A boolean value: true if there is a short Kislev
  1266. /// in the given Hebrew year; false otherwise.
  1267. /// </returns>
  1268. public static bool short_kislev(int year) {
  1269. return CCMath.mod(days_in_year(year), 10) == 3;
  1270. }
  1271. /// <summary>
  1272. /// The functions gives the number of days in the specified Hebrew
  1273. /// year.
  1274. /// </summary>
  1275. /// <param name="year">An integer that gives the Hebrew year.
  1276. /// </param>
  1277. /// <returns>The days of the Hebrew year as integer.
  1278. /// </returns>
  1279. public static int days_in_year(int year) {
  1280. return fixed_from_dmy(1, 7, year+1) -
  1281. fixed_from_dmy(1, 7, year);
  1282. }
  1283. /// <summary>
  1284. /// The method returns the fixed day number of the given Hebrew
  1285. /// date.
  1286. /// </summary>
  1287. /// <param name="day">An integer representing the day of the month,
  1288. /// counting from 1.
  1289. /// </param>
  1290. /// <param name="month">An integer representing the month in the
  1291. /// Hebrew year.
  1292. /// </param>
  1293. /// <param name="year">An integer representing the Hebrew year.
  1294. /// Non-positive values are allowed also.
  1295. /// </param>
  1296. /// <returns>An integer value representing the fixed day number.
  1297. /// </returns>
  1298. public static int fixed_from_dmy(int day, int month, int year) {
  1299. int m;
  1300. int k = epoch-1;
  1301. k += elapsed_days(year);
  1302. k += new_year_delay(year);
  1303. if (month < 7) {
  1304. int l = last_month_of_year(year);
  1305. for (m = 7; m <= l; m++) {
  1306. k += last_day_of_month(m, year);
  1307. }
  1308. for (m = 1; m < month; m++) {
  1309. k += last_day_of_month(m, year);
  1310. }
  1311. }
  1312. else {
  1313. for (m = 7; m < month; m++) {
  1314. k += last_day_of_month(m, year);
  1315. }
  1316. }
  1317. k += day;
  1318. return k;
  1319. }
  1320. /// <summary>
  1321. /// The method computes the Hebrew year from a fixed day number.
  1322. /// </summary>
  1323. /// <param name="date">The fixed day number.
  1324. /// </param>
  1325. /// <returns>An integer value giving the Hebrew year of the date.
  1326. /// </returns>
  1327. public static int year_from_fixed(int date) {
  1328. int approx = (int)System.Math.Floor(
  1329. ((double)(date - epoch))/(35975351.0/98496.0));
  1330. int y;
  1331. for (y = approx; date >= fixed_from_dmy(1, 7, y); y++) {}
  1332. return y-1;
  1333. }
  1334. /// <summary>
  1335. /// The method computes the Hebrew year and month from a fixed day
  1336. /// number.
  1337. /// </summary>
  1338. /// <param name="month">The output value giving the Hebrew month.
  1339. /// </param>
  1340. /// <param name="year">The output value giving the Hebrew year.
  1341. /// </param>
  1342. /// <param name="date">An integer value specifying the fixed day
  1343. /// number.</param>
  1344. public static void my_from_fixed(out int month, out int year,
  1345. int date)
  1346. {
  1347. year = year_from_fixed(date);
  1348. int start = date < fixed_from_dmy(1, 1, year) ? 7 : 1;
  1349. for (month = start;
  1350. date > fixed_from_dmy(last_day_of_month(month, year),
  1351. month, year);
  1352. month++)
  1353. {}
  1354. }
  1355. /// <summary>
  1356. /// The method computes the Hebrew year, month, and day from a
  1357. /// fixed day number.
  1358. /// </summary>
  1359. /// <param name="day">The output value returning the day of the
  1360. /// month.
  1361. /// </param>
  1362. /// <param name="month">The output value giving the Hebrew month.
  1363. /// </param>
  1364. /// <param name="year">The output value giving the Hebrew year.
  1365. /// </param>
  1366. /// <param name="date">An integer value specifying the fixed day
  1367. /// number.</param>
  1368. public static void dmy_from_fixed(out int day, out int month,
  1369. out int year, int date)
  1370. {
  1371. my_from_fixed(out month, out year, date);
  1372. day = date - fixed_from_dmy(1, month, year) + 1;
  1373. }
  1374. /// <summary>A method computing the Hebrew month from a fixed
  1375. /// day number.
  1376. /// </summary>
  1377. /// <param name="date">An integer specifying the fixed day number.
  1378. /// </param>
  1379. /// <returns>An integer value representing the Hebrew month.
  1380. /// </returns>
  1381. public static int month_from_fixed(int date) {
  1382. int month, year;
  1383. my_from_fixed(out month, out year, date);
  1384. return month;
  1385. }
  1386. /// <summary>
  1387. /// A method computing the day of the month from a fixed day number.
  1388. /// </summary>
  1389. /// <param name="date">An integer specifying the fixed day number.
  1390. /// </param>
  1391. /// <returns>An integer value representing the day of the month.
  1392. /// </returns>
  1393. public static int day_from_fixed(int date) {
  1394. int day, month, year;
  1395. dmy_from_fixed(out day, out month, out year, date);
  1396. return day;
  1397. }
  1398. /// <summary>
  1399. /// The method computes the difference between two Hebrew dates.
  1400. /// </summary>
  1401. /// <param name="dayA">The integer parameter gives the day of month
  1402. /// of the first date.
  1403. /// </param>
  1404. /// <param name="monthA">The integer parameter gives the Hebrew
  1405. /// month of the first date.
  1406. /// </param>
  1407. /// <param name="yearA">The integer parameter gives the Hebrew
  1408. /// year of the first date.
  1409. /// </param>
  1410. /// <param name="dayB">The integer parameter gives the day of month
  1411. /// of the second date.
  1412. /// </param>
  1413. /// <param name="monthB">The integer parameter gives the Hebrew
  1414. /// month of the second date.
  1415. /// </param>
  1416. /// <param name="yearB">The integer parameter gives the Hebrew
  1417. /// year of the second date.
  1418. /// </param>
  1419. /// <returns>An integer giving the difference of days from the first
  1420. /// the second date.
  1421. /// </returns>
  1422. public static int date_difference(int dayA, int monthA, int yearA,
  1423. int dayB, int monthB, int yearB)
  1424. {
  1425. return fixed_from_dmy(dayB, monthB, yearB) -
  1426. fixed_from_dmy(dayA, monthA, yearA);
  1427. }
  1428. /// <summary>
  1429. /// The method computes the number of the day in the year from
  1430. /// a Hebrew date.
  1431. /// </summary>
  1432. /// <param name="day">An integer representing the day of the month,
  1433. /// counting from 1.
  1434. /// </param>
  1435. /// <param name="month">An integer representing the month in the
  1436. /// Hebrew year.
  1437. /// </param>
  1438. /// <param name="year">An integer representing the Hebrew year.
  1439. /// </param>
  1440. /// <returns>An integer value giving the number of the day in the
  1441. /// Hebrew year, counting from 1.
  1442. /// </returns>
  1443. public static int day_number(int day, int month, int year) {
  1444. return date_difference(1, 7, year,
  1445. day, month, year) + 1;
  1446. }
  1447. /// <summary>
  1448. /// The method computes the days remaining in the given Hebrew
  1449. /// year from a Hebrew date.
  1450. /// </summary>
  1451. /// <param name="day">An integer representing the day of the month,
  1452. /// counting from 1.
  1453. /// </param>
  1454. /// <param name="month">An integer representing the month in the
  1455. /// Hebrew year.
  1456. /// </param>
  1457. /// <param name="year">An integer representing the Hebrew year.
  1458. /// </param>
  1459. /// <returns>An integer value giving the number of days remaining in
  1460. /// the Hebrew year.
  1461. /// </returns>
  1462. public static int days_remaining(int day, int month, int year) {
  1463. return date_difference(day, month, year,
  1464. 1, 7, year+1)-1;
  1465. }
  1466. } // class HebrewCalendar
  1467. /// <summary>
  1468. /// A class encapsulating the functions of the Islamic calendar as static
  1469. /// methods.
  1470. /// </summary>
  1471. /// <remarks>
  1472. /// <para>There is no difference here in using Hijri or Islamic calendar.
  1473. /// </para>
  1474. /// <para>The epoch of the Islamic calendar isn't fixed, because we cannot
  1475. /// surely say today, when the crescent of the new moon has been observed
  1476. /// around the July 16, 622 C.E. Julian. Even today the start and end of
  1477. /// the month Ramadan is defined by religous authorities. So the calendar
  1478. /// can be offset by two days.
  1479. /// </para>
  1480. /// <para>
  1481. /// We don't support the offset here, however we changed the epoch from
  1482. /// "Calendrical Calculations" to value, that .Net seems to be using.
  1483. /// </para>
  1484. /// <para>
  1485. /// This class is not compatible to
  1486. /// <see cref="T:System.Globalization.HijriCalendar"/>.
  1487. /// </para>
  1488. /// <seealso cref="T:CCFixed"/>
  1489. /// </remarks>
  1490. internal class CCHijriCalendar {
  1491. /// <summary>An integer defining the epoch of the Gregorian calendar
  1492. /// as fixed day number.</summary>
  1493. /// <remarks>
  1494. /// <para>
  1495. /// The epoch is given as 16 July 622 C.E. Julian (R.D. 227015)
  1496. /// in Calendrical Calculations, the approximate date of
  1497. /// the emigration of
  1498. /// Muhammed to Medina. However there is no way to determine today
  1499. /// the observation of the crescent of the new moon in July 622 C.E.
  1500. /// (Julian). So there is some variability in the epoch.
  1501. /// Religous authorities determine the epoch by observing the
  1502. /// crescent of the new moon for the month Ramadan, so there might
  1503. /// be an offsets by two days of the epoch.
  1504. /// </para>
  1505. /// <para>Windows
  1506. /// supports an AddHijriDate parameter in the registry to adapt
  1507. /// for it. It seems that the .NET implementation of
  1508. /// HijriCalendar uses an epoch of 227014, so we use it here. The
  1509. /// ArgumentOutOfRangeException gives July, 18 622 as epoch,
  1510. /// which is 227014 supporting our theory.
  1511. /// </para>
  1512. /// </remarks>
  1513. const int epoch = 227014;
  1514. /// <summary>The enumeration defines the months of the Islamic
  1515. /// calendar.
  1516. /// </summary>
  1517. public enum Month {
  1518. /// <summary>
  1519. /// Muharram.
  1520. /// </summary>
  1521. muharram = 1,
  1522. /// <summary>
  1523. /// Safar.
  1524. /// </summary>
  1525. safar,
  1526. /// <summary>
  1527. /// Rabi I.
  1528. /// </summary>
  1529. rabi_I,
  1530. /// <summary>
  1531. /// Rabi II.
  1532. /// </summary>
  1533. rabi_II,
  1534. /// <summary>
  1535. /// Jumada I.
  1536. /// </summary>
  1537. jumada_I,
  1538. /// <summary>
  1539. /// Jumada II.
  1540. /// </summary>…

Large files files are truncated, but you can click here to view the full file