intl/icu/source/i18n/islamcal.h

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial