1/*
2******************************************************************************
3* Copyright (C) 2003-2013, International Business Machines Corporation
4* and others. All Rights Reserved.
5******************************************************************************
6*
7* File HEBRWCAL.H
8*
9* Modification History:
10*
11*   Date        Name        Description
12*   05/13/2003  srl          copied from gregocal.h
13*   11/26/2003  srl          copied from buddhcal.h
14******************************************************************************
15*/
16
17#ifndef HEBRWCAL_H
18#define HEBRWCAL_H
19
20#include "unicode/utypes.h"
21
22#if !UCONFIG_NO_FORMATTING
23
24#include "unicode/calendar.h"
25#include "unicode/gregocal.h"
26
27U_NAMESPACE_BEGIN
28
29/**
30 * <code>HebrewCalendar</code> is a subclass of <code>Calendar</code>
31 * that that implements the traditional Hebrew calendar.
32 * This is the civil calendar in Israel and the liturgical calendar
33 * of the Jewish faith worldwide.
34 * <p>
35 * The Hebrew calendar is lunisolar and thus has a number of interesting
36 * properties that distinguish it from the Gregorian.  Months start
37 * on the day of (an arithmetic approximation of) each new moon.  Since the
38 * solar year (approximately 365.24 days) is not an even multiple of
39 * the lunar month (approximately 29.53 days) an extra "leap month" is
40 * inserted in 7 out of every 19 years.  To make matters even more
41 * interesting, the start of a year can be delayed by up to three days
42 * in order to prevent certain holidays from falling on the Sabbath and
43 * to prevent certain illegal year lengths.  Finally, the lengths of certain
44 * months can vary depending on the number of days in the year.
45 * <p>
46 * The leap month is known as "Adar 1" and is inserted between the
47 * months of Shevat and Adar in leap years.  Since the leap month does
48 * not come at the end of the year, calculations involving
49 * month numbers are particularly complex.  Users of this class should
50 * make sure to use the {@link #roll roll} and {@link #add add} methods
51 * rather than attempting to perform date arithmetic by manipulating
52 * the fields directly.
53 * <p>
54 * <b>Note:</b> In the traditional Hebrew calendar, days start at sunset.
55 * However, in order to keep the time fields in this class
56 * synchronized with those of the other calendars and with local clock time,
57 * we treat days and months as beginning at midnight,
58 * roughly 6 hours after the corresponding sunset.
59 * <p>
60 * If you are interested in more information on the rules behind the Hebrew
61 * calendar, see one of the following references:
62 * <ul>
63 * <li>"<a href="http://www.amazon.com/exec/obidos/ASIN/0521564743">Calendrical Calculations</a>",
64 *      by Nachum Dershowitz & Edward Reingold, Cambridge University Press, 1997, pages 85-91.
65 *
66 * <li>Hebrew Calendar Science and Myths,
67 *      <a href="http://www.geocities.com/Athens/1584/">
68 *      http://www.geocities.com/Athens/1584/</a>
69 *
70 * <li>The Calendar FAQ,
71 *      <a href="http://www.faqs.org/faqs/calendars/faq/">
72 *      http://www.faqs.org/faqs/calendars/faq/</a>
73 * </ul>
74 * <p>
75 * @see com.ibm.icu.util.GregorianCalendar
76 *
77 * @author Laura Werner
78 * @author Alan Liu
79 * @author Steven R. Loomis
80 * <p>
81 * @internal
82 */
83class U_I18N_API HebrewCalendar : public Calendar {
84public:
85  /**
86   * Useful constants for HebrewCalendar.
87   * @internal
88   */
89  enum EEras {
90    /**
91     * Constant for Tishri, the 1st month of the Hebrew year.
92     */
93      TISHRI,
94      /**
95     * Constant for Heshvan, the 2nd month of the Hebrew year.
96     */
97      HESHVAN,
98      /**
99     * Constant for Kislev, the 3rd month of the Hebrew year.
100     */
101      KISLEV,
102
103    /**
104     * Constant for Tevet, the 4th month of the Hebrew year.
105     */
106      TEVET,
107
108    /**
109     * Constant for Shevat, the 5th month of the Hebrew year.
110     */
111      SHEVAT,
112
113    /**
114     * Constant for Adar I, the 6th month of the Hebrew year
115     * (present in leap years only). In non-leap years, the calendar
116     * jumps from Shevat (5th month) to Adar (7th month).
117     */
118      ADAR_1,
119
120    /**
121     * Constant for the Adar, the 7th month of the Hebrew year.
122     */
123      ADAR,
124
125    /**
126     * Constant for Nisan, the 8th month of the Hebrew year.
127     */
128      NISAN,
129
130    /**
131     * Constant for Iyar, the 9th month of the Hebrew year.
132     */
133      IYAR,
134
135    /**
136     * Constant for Sivan, the 10th month of the Hebrew year.
137     */
138      SIVAN,
139
140    /**
141     * Constant for Tammuz, the 11th month of the Hebrew year.
142     */
143      TAMUZ,
144
145    /**
146     * Constant for Av, the 12th month of the Hebrew year.
147     */
148      AV,
149
150    /**
151     * Constant for Elul, the 13th month of the Hebrew year.
152     */
153      ELUL
154    };
155
156    /**
157     * Constructs a HebrewCalendar based on the current time in the default time zone
158     * with the given locale.
159     *
160     * @param aLocale  The given locale.
161     * @param success  Indicates the status of HebrewCalendar object construction.
162     *                 Returns U_ZERO_ERROR if constructed successfully.
163     * @internal
164     */
165    HebrewCalendar(const Locale& aLocale, UErrorCode& success);
166
167
168    /**
169     * Destructor
170     * @internal
171     */
172    virtual ~HebrewCalendar();
173
174    /**
175     * Copy constructor
176     * @param source    the object to be copied.
177     * @internal
178     */
179    HebrewCalendar(const HebrewCalendar& source);
180
181    /**
182     * Default assignment operator
183     * @param right    the object to be copied.
184     * @internal
185     */
186    HebrewCalendar& operator=(const HebrewCalendar& right);
187
188    /**
189     * Create and return a polymorphic copy of this calendar.
190     * @return    return a polymorphic copy of this calendar.
191     * @internal
192     */
193    virtual Calendar* clone(void) const;
194
195public:
196    /**
197     * Override Calendar Returns a unique class ID POLYMORPHICALLY. Pure virtual
198     * override. This method is to implement a simple version of RTTI, since not all C++
199     * compilers support genuine RTTI. Polymorphic operator==() and clone() methods call
200     * this method.
201     *
202     * @return   The class ID for this object. All objects of a given class have the
203     *           same class ID. Objects of other classes have different class IDs.
204     * @internal
205     */
206    virtual UClassID getDynamicClassID(void) const;
207
208    /**
209     * Return the class ID for this class. This is useful only for comparing to a return
210     * value from getDynamicClassID(). For example:
211     *
212     *      Base* polymorphic_pointer = createPolymorphicObject();
213     *      if (polymorphic_pointer->getDynamicClassID() ==
214     *          Derived::getStaticClassID()) ...
215     *
216     * @return   The class ID for all objects of this class.
217     * @internal
218     */
219    static UClassID U_EXPORT2 getStaticClassID(void);
220
221    /**
222     * return the calendar type, "hebrew".
223     *
224     * @return calendar type
225     * @internal
226     */
227    virtual const char * getType() const;
228
229
230    // Calendar API
231 public:
232    /**
233     * (Overrides Calendar) UDate Arithmetic function. Adds the specified (signed) amount
234     * of time to the given time field, based on the calendar's rules.  For more
235     * information, see the documentation for Calendar::add().
236     *
237     * @param field   The time field.
238     * @param amount  The amount of date or time to be added to the field.
239     * @param status  Output param set to success/failure code on exit. If any value
240     *                previously set in the time field is invalid, this will be set to
241     *                an error status.
242     */
243    virtual void add(UCalendarDateFields field, int32_t amount, UErrorCode& status);
244    /**
245     * @deprecated ICU 2.6 use UCalendarDateFields instead of EDateFields
246     */
247    virtual void add(EDateFields field, int32_t amount, UErrorCode& status);
248
249
250    /**
251     * (Overrides Calendar) Rolls up or down by the given amount in the specified field.
252     * For more information, see the documentation for Calendar::roll().
253     *
254     * @param field   The time field.
255     * @param amount  Indicates amount to roll.
256     * @param status  Output param set to success/failure code on exit. If any value
257     *                previously set in the time field is invalid, this will be set to
258     *                an error status.
259     * @internal
260     */
261    virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode& status);
262
263    /**
264     * (Overrides Calendar) Rolls up or down by the given amount in the specified field.
265     * For more information, see the documentation for Calendar::roll().
266     *
267     * @param field   The time field.
268     * @param amount  Indicates amount to roll.
269     * @param status  Output param set to success/failure code on exit. If any value
270     *                previously set in the time field is invalid, this will be set to
271     *                an error status.
272     * @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead.
273`     */
274    virtual void roll(EDateFields field, int32_t amount, UErrorCode& status);
275
276    /**
277     * @internal
278     */
279    static UBool isLeapYear(int32_t year) ;
280
281 protected:
282
283    /**
284     * Subclass API for defining limits of different types.
285     * Subclasses must implement this method to return limits for the
286     * following fields:
287     *
288     * <pre>UCAL_ERA
289     * UCAL_YEAR
290     * UCAL_MONTH
291     * UCAL_WEEK_OF_YEAR
292     * UCAL_WEEK_OF_MONTH
293     * UCAL_DATE (DAY_OF_MONTH on Java)
294     * UCAL_DAY_OF_YEAR
295     * UCAL_DAY_OF_WEEK_IN_MONTH
296     * UCAL_YEAR_WOY
297     * UCAL_EXTENDED_YEAR</pre>
298     *
299     * @param field one of the above field numbers
300     * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
301     * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
302     * @internal
303     */
304    virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
305
306    /**
307     * Return the number of days in the given month of the given extended
308     * year of this calendar system.  Subclasses should override this
309     * method if they can provide a more correct or more efficient
310     * implementation than the default implementation in Calendar.
311     * @internal
312     */
313    virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const;
314
315    /**
316     * Return the number of days in the given extended year of this
317     * calendar system.  Subclasses should override this method if they can
318     * provide a more correct or more efficient implementation than the
319     * default implementation in Calendar.
320     * @stable ICU 2.0
321     */
322    virtual int32_t handleGetYearLength(int32_t eyear) const;
323    /**
324     * Subclasses may override this method to compute several fields
325     * specific to each calendar system.  These are:
326     *
327     * <ul><li>ERA
328     * <li>YEAR
329     * <li>MONTH
330     * <li>DAY_OF_MONTH
331     * <li>DAY_OF_YEAR
332     * <li>EXTENDED_YEAR</ul>
333     *
334     * <p>The GregorianCalendar implementation implements
335     * a calendar with the specified Julian/Gregorian cutover date.
336     * @internal
337     */
338    virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
339    /**
340     * Return the extended year defined by the current fields.  This will
341     * use the UCAL_EXTENDED_YEAR field or the UCAL_YEAR and supra-year fields (such
342     * as UCAL_ERA) specific to the calendar system, depending on which set of
343     * fields is newer.
344     * @return the extended year
345     * @internal
346     */
347    virtual int32_t handleGetExtendedYear();
348    /**
349     * Return the Julian day number of day before the first day of the
350     * given month in the given extended year.  Subclasses should override
351     * this method to implement their calendar system.
352     * @param eyear the extended year
353     * @param month the zero-based month, or 0 if useMonth is false
354     * @param useMonth if false, compute the day before the first day of
355     * the given year, otherwise, compute the day before the first day of
356     * the given month
357     * @param return the Julian day number of the day before the first
358     * day of the given month and year
359     * @internal
360     */
361    virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month,
362                                                   UBool useMonth) const;
363
364
365
366 protected:
367
368  /**
369   * (Overrides Calendar) Return true if the current date for this Calendar is in
370   * Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
371   *
372   * @param status Fill-in parameter which receives the status of this operation.
373   * @return   True if the current date for this Calendar is in Daylight Savings Time,
374   *           false, otherwise.
375   * @internal
376   */
377  virtual UBool inDaylightTime(UErrorCode& status) const;
378
379    /**
380     * Returns TRUE because the Hebrew Calendar does have a default century
381     * @internal
382     */
383    virtual UBool haveDefaultCentury() const;
384
385    /**
386     * Returns the date of the start of the default century
387     * @return start of century - in milliseconds since epoch, 1970
388     * @internal
389     */
390    virtual UDate defaultCenturyStart() const;
391
392    /**
393     * Returns the year in which the default century begins
394     * @internal
395     */
396    virtual int32_t defaultCenturyStartYear() const;
397
398 private: // Calendar-specific implementation
399    /**
400     * Finds the day # of the first day in the given Hebrew year.
401     * To do this, we want to calculate the time of the Tishri 1 new moon
402     * in that year.
403     * <p>
404     * The algorithm here is similar to ones described in a number of
405     * references, including:
406     * <ul>
407     * <li>"Calendrical Calculations", by Nachum Dershowitz & Edward Reingold,
408     *     Cambridge University Press, 1997, pages 85-91.
409     *
410     * <li>Hebrew Calendar Science and Myths,
411     *     <a href="http://www.geocities.com/Athens/1584/">
412     *     http://www.geocities.com/Athens/1584/</a>
413     *
414     * <li>The Calendar FAQ,
415     *      <a href="http://www.faqs.org/faqs/calendars/faq/">
416     *      http://www.faqs.org/faqs/calendars/faq/</a>
417     * </ul>
418     * @param year extended year
419     * @return day number (JD)
420     * @internal
421     */
422    static int32_t startOfYear(int32_t year, UErrorCode& status);
423
424    static int32_t absoluteDayToDayOfWeek(int32_t day) ;
425
426    /**
427     * @internal
428     */
429    int32_t yearType(int32_t year) const;
430
431    /**
432     * @internal
433     */
434    static int32_t monthsInYear(int32_t year) ;
435};
436
437U_NAMESPACE_END
438
439#endif /* #if !UCONFIG_NO_FORMATTING */
440
441#endif
442//eof
443
444