michael@0: /*
michael@0: ******************************************************************************
michael@0: * Copyright (C) 2003-2013, International Business Machines Corporation
michael@0: * and others. All Rights Reserved.
michael@0: ******************************************************************************
michael@0: *
michael@0: * File HEBRWCAL.H
michael@0: *
michael@0: * Modification History:
michael@0: *
michael@0: * Date Name Description
michael@0: * 05/13/2003 srl copied from gregocal.h
michael@0: * 11/26/2003 srl copied from buddhcal.h
michael@0: ******************************************************************************
michael@0: */
michael@0:
michael@0: #ifndef HEBRWCAL_H
michael@0: #define HEBRWCAL_H
michael@0:
michael@0: #include "unicode/utypes.h"
michael@0:
michael@0: #if !UCONFIG_NO_FORMATTING
michael@0:
michael@0: #include "unicode/calendar.h"
michael@0: #include "unicode/gregocal.h"
michael@0:
michael@0: U_NAMESPACE_BEGIN
michael@0:
michael@0: /**
michael@0: * HebrewCalendar
is a subclass of Calendar
michael@0: * that that implements the traditional Hebrew calendar.
michael@0: * This is the civil calendar in Israel and the liturgical calendar
michael@0: * of the Jewish faith worldwide.
michael@0: *
michael@0: * The Hebrew calendar is lunisolar and thus has a number of interesting michael@0: * properties that distinguish it from the Gregorian. Months start michael@0: * on the day of (an arithmetic approximation of) each new moon. Since the michael@0: * solar year (approximately 365.24 days) is not an even multiple of michael@0: * the lunar month (approximately 29.53 days) an extra "leap month" is michael@0: * inserted in 7 out of every 19 years. To make matters even more michael@0: * interesting, the start of a year can be delayed by up to three days michael@0: * in order to prevent certain holidays from falling on the Sabbath and michael@0: * to prevent certain illegal year lengths. Finally, the lengths of certain michael@0: * months can vary depending on the number of days in the year. michael@0: *
michael@0: * The leap month is known as "Adar 1" and is inserted between the michael@0: * months of Shevat and Adar in leap years. Since the leap month does michael@0: * not come at the end of the year, calculations involving michael@0: * month numbers are particularly complex. Users of this class should michael@0: * make sure to use the {@link #roll roll} and {@link #add add} methods michael@0: * rather than attempting to perform date arithmetic by manipulating michael@0: * the fields directly. michael@0: *
michael@0: * Note: In the traditional Hebrew calendar, days start at sunset. michael@0: * However, in order to keep the time fields in this class michael@0: * synchronized with those of the other calendars and with local clock time, michael@0: * we treat days and months as beginning at midnight, michael@0: * roughly 6 hours after the corresponding sunset. michael@0: *
michael@0: * If you are interested in more information on the rules behind the Hebrew michael@0: * calendar, see one of the following references: michael@0: *
michael@0: * @see com.ibm.icu.util.GregorianCalendar michael@0: * michael@0: * @author Laura Werner michael@0: * @author Alan Liu michael@0: * @author Steven R. Loomis michael@0: *
michael@0: * @internal michael@0: */ michael@0: class U_I18N_API HebrewCalendar : public Calendar { michael@0: public: michael@0: /** michael@0: * Useful constants for HebrewCalendar. michael@0: * @internal michael@0: */ michael@0: enum EEras { michael@0: /** michael@0: * Constant for Tishri, the 1st month of the Hebrew year. michael@0: */ michael@0: TISHRI, michael@0: /** michael@0: * Constant for Heshvan, the 2nd month of the Hebrew year. michael@0: */ michael@0: HESHVAN, michael@0: /** michael@0: * Constant for Kislev, the 3rd month of the Hebrew year. michael@0: */ michael@0: KISLEV, michael@0: michael@0: /** michael@0: * Constant for Tevet, the 4th month of the Hebrew year. michael@0: */ michael@0: TEVET, michael@0: michael@0: /** michael@0: * Constant for Shevat, the 5th month of the Hebrew year. michael@0: */ michael@0: SHEVAT, michael@0: michael@0: /** michael@0: * Constant for Adar I, the 6th month of the Hebrew year michael@0: * (present in leap years only). In non-leap years, the calendar michael@0: * jumps from Shevat (5th month) to Adar (7th month). michael@0: */ michael@0: ADAR_1, michael@0: michael@0: /** michael@0: * Constant for the Adar, the 7th month of the Hebrew year. michael@0: */ michael@0: ADAR, michael@0: michael@0: /** michael@0: * Constant for Nisan, the 8th month of the Hebrew year. michael@0: */ michael@0: NISAN, michael@0: michael@0: /** michael@0: * Constant for Iyar, the 9th month of the Hebrew year. michael@0: */ michael@0: IYAR, michael@0: michael@0: /** michael@0: * Constant for Sivan, the 10th month of the Hebrew year. michael@0: */ michael@0: SIVAN, michael@0: michael@0: /** michael@0: * Constant for Tammuz, the 11th month of the Hebrew year. michael@0: */ michael@0: TAMUZ, michael@0: michael@0: /** michael@0: * Constant for Av, the 12th month of the Hebrew year. michael@0: */ michael@0: AV, michael@0: michael@0: /** michael@0: * Constant for Elul, the 13th month of the Hebrew year. michael@0: */ michael@0: ELUL michael@0: }; michael@0: michael@0: /** michael@0: * Constructs a HebrewCalendar based on the current time in the default time zone michael@0: * with the given locale. michael@0: * michael@0: * @param aLocale The given locale. michael@0: * @param success Indicates the status of HebrewCalendar object construction. michael@0: * Returns U_ZERO_ERROR if constructed successfully. michael@0: * @internal michael@0: */ michael@0: HebrewCalendar(const Locale& aLocale, UErrorCode& success); michael@0: michael@0: michael@0: /** michael@0: * Destructor michael@0: * @internal michael@0: */ michael@0: virtual ~HebrewCalendar(); michael@0: michael@0: /** michael@0: * Copy constructor michael@0: * @param source the object to be copied. michael@0: * @internal michael@0: */ michael@0: HebrewCalendar(const HebrewCalendar& source); michael@0: michael@0: /** michael@0: * Default assignment operator michael@0: * @param right the object to be copied. michael@0: * @internal michael@0: */ michael@0: HebrewCalendar& operator=(const HebrewCalendar& right); michael@0: michael@0: /** michael@0: * Create and return a polymorphic copy of this calendar. michael@0: * @return return a polymorphic copy of this calendar. michael@0: * @internal michael@0: */ michael@0: virtual Calendar* clone(void) const; michael@0: michael@0: public: michael@0: /** michael@0: * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual michael@0: * override. This method is to implement a simple version of RTTI, since not all C++ michael@0: * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call michael@0: * this method. michael@0: * michael@0: * @return The class ID for this object. All objects of a given class have the michael@0: * same class ID. Objects of other classes have different class IDs. michael@0: * @internal michael@0: */ michael@0: virtual UClassID getDynamicClassID(void) const; michael@0: michael@0: /** michael@0: * Return the class ID for this class. This is useful only for comparing to a return michael@0: * value from getDynamicClassID(). For example: michael@0: * michael@0: * Base* polymorphic_pointer = createPolymorphicObject(); michael@0: * if (polymorphic_pointer->getDynamicClassID() == michael@0: * Derived::getStaticClassID()) ... michael@0: * michael@0: * @return The class ID for all objects of this class. michael@0: * @internal michael@0: */ michael@0: static UClassID U_EXPORT2 getStaticClassID(void); michael@0: michael@0: /** michael@0: * return the calendar type, "hebrew". michael@0: * michael@0: * @return calendar type michael@0: * @internal michael@0: */ michael@0: virtual const char * getType() const; michael@0: michael@0: michael@0: // Calendar API michael@0: public: michael@0: /** michael@0: * (Overrides Calendar) UDate Arithmetic function. Adds the specified (signed) amount michael@0: * of time to the given time field, based on the calendar's rules. For more michael@0: * information, see the documentation for Calendar::add(). michael@0: * michael@0: * @param field The time field. michael@0: * @param amount The amount of date or time to be added to the field. michael@0: * @param status Output param set to success/failure code on exit. If any value michael@0: * previously set in the time field is invalid, this will be set to michael@0: * an error status. michael@0: */ michael@0: virtual void add(UCalendarDateFields field, int32_t amount, UErrorCode& status); michael@0: /** michael@0: * @deprecated ICU 2.6 use UCalendarDateFields instead of EDateFields michael@0: */ michael@0: virtual void add(EDateFields field, int32_t amount, UErrorCode& status); michael@0: michael@0: michael@0: /** michael@0: * (Overrides Calendar) Rolls up or down by the given amount in the specified field. michael@0: * For more information, see the documentation for Calendar::roll(). michael@0: * michael@0: * @param field The time field. michael@0: * @param amount Indicates amount to roll. michael@0: * @param status Output param set to success/failure code on exit. If any value michael@0: * previously set in the time field is invalid, this will be set to michael@0: * an error status. michael@0: * @internal michael@0: */ michael@0: virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode& status); michael@0: michael@0: /** michael@0: * (Overrides Calendar) Rolls up or down by the given amount in the specified field. michael@0: * For more information, see the documentation for Calendar::roll(). michael@0: * michael@0: * @param field The time field. michael@0: * @param amount Indicates amount to roll. michael@0: * @param status Output param set to success/failure code on exit. If any value michael@0: * previously set in the time field is invalid, this will be set to michael@0: * an error status. michael@0: * @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead. michael@0: ` */ michael@0: virtual void roll(EDateFields field, int32_t amount, UErrorCode& status); michael@0: michael@0: /** michael@0: * @internal michael@0: */ michael@0: static UBool isLeapYear(int32_t year) ; michael@0: michael@0: protected: michael@0: michael@0: /** michael@0: * Subclass API for defining limits of different types. michael@0: * Subclasses must implement this method to return limits for the michael@0: * following fields: michael@0: * michael@0: *
UCAL_ERA michael@0: * UCAL_YEAR michael@0: * UCAL_MONTH michael@0: * UCAL_WEEK_OF_YEAR michael@0: * UCAL_WEEK_OF_MONTH michael@0: * UCAL_DATE (DAY_OF_MONTH on Java) michael@0: * UCAL_DAY_OF_YEAR michael@0: * UCAL_DAY_OF_WEEK_IN_MONTH michael@0: * UCAL_YEAR_WOY michael@0: * UCAL_EXTENDED_YEARmichael@0: * michael@0: * @param field one of the above field numbers michael@0: * @param limitType one of
MINIMUM
, GREATEST_MINIMUM
,
michael@0: * LEAST_MAXIMUM
, or MAXIMUM
michael@0: * @internal
michael@0: */
michael@0: virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
michael@0:
michael@0: /**
michael@0: * Return the number of days in the given month of the given extended
michael@0: * year of this calendar system. Subclasses should override this
michael@0: * method if they can provide a more correct or more efficient
michael@0: * implementation than the default implementation in Calendar.
michael@0: * @internal
michael@0: */
michael@0: virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const;
michael@0:
michael@0: /**
michael@0: * Return the number of days in the given extended year of this
michael@0: * calendar system. Subclasses should override this method if they can
michael@0: * provide a more correct or more efficient implementation than the
michael@0: * default implementation in Calendar.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: virtual int32_t handleGetYearLength(int32_t eyear) const;
michael@0: /**
michael@0: * Subclasses may override this method to compute several fields
michael@0: * specific to each calendar system. These are:
michael@0: *
michael@0: * The GregorianCalendar implementation implements michael@0: * a calendar with the specified Julian/Gregorian cutover date. michael@0: * @internal michael@0: */ michael@0: virtual void handleComputeFields(int32_t julianDay, UErrorCode &status); michael@0: /** michael@0: * Return the extended year defined by the current fields. This will michael@0: * use the UCAL_EXTENDED_YEAR field or the UCAL_YEAR and supra-year fields (such michael@0: * as UCAL_ERA) specific to the calendar system, depending on which set of michael@0: * fields is newer. michael@0: * @return the extended year michael@0: * @internal michael@0: */ michael@0: virtual int32_t handleGetExtendedYear(); michael@0: /** michael@0: * Return the Julian day number of day before the first day of the michael@0: * given month in the given extended year. Subclasses should override michael@0: * this method to implement their calendar system. michael@0: * @param eyear the extended year michael@0: * @param month the zero-based month, or 0 if useMonth is false michael@0: * @param useMonth if false, compute the day before the first day of michael@0: * the given year, otherwise, compute the day before the first day of michael@0: * the given month michael@0: * @param return the Julian day number of the day before the first michael@0: * day of the given month and year michael@0: * @internal michael@0: */ michael@0: virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month, michael@0: UBool useMonth) const; michael@0: michael@0: michael@0: michael@0: protected: michael@0: michael@0: /** michael@0: * (Overrides Calendar) Return true if the current date for this Calendar is in michael@0: * Daylight Savings Time. Recognizes DST_OFFSET, if it is set. michael@0: * michael@0: * @param status Fill-in parameter which receives the status of this operation. michael@0: * @return True if the current date for this Calendar is in Daylight Savings Time, michael@0: * false, otherwise. michael@0: * @internal michael@0: */ michael@0: virtual UBool inDaylightTime(UErrorCode& status) const; michael@0: michael@0: /** michael@0: * Returns TRUE because the Hebrew Calendar does have a default century michael@0: * @internal michael@0: */ michael@0: virtual UBool haveDefaultCentury() const; michael@0: michael@0: /** michael@0: * Returns the date of the start of the default century michael@0: * @return start of century - in milliseconds since epoch, 1970 michael@0: * @internal michael@0: */ michael@0: virtual UDate defaultCenturyStart() const; michael@0: michael@0: /** michael@0: * Returns the year in which the default century begins michael@0: * @internal michael@0: */ michael@0: virtual int32_t defaultCenturyStartYear() const; michael@0: michael@0: private: // Calendar-specific implementation michael@0: /** michael@0: * Finds the day # of the first day in the given Hebrew year. michael@0: * To do this, we want to calculate the time of the Tishri 1 new moon michael@0: * in that year. michael@0: *
michael@0: * The algorithm here is similar to ones described in a number of michael@0: * references, including: michael@0: *