12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others.
22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
5bee65486a185907111f3be60992433e133ec0e32Scott Russell * Copyright (C) 1996-2016, International Business Machines Corporation and
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved.
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.util;
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.CalendarCache;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale.Category;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>HebrewCalendar</code> is a subclass of <code>Calendar</code>
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * that that implements the traditional Hebrew calendar.
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This is the civil calendar in Israel and the liturgical calendar
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * of the Jewish faith worldwide.
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The Hebrew calendar is lunisolar and thus has a number of interesting
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * properties that distinguish it from the Gregorian.  Months start
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * on the day of (an arithmetic approximation of) each new moon.  Since the
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * solar year (approximately 365.24 days) is not an even multiple of
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the lunar month (approximately 29.53 days) an extra "leap month" is
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * inserted in 7 out of every 19 years.  To make matters even more
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * interesting, the start of a year can be delayed by up to three days
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in order to prevent certain holidays from falling on the Sabbath and
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * to prevent certain illegal year lengths.  Finally, the lengths of certain
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * months can vary depending on the number of days in the year.
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The leap month is known as "Adar 1" and is inserted between the
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * months of Shevat and Adar in leap years.  Since the leap month does
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * not come at the end of the year, calculations involving
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * month numbers are particularly complex.  Users of this class should
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * make sure to use the {@link #roll roll} and {@link #add add} methods
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * rather than attempting to perform date arithmetic by manipulating
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the fields directly.
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <b>Note:</b> In the traditional Hebrew calendar, days start at sunset.
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * However, in order to keep the time fields in this class
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * synchronized with those of the other calendars and with local clock time,
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * we treat days and months as beginning at midnight,
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * roughly 6 hours after the corresponding sunset.
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If you are interested in more information on the rules behind the Hebrew
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * calendar, see one of the following references:
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <ul>
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>"<a href="http://www.amazon.com/exec/obidos/ASIN/0521564743">Calendrical Calculations</a>",
51bee65486a185907111f3be60992433e133ec0e32Scott Russell *      by Nachum Dershowitz &amp; Edward Reingold, Cambridge University Press, 1997, pages 85-91.
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>Hebrew Calendar Science and Myths,
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      <a href="http://web.archive.org/web/20090423084613/http://www.geocities.com/Athens/1584/">
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      http://web.archive.org/web/20090423084613/http://www.geocities.com/Athens/1584/</a>
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <li>The Calendar FAQ,
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      <a href="http://www.faqs.org/faqs/calendars/faq/">
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *      http://www.faqs.org/faqs/calendars/faq/</a>
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * </ul>
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This class should not be subclassed.</p>
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * HebrewCalendar usually should be instantiated using
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code>
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * with the tag <code>"@calendar=hebrew"</code>.</p>
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see com.ibm.icu.util.GregorianCalendar
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see com.ibm.icu.util.Calendar
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author Laura Werner
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author Alan Liu
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @stable ICU 2.8
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class HebrewCalendar extends Calendar {
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // jdk1.4.2 serialver
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final long serialVersionUID = -1952524560588825816L;
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Tons o' Constants...
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Tishri, the 1st month of the Hebrew year.
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int TISHRI = 0;
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Heshvan, the 2nd month of the Hebrew year.
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int HESHVAN = 1;
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Kislev, the 3rd month of the Hebrew year.
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int KISLEV = 2;
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Tevet, the 4th month of the Hebrew year.
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int TEVET = 3;
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Shevat, the 5th month of the Hebrew year.
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int SHEVAT = 4;
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Adar I, the 6th month of the Hebrew year
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * (present in leap years only). In non-leap years, the calendar
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * jumps from Shevat (5th month) to Adar (7th month).
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ADAR_1 = 5;
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for the Adar, the 7th month of the Hebrew year.
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ADAR = 6;
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Nisan, the 8th month of the Hebrew year.
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int NISAN = 7;
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Iyar, the 9th month of the Hebrew year.
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int IYAR = 8;
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Sivan, the 10th month of the Hebrew year.
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int SIVAN = 9;
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Tammuz, the 11th month of the Hebrew year.
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int TAMUZ = 10;
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Av, the 12th month of the Hebrew year.
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int AV = 11;
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constant for Elul, the 13th month of the Hebrew year.
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static final int ELUL = 12;
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The absolute date, in milliseconds since 1/1/1970 AD, Gregorian,
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * of the start of the Hebrew calendar.  In order to keep this calendar's
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * time of day in sync with that of the Gregorian calendar, we use
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * midnight, rather than sunset the day before.
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //private static final long EPOCH_MILLIS = -180799862400000L; // 1/1/1 HY
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int LIMITS[][] = {
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Minimum  Greatest    Least  Maximum
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //           Minimum  Maximum
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        0,        0,       0,       0 }, // ERA
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { -5000000, -5000000, 5000000, 5000000 }, // YEAR
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        0,        0,      12,      12 }, // MONTH
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        1,        1,      51,      56 }, // WEEK_OF_YEAR
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // WEEK_OF_MONTH
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        1,        1,      29,      30 }, // DAY_OF_MONTH
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {        1,        1,     353,     385 }, // DAY_OF_YEAR
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // DAY_OF_WEEK
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {       -1,       -1,       5,       5 }, // DAY_OF_WEEK_IN_MONTH
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // AM_PM
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // HOUR
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // HOUR_OF_DAY
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // MINUTE
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // SECOND
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // MILLISECOND
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // ZONE_OFFSET
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // DST_OFFSET
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { -5000000, -5000000, 5000000, 5000000 }, // YEAR_WOY
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // DOW_LOCAL
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { -5000000, -5000000, 5000000, 5000000 }, // EXTENDED_YEAR
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // JULIAN_DAY
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {/*                                  */}, // MILLISECONDS_IN_DAY
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The lengths of the Hebrew months.  This is complicated, because there
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * are three different types of years, or six if you count leap years.
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Due to the rules for postponing the start of the year to avoid having
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * certain holidays fall on the sabbath, the year can end up being three
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * different lengths, called "deficient", "normal", and "complete".
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int MONTH_LENGTH[][] = {
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Deficient  Normal     Complete
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30     },           //Tishri
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   29,         29,         30     },           //Heshvan
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   29,         30,         30     },           //Kislev
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   29,         29,         29     },           //Tevet
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30     },           //Shevat
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30     },           //Adar I (leap years only)
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   29,         29,         29     },           //Adar
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30     },           //Nisan
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   29,         29,         29     },           //Iyar
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30     },           //Sivan
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   29,         29,         29     },           //Tammuz
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30     },           //Av
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   29,         29,         29     },           //Elul
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The cumulative # of days to the end of each month in a non-leap year
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Although this can be calculated from the MONTH_LENGTH table,
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * keeping it around separately makes some calculations a lot faster
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int MONTH_START[][] = {
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Deficient  Normal     Complete
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {    0,          0,          0  },          // (placeholder)
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30  },          // Tishri
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   59,         59,         60  },          // Heshvan
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   88,         89,         90  },          // Kislev
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  117,        118,        119  },          // Tevet
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  147,        148,        149  },          // Shevat
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  147,        148,        149  },          // (Adar I placeholder)
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  176,        177,        178  },          // Adar
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  206,        207,        208  },          // Nisan
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  235,        236,        237  },          // Iyar
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  265,        266,        267  },          // Sivan
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  294,        295,        296  },          // Tammuz
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  324,        325,        326  },          // Av
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  353,        354,        355  },          // Elul
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The cumulative # of days to the end of each month in a leap year
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int LEAP_MONTH_START[][] = {
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Deficient  Normal     Complete
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {    0,          0,          0  },          // (placeholder)
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   30,         30,         30  },          // Tishri
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   59,         59,         60  },          // Heshvan
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {   88,         89,         90  },          // Kislev
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  117,        118,        119  },          // Tevet
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  147,        148,        149  },          // Shevat
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  177,        178,        179  },          // Adar I
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  206,        207,        208  },          // Adar II
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  236,        237,        238  },          // Nisan
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  265,        266,        267  },          // Iyar
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  295,        296,        297  },          // Sivan
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  324,        325,        326  },          // Tammuz
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  354,        355,        356  },          // Av
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {  383,        384,        385  },          // Elul
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Data Members...
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static CalendarCache cache = new CalendarCache();
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Constructors...
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a default <code>HebrewCalendar</code> using the current time
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the default <code>FORMAT</code> locale.
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar() {
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> based on the current time
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the given time zone with the default <code>FORMAT</code> locale.
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param zone The time zone for the new calendar.
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(TimeZone zone) {
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(zone, ULocale.getDefault(Category.FORMAT));
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> based on the current time
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the given locale.
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aLocale The locale for the new calendar.
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(Locale aLocale) {
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(TimeZone.getDefault(), aLocale);
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> based on the current time
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the given locale.
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale The locale for the new calendar.
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.2
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(ULocale locale) {
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this(TimeZone.getDefault(), locale);
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> based on the current time
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the given time zone with the given locale.
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param zone The time zone for the new calendar.
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param aLocale The locale for the new calendar.
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(TimeZone zone, Locale aLocale) {
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(zone, aLocale);
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        setTimeInMillis(System.currentTimeMillis());
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> based on the current time
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the given time zone with the given locale.
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param zone The time zone for the new calendar.
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param locale The locale for the new calendar.
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.2
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(TimeZone zone, ULocale locale) {
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(zone, locale);
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        setTimeInMillis(System.currentTimeMillis());
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> with the given date set
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the default <code>FORMAT</code> locale.
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param year      The value used to set the calendar's {@link #YEAR YEAR} time field.
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  The value is 0-based. e.g., 0 for Tishri.
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(int year, int month, int date) {
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(YEAR, year);
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(MONTH, month);
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(DATE, date);
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> with the given date set
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in the default time zone with the default <code>FORMAT</code> locale.
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date      The date to which the new calendar is set.
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(Date date) {
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.setTime(date);
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructs a <code>HebrewCalendar</code> with the given date
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and time set for the default time zone with the default <code>FORMAT</code> locale.
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param year      The value used to set the calendar's {@link #YEAR YEAR} time field.
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param month     The value used to set the calendar's {@link #MONTH MONTH} time field.
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *                  The value is 0-based. e.g., 0 for Tishri.
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param date      The value used to set the calendar's {@link #DATE DATE} time field.
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param hour      The value used to set the calendar's {@link #HOUR_OF_DAY HOUR_OF_DAY} time field.
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param minute    The value used to set the calendar's {@link #MINUTE MINUTE} time field.
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param second    The value used to set the calendar's {@link #SECOND SECOND} time field.
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @see Category#FORMAT
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public HebrewCalendar(int year, int month, int date, int hour,
4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                             int minute, int second)
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(YEAR, year);
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(MONTH, month);
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(DATE, date);
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(HOUR_OF_DAY, hour);
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(MINUTE, minute);
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        this.set(SECOND, second);
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Rolling and adding functions overridden from Calendar
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // These methods call through to the default implementation in IBMCalendar
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // for most of the fields and only handle the unusual ones themselves.
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Add a signed amount to a specified field, using this calendar's rules.
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * For example, to add three days to the current date, you can call
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>add(Calendar.DATE, 3)</code>.
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * When adding to certain fields, the values of other fields may conflict and
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * need to be changed.  For example, when adding one to the {@link #MONTH MONTH} field
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * for the date "30 Av 5758", the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * must be adjusted so that the result is "29 Elul 5758" rather than the invalid
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * "30 Elul 5758".
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This method is able to add to
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and {@link #ZONE_OFFSET ZONE_OFFSET}.
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <b>Note:</b> You should always use {@link #roll roll} and add rather
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * than attempting to perform arithmetic operations directly on the fields
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * of a <tt>HebrewCalendar</tt>.  Since the {@link #MONTH MONTH} field behaves
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * discontinuously in non-leap years, simple arithmetic can give invalid results.
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param field     the time field.
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param amount    the amount to add to the field.
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @exception   IllegalArgumentException if the field is invalid or refers
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *              to a field that cannot be handled by this method.
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void add(int field, int amount)
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        switch (field) {
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        case MONTH:
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // We can't just do a set(MONTH, get(MONTH) + amount).  The
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // reason is ADAR_1.  Suppose amount is +2 and we land in
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // ADAR_1 -- then we have to bump to ADAR_2 aka ADAR.  But
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // if amount is -2 and we land in ADAR_1, then we have to
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // bump the other way -- down to SHEVAT.  - Alan 11/00
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int month = get(MONTH);
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int year = get(YEAR);
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                boolean acrossAdar1;
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (amount > 0) {
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    acrossAdar1 = (month < ADAR_1); // started before ADAR_1?
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    month += amount;
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (;;) {
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (acrossAdar1 && month>=ADAR_1 && !isLeapYear(year)) {
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ++month;
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (month <= ELUL) {
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            break;
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        month -= ELUL+1;
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        ++year;
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        acrossAdar1 = true;
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    acrossAdar1 = (month > ADAR_1); // started after ADAR_1?
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    month += amount;
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    for (;;) {
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (acrossAdar1 && month<=ADAR_1 && !isLeapYear(year)) {
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            --month;
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (month >= 0) {
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            break;
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        month += ELUL+1;
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        --year;
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        acrossAdar1 = true;
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                set(MONTH, month);
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                set(YEAR, year);
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                pinField(DAY_OF_MONTH);
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                break;
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        default:
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            super.add(field, amount);
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            break;
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Rolls (up/down) a specified amount time on the given field.  For
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * example, to roll the current date up by three days, you can call
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <code>roll(Calendar.DATE, 3)</code>.  If the
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * field is rolled past its maximum allowable value, it will "wrap" back
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * to its minimum and continue rolling.
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * For example, calling <code>roll(Calendar.DATE, 10)</code>
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * on a Hebrew calendar set to "25 Av 5758" will result in the date "5 Av 5758".
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * When rolling certain fields, the values of other fields may conflict and
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * need to be changed.  For example, when rolling the {@link #MONTH MONTH} field
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * upward by one for the date "30 Av 5758", the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * must be adjusted so that the result is "29 Elul 5758" rather than the invalid
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * "30 Elul".
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This method is able to roll
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * additional fields in their overrides of <code>roll</code>.
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <b>Note:</b> You should always use roll and {@link #add add} rather
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * than attempting to perform arithmetic operations directly on the fields
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * of a <tt>HebrewCalendar</tt>.  Since the {@link #MONTH MONTH} field behaves
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * discontinuously in non-leap years, simple arithmetic can give invalid results.
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param field     the time field.
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param amount    the amount by which the field should be rolled.
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @exception   IllegalArgumentException if the field is invalid or refers
5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *              to a field that cannot be handled by this method.
5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void roll(int field, int amount)
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        switch (field) {
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        case MONTH:
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int month = get(MONTH);
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int year = get(YEAR);
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                boolean leapYear = isLeapYear(year);
5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int yearLength = monthsInYear(year);
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int newMonth = month + (amount % yearLength);
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // If it's not a leap year and we're rolling past the missing month
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // of ADAR_1, we need to roll an extra month to make up for it.
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                //
5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (!leapYear) {
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (amount > 0 && month < ADAR_1 && newMonth >= ADAR_1) {
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newMonth++;
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    } else if (amount < 0 && month > ADAR_1 && newMonth <= ADAR_1) {
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        newMonth--;
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                set(MONTH, (newMonth + 13) % 13);
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                pinField(DAY_OF_MONTH);
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return;
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        default:
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            super.roll(field, amount);
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Support methods
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Hebrew date calculations are performed in terms of days, hours, and
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final long HOUR_PARTS = 1080;
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final long DAY_PARTS  = 24*HOUR_PARTS;
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // An approximate value for the length of a lunar month.
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // It is used to calculate the approximate year and month of a given
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // absolute date.
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static private final int  MONTH_DAYS = 29;
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static private final long MONTH_FRACT = 12*HOUR_PARTS + 793;
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static private final long MONTH_PARTS = MONTH_DAYS*DAY_PARTS + MONTH_FRACT;
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // The time of the new moon (in parts) on 1 Tishri, year 1 (the epoch)
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // counting from noon on the day before.  BAHARAD is an abbreviation of
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Bet (Monday), Hey (5 hours from sunset), Resh-Daled (204).
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static private final long BAHARAD = 11*HOUR_PARTS + 204;
5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Finds the day # of the first day in the given Hebrew year.
5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * To do this, we want to calculate the time of the Tishri 1 new moon
5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * in that year.
5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The algorithm here is similar to ones described in a number of
5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * references, including:
5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <ul>
5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>"Calendrical Calculations", by Nachum Dershowitz & Edward Reingold,
5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *     Cambridge University Press, 1997, pages 85-91.
5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>Hebrew Calendar Science and Myths,
5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *     <a href="http://www.geocities.com/Athens/1584/">
5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *     http://www.geocities.com/Athens/1584/</a>
6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>The Calendar FAQ,
6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *      <a href="http://www.faqs.org/faqs/calendars/faq/">
6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *      http://www.faqs.org/faqs/calendars/faq/</a>
6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * </ul>
6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static long startOfYear(int year)
6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long day = cache.get(year);
6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (day == CalendarCache.EMPTY) {
6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int months = (235 * year - 234) / 19;           // # of months before year
6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            long frac = months * MONTH_FRACT + BAHARAD;     // Fractional part of day #
6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            day  = months * 29 + (frac / DAY_PARTS);        // Whole # part of calculation
6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            frac = frac % DAY_PARTS;                        // Time of day
6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int wd = (int)(day % 7);                        // Day of week (0 == Monday)
6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (wd == 2 || wd == 4 || wd == 6) {
6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // If the 1st is on Sun, Wed, or Fri, postpone to the next day
6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                day += 1;
6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                wd = (int)(day % 7);
6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (wd == 1 && frac > 15*HOUR_PARTS+204 && !isLeapYear(year) ) {
6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // If the new moon falls after 3:11:20am (15h204p from the previous noon)
6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // on a Tuesday and it is not a leap year, postpone by 2 days.
6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // This prevents 356-day years.
6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                day += 2;
6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else if (wd == 0 && frac > 21*HOUR_PARTS+589 && isLeapYear(year-1) ) {
6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // If the new moon falls after 9:32:43 1/3am (21h589p from yesterday noon)
6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // on a Monday and *last* year was a leap year, postpone by 1 day.
6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // Prevents 382-day years.
6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                day += 1;
6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cache.put(year, day);
6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return day;
6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Find the day of the week for a given day
6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @param day   The # of days since the start of the Hebrew calendar,
6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *              1-based (i.e. 1/1/1 AM is day 1).
6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*private static int absoluteDayToDayOfWeek(long day)
6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // We know that 1/1/1 AM is a Monday, which makes the math easy...
6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return (int)(day % 7) + 1;
6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }*/
6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the the type of a given year.
6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *  0   "Deficient" year with 353 or 383 days
6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *  1   "Normal"    year with 354 or 384 days
6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *  2   "Complete"  year with 355 or 385 days
6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private final int yearType(int year)
6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int yearLength = handleGetYearLength(year);
6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (yearLength > 380) {
6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert           yearLength -= 30;        // Subtract length of leap month.
6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int type = 0;
6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        switch (yearLength) {
6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            case 353:
6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                type = 0; break;
6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            case 354:
6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                type = 1; break;
6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            case 355:
6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                type = 2; break;
6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            default:
6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                throw new IllegalArgumentException("Illegal year length " + yearLength + " in year " + year);
6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return type;
6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Determine whether a given Hebrew year is a leap year
6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The rule here is that if (year % 19) == 0, 3, 6, 8, 11, 14, or 17.
6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The formula below performs the same test, believe it or not.
6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static boolean isLeapYear(int year) {
6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //return (year * 12 + 17) % 19 >= 12;
6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int x = (year*12 + 17) % 19;
6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return x >= ((x < 0) ? -7 : 12);
6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static int monthsInYear(int year) {
6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return isLeapYear(year) ? 13 : 12;
7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Calendar framework
7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetLimit(int field, int limitType) {
7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return LIMITS[field][limitType];
7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the length of the given month in the given year
7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetMonthLength(int extendedYear, int month) {
7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Resolve out-of-range months.  This is necessary in order to
7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // obtain the correct year.  We correct to
7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // a 12- or 13-month year (add/subtract 12 or 13, depending
7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // on the year) but since we _always_ number from 0..12, and
7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // the leap year determines whether or not month 5 (Adar 1)
7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // is present, we allow 0..12 in any given year.
7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while (month < 0) {
7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            month += monthsInYear(--extendedYear);
7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Careful: allow 0..12 in all years
7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while (month > 12) {
7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            month -= monthsInYear(extendedYear++);
7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        switch (month) {
7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            case HESHVAN:
7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            case KISLEV:
7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // These two month lengths can vary
7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return MONTH_LENGTH[month][yearType(extendedYear)];
7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            default:
7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // The rest are a fixed length
7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return MONTH_LENGTH[month][0];
7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Returns the number of days in the given Hebrew year
7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetYearLength(int eyear) {
7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return (int)(startOfYear(eyear+1) - startOfYear(eyear));
7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>
7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Overrides {@link Calendar#validateField(int)} to provide
7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * special handling for month validation for Hebrew calendar.
7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @internal
7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @deprecated This API is ICU internal only.
7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    @Deprecated
7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected void validateField(int field) {
7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (field == MONTH && !isLeapYear(handleGetExtendedYear()) && internalGet(MONTH) == ADAR_1) {
7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            throw new IllegalArgumentException("MONTH cannot be ADAR_1(5) except leap years");
7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        super.validateField(field);
7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Functions for converting from milliseconds to field values
7717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Subclasses may override this method to compute several fields
7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * specific to each calendar system.  These are:
7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <ul><li>ERA
7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>YEAR
7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>MONTH
7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>DAY_OF_MONTH
7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>DAY_OF_YEAR
7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <li>EXTENDED_YEAR</ul>
7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields,
7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * which will be set when this method is called.  Subclasses can
7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * also call the getGregorianXxx() methods to obtain Gregorian
7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * calendar equivalents for the given Julian day.
7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * <p>In addition, subclasses should compute any subclass-specific
7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * fields, that is, fields from BASE_FIELD_COUNT to
7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * getFieldCount() - 1.
7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected void handleComputeFields(int julianDay) {
7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long d = julianDay - 347997;
7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long m = (d * DAY_PARTS) / MONTH_PARTS;         // Months (approx)
7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int year = (int)((19 * m + 234) / 235) + 1;     // Years (approx)
7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long ys  = startOfYear(year);                   // 1st day of year
7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dayOfYear = (int)(d - ys);
8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Because of the postponement rules, it's possible to guess wrong.  Fix it.
8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while (dayOfYear < 1) {
8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            year--;
8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ys  = startOfYear(year);
8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            dayOfYear = (int)(d - ys);
8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Now figure out which month we're in, and the date within that month
8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int yearType = yearType(year);
8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int monthStart[][] = isLeapYear(year) ? LEAP_MONTH_START : MONTH_START;
8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int month = 0;
8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while (dayOfYear > monthStart[month][yearType]) {
8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            month++;
8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        month--;
8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dayOfMonth = dayOfYear - monthStart[month][yearType];
8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(ERA, 0);
8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(YEAR, year);
8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(EXTENDED_YEAR, year);
8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(MONTH, month);
8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(DAY_OF_MONTH, dayOfMonth);
8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        internalSet(DAY_OF_YEAR, dayOfYear);
8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Functions for converting from field values to milliseconds
8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //-------------------------------------------------------------------------
8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleGetExtendedYear() {
8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int year;
8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) {
8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            year = internalGet(EXTENDED_YEAR, 1); // Default to year 1
8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            year = internalGet(YEAR, 1); // Default to year 1
8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return year;
8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Return JD of start of given month/year.
8467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 2.8
8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    protected int handleComputeMonthStart(int eyear, int month, boolean useMonth) {
8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Resolve out-of-range months.  This is necessary in order to
8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // obtain the correct year.  We correct to
8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // a 12- or 13-month year (add/subtract 12 or 13, depending
8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // on the year) but since we _always_ number from 0..12, and
8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // the leap year determines whether or not month 5 (Adar 1)
8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // is present, we allow 0..12 in any given year.
8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while (month < 0) {
8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            month += monthsInYear(--eyear);
8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Careful: allow 0..12 in all years
8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while (month > 12) {
8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            month -= monthsInYear(eyear++);
8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long day = startOfYear(eyear);
8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (month != 0) {
8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (isLeapYear(eyear)) {
8687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                day += LEAP_MONTH_START[month][yearType(eyear)];
8697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
8707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                day += MONTH_START[month][yearType(eyear)];
8717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return (int) (day + 347997);
8757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * {@inheritDoc}
8797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * @stable ICU 3.8
8807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public String getType() {
8827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return "hebrew";
8837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
8867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static CalendarFactory factory;
8877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static CalendarFactory factory() {
8887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (factory == null) {
8897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            factory = new CalendarFactory() {
8907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                public Calendar create(TimeZone tz, ULocale loc) {
8917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return new HebrewCalendar(tz, loc);
8927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
8937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                public String factoryName() {
8957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return "Hebrew";
8967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
8977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            };
8987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return factory;
9007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    */
9027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
903