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