islamcal.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. ********************************************************************************
  5. * Copyright (C) 2003-2013, International Business Machines Corporation
  6. * and others. All Rights Reserved.
  7. ******************************************************************************
  8. *
  9. * File ISLAMCAL.H
  10. *
  11. * Modification History:
  12. *
  13. * Date Name Description
  14. * 10/14/2003 srl ported from java IslamicCalendar
  15. *****************************************************************************
  16. */
  17. #ifndef ISLAMCAL_H
  18. #define ISLAMCAL_H
  19. #include "unicode/utypes.h"
  20. #if !UCONFIG_NO_FORMATTING
  21. #include "unicode/calendar.h"
  22. U_NAMESPACE_BEGIN
  23. /**
  24. * <code>IslamicCalendar</code> is a subclass of <code>Calendar</code>
  25. * that implements the Islamic civil and religious calendars. It
  26. * is used as the civil calendar in most of the Arab world and the
  27. * liturgical calendar of the Islamic faith worldwide. This calendar
  28. * is also known as the "Hijri" calendar, since it starts at the time
  29. * of Mohammed's emigration (or "hijra") to Medinah on Thursday,
  30. * July 15, 622 AD (Julian).
  31. * <p>
  32. * The Islamic calendar is strictly lunar, and thus an Islamic year of twelve
  33. * lunar months does not correspond to the solar year used by most other
  34. * calendar systems, including the Gregorian. An Islamic year is, on average,
  35. * about 354 days long, so each successive Islamic year starts about 11 days
  36. * earlier in the corresponding Gregorian year.
  37. * <p>
  38. * Each month of the calendar starts when the new moon's crescent is visible
  39. * at sunset. However, in order to keep the time fields in this class
  40. * synchronized with those of the other calendars and with local clock time,
  41. * we treat days and months as beginning at midnight,
  42. * roughly 6 hours after the corresponding sunset.
  43. * <p>
  44. * There are two main variants of the Islamic calendar in existence. The first
  45. * is the <em>civil</em> calendar, which uses a fixed cycle of alternating 29-
  46. * and 30-day months, with a leap day added to the last month of 11 out of
  47. * every 30 years. This calendar is easily calculated and thus predictable in
  48. * advance, so it is used as the civil calendar in a number of Arab countries.
  49. * This is the default behavior of a newly-created <code>IslamicCalendar</code>
  50. * object.
  51. * <p>
  52. * The Islamic <em>religious</em> calendar, however, is based on the <em>observation</em>
  53. * of the crescent moon. It is thus affected by the position at which the
  54. * observations are made, seasonal variations in the time of sunset, the
  55. * eccentricities of the moon's orbit, and even the weather at the observation
  56. * site. This makes it impossible to calculate in advance, and it causes the
  57. * start of a month in the religious calendar to differ from the civil calendar
  58. * by up to three days.
  59. * <p>
  60. * Using astronomical calculations for the position of the sun and moon, the
  61. * moon's illumination, and other factors, it is possible to determine the start
  62. * of a lunar month with a fairly high degree of certainty. However, these
  63. * calculations are extremely complicated and thus slow, so most algorithms,
  64. * including the one used here, are only approximations of the true astronical
  65. * calculations. At present, the approximations used in this class are fairly
  66. * simplistic; they will be improved in later versions of the code.
  67. * <p>
  68. * The {@link #setCivil setCivil} method determines
  69. * which approach is used to determine the start of a month. By default, the
  70. * fixed-cycle civil calendar is used. However, if <code>setCivil(false)</code>
  71. * is called, an approximation of the true lunar calendar will be used.
  72. *
  73. * @see GregorianCalendar
  74. *
  75. * @author Laura Werner
  76. * @author Alan Liu
  77. * @author Steven R. Loomis
  78. * @internal
  79. */
  80. class U_I18N_API IslamicCalendar : public Calendar {
  81. public:
  82. //-------------------------------------------------------------------------
  83. // Constants...
  84. //-------------------------------------------------------------------------
  85. /**
  86. * Calendar type - civil or religious or um alqura
  87. * @internal
  88. */
  89. enum ECalculationType {
  90. ASTRONOMICAL,
  91. CIVIL,
  92. UMALQURA,
  93. TBLA
  94. };
  95. /**
  96. * Constants for the months
  97. * @internal
  98. */
  99. enum EMonths {
  100. /**
  101. * Constant for Muharram, the 1st month of the Islamic year.
  102. * @internal
  103. */
  104. MUHARRAM = 0,
  105. /**
  106. * Constant for Safar, the 2nd month of the Islamic year.
  107. * @internal
  108. */
  109. SAFAR = 1,
  110. /**
  111. * Constant for Rabi' al-awwal (or Rabi' I), the 3rd month of the Islamic year.
  112. * @internal
  113. */
  114. RABI_1 = 2,
  115. /**
  116. * Constant for Rabi' al-thani or (Rabi' II), the 4th month of the Islamic year.
  117. * @internal
  118. */
  119. RABI_2 = 3,
  120. /**
  121. * Constant for Jumada al-awwal or (Jumada I), the 5th month of the Islamic year.
  122. * @internal
  123. */
  124. JUMADA_1 = 4,
  125. /**
  126. * Constant for Jumada al-thani or (Jumada II), the 6th month of the Islamic year.
  127. * @internal
  128. */
  129. JUMADA_2 = 5,
  130. /**
  131. * Constant for Rajab, the 7th month of the Islamic year.
  132. * @internal
  133. */
  134. RAJAB = 6,
  135. /**
  136. * Constant for Sha'ban, the 8th month of the Islamic year.
  137. * @internal
  138. */
  139. SHABAN = 7,
  140. /**
  141. * Constant for Ramadan, the 9th month of the Islamic year.
  142. * @internal
  143. */
  144. RAMADAN = 8,
  145. /**
  146. * Constant for Shawwal, the 10th month of the Islamic year.
  147. * @internal
  148. */
  149. SHAWWAL = 9,
  150. /**
  151. * Constant for Dhu al-Qi'dah, the 11th month of the Islamic year.
  152. * @internal
  153. */
  154. DHU_AL_QIDAH = 10,
  155. /**
  156. * Constant for Dhu al-Hijjah, the 12th month of the Islamic year.
  157. * @internal
  158. */
  159. DHU_AL_HIJJAH = 11,
  160. ISLAMIC_MONTH_MAX
  161. };
  162. //-------------------------------------------------------------------------
  163. // Constructors...
  164. //-------------------------------------------------------------------------
  165. /**
  166. * Constructs an IslamicCalendar based on the current time in the default time zone
  167. * with the given locale.
  168. *
  169. * @param aLocale The given locale.
  170. * @param success Indicates the status of IslamicCalendar object construction.
  171. * Returns U_ZERO_ERROR if constructed successfully.
  172. * @param type The Islamic calendar calculation type. The default value is CIVIL.
  173. * @internal
  174. */
  175. IslamicCalendar(const Locale& aLocale, UErrorCode &success, ECalculationType type = CIVIL);
  176. /**
  177. * Copy Constructor
  178. * @internal
  179. */
  180. IslamicCalendar(const IslamicCalendar& other);
  181. /**
  182. * Destructor.
  183. * @internal
  184. */
  185. virtual ~IslamicCalendar();
  186. /**
  187. * Sets Islamic calendar calculation type used by this instance.
  188. *
  189. * @param type The calendar calculation type, <code>CIVIL</code> to use the civil
  190. * calendar, <code>ASTRONOMICAL</code> to use the astronomical calendar.
  191. * @internal
  192. */
  193. void setCalculationType(ECalculationType type, UErrorCode &status);
  194. /**
  195. * Returns <code>true</code> if this object is using the fixed-cycle civil
  196. * calendar, or <code>false</code> if using the religious, astronomical
  197. * calendar.
  198. * @internal
  199. */
  200. UBool isCivil();
  201. // TODO: copy c'tor, etc
  202. // clone
  203. virtual IslamicCalendar* clone() const;
  204. private:
  205. /**
  206. * Determine whether a year is a leap year in the Islamic civil calendar
  207. */
  208. static UBool civilLeapYear(int32_t year);
  209. /**
  210. * Return the day # on which the given year starts. Days are counted
  211. * from the Hijri epoch, origin 0.
  212. */
  213. int32_t yearStart(int32_t year) const;
  214. /**
  215. * Return the day # on which the given month starts. Days are counted
  216. * from the Hijri epoch, origin 0.
  217. *
  218. * @param year The hijri year
  219. * @param year The hijri month, 0-based
  220. */
  221. int32_t monthStart(int32_t year, int32_t month) const;
  222. /**
  223. * Find the day number on which a particular month of the true/lunar
  224. * Islamic calendar starts.
  225. *
  226. * @param month The month in question, origin 0 from the Hijri epoch
  227. *
  228. * @return The day number on which the given month starts.
  229. */
  230. int32_t trueMonthStart(int32_t month) const;
  231. /**
  232. * Return the "age" of the moon at the given time; this is the difference
  233. * in ecliptic latitude between the moon and the sun. This method simply
  234. * calls CalendarAstronomer.moonAge, converts to degrees,
  235. * and adjusts the resultto be in the range [-180, 180].
  236. *
  237. * @param time The time at which the moon's age is desired,
  238. * in millis since 1/1/1970.
  239. */
  240. static double moonAge(UDate time, UErrorCode &status);
  241. //-------------------------------------------------------------------------
  242. // Internal data....
  243. //
  244. /**
  245. * <code>CIVIL</code> if this object uses the fixed-cycle Islamic civil calendar,
  246. * and <code>ASTRONOMICAL</code> if it approximates the true religious calendar using
  247. * astronomical calculations for the time of the new moon.
  248. */
  249. ECalculationType cType;
  250. //----------------------------------------------------------------------
  251. // Calendar framework
  252. //----------------------------------------------------------------------
  253. protected:
  254. /**
  255. * @internal
  256. */
  257. virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
  258. /**
  259. * Return the length (in days) of the given month.
  260. *
  261. * @param year The hijri year
  262. * @param year The hijri month, 0-based
  263. * @internal
  264. */
  265. virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const;
  266. /**
  267. * Return the number of days in the given Islamic year
  268. * @internal
  269. */
  270. virtual int32_t handleGetYearLength(int32_t extendedYear) const;
  271. //-------------------------------------------------------------------------
  272. // Functions for converting from field values to milliseconds....
  273. //-------------------------------------------------------------------------
  274. // Return JD of start of given month/year
  275. /**
  276. * @internal
  277. */
  278. virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const;
  279. //-------------------------------------------------------------------------
  280. // Functions for converting from milliseconds to field values
  281. //-------------------------------------------------------------------------
  282. /**
  283. * @internal
  284. */
  285. virtual int32_t handleGetExtendedYear();
  286. /**
  287. * Override Calendar to compute several fields specific to the Islamic
  288. * calendar system. These are:
  289. *
  290. * <ul><li>ERA
  291. * <li>YEAR
  292. * <li>MONTH
  293. * <li>DAY_OF_MONTH
  294. * <li>DAY_OF_YEAR
  295. * <li>EXTENDED_YEAR</ul>
  296. *
  297. * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
  298. * method is called. The getGregorianXxx() methods return Gregorian
  299. * calendar equivalents for the given Julian day.
  300. * @internal
  301. */
  302. virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
  303. // UObject stuff
  304. public:
  305. /**
  306. * @return The class ID for this object. All objects of a given class have the
  307. * same class ID. Objects of other classes have different class IDs.
  308. * @internal
  309. */
  310. virtual UClassID getDynamicClassID(void) const;
  311. /**
  312. * Return the class ID for this class. This is useful only for comparing to a return
  313. * value from getDynamicClassID(). For example:
  314. *
  315. * Base* polymorphic_pointer = createPolymorphicObject();
  316. * if (polymorphic_pointer->getDynamicClassID() ==
  317. * Derived::getStaticClassID()) ...
  318. *
  319. * @return The class ID for all objects of this class.
  320. * @internal
  321. */
  322. /*U_I18N_API*/ static UClassID U_EXPORT2 getStaticClassID(void);
  323. /**
  324. * return the calendar type, "buddhist".
  325. *
  326. * @return calendar type
  327. * @internal
  328. */
  329. virtual const char * getType() const;
  330. private:
  331. IslamicCalendar(); // default constructor not implemented
  332. // Default century.
  333. protected:
  334. /**
  335. * (Overrides Calendar) Return true if the current date for this Calendar is in
  336. * Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
  337. *
  338. * @param status Fill-in parameter which receives the status of this operation.
  339. * @return True if the current date for this Calendar is in Daylight Savings Time,
  340. * false, otherwise.
  341. * @internal
  342. */
  343. virtual UBool inDaylightTime(UErrorCode& status) const;
  344. /**
  345. * Returns TRUE because the Islamic Calendar does have a default century
  346. * @internal
  347. */
  348. virtual UBool haveDefaultCentury() const;
  349. /**
  350. * Returns the date of the start of the default century
  351. * @return start of century - in milliseconds since epoch, 1970
  352. * @internal
  353. */
  354. virtual UDate defaultCenturyStart() const;
  355. /**
  356. * Returns the year in which the default century begins
  357. * @internal
  358. */
  359. virtual int32_t defaultCenturyStartYear() const;
  360. private:
  361. /**
  362. * Initializes the 100-year window that dates with 2-digit years
  363. * are considered to fall within so that its start date is 80 years
  364. * before the current time.
  365. */
  366. static void U_CALLCONV initializeSystemDefaultCentury(void);
  367. };
  368. U_NAMESPACE_END
  369. #endif
  370. #endif