1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2003-2008, International Business Machines Corporation
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* and others. All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File HEBRWCAL.CPP
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History:
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Date        Name        Description
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   12/03/2003  srl         ported from java HebrewCalendar
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*****************************************************************************
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "hebrwcal.h"
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h"
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <float.h>
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "gregoimp.h" // Math
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "astro.h" // CalendarAstronomer
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uhash.h"
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucln_in.h"
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Hebrew Calendar implementation
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The absolute date, in milliseconds since 1/1/1970 AD, Gregorian,
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* of the start of the Hebrew calendar.  In order to keep this calendar's
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* time of day in sync with that of the Gregorian calendar, we use
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* midnight, rather than sunset the day before.
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//static const double EPOCH_MILLIS = -180799862400000.; // 1/1/1 HY
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t LIMITS[UCAL_FIELD_COUNT][4] = {
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Minimum  Greatest    Least  Maximum
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //           Minimum  Maximum
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {        0,        0,        0,        0}, // ERA
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { -5000000, -5000000,  5000000,  5000000}, // YEAR
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {        0,        0,       12,       12}, // MONTH
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {        1,        1,       51,       56}, // WEEK_OF_YEAR
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // WEEK_OF_MONTH
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {        1,        1,       29,       30}, // DAY_OF_MONTH
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {        1,        1,      353,      385}, // DAY_OF_YEAR
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {       -1,       -1,        5,        5}, // DAY_OF_WEEK_IN_MONTH
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { -5000000, -5000000,  5000000,  5000000}, // YEAR_WOY
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { -5000000, -5000000,  5000000,  5000000}, // EXTENDED_YEAR
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECONDS_IN_DAY
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // IS_LEAP_MONTH
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The lengths of the Hebrew months.  This is complicated, because there
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* are three different types of years, or six if you count leap years.
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Due to the rules for postponing the start of the year to avoid having
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* certain holidays fall on the sabbath, the year can end up being three
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* different lengths, called "deficient", "normal", and "complete".
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int8_t MONTH_LENGTH[][3] = {
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Deficient  Normal     Complete
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30     },           //Tishri
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   29,         29,         30     },           //Heshvan
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   29,         30,         30     },           //Kislev
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   29,         29,         29     },           //Tevet
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30     },           //Shevat
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30     },           //Adar I (leap years only)
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   29,         29,         29     },           //Adar
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30     },           //Nisan
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   29,         29,         29     },           //Iyar
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30     },           //Sivan
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   29,         29,         29     },           //Tammuz
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30     },           //Av
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   29,         29,         29     },           //Elul
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The cumulative # of days to the end of each month in a non-leap year
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Although this can be calculated from the MONTH_LENGTH table,
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* keeping it around separately makes some calculations a lot faster
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int16_t MONTH_START[][3] = {
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Deficient  Normal     Complete
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {    0,          0,          0  },          // (placeholder)
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30  },          // Tishri
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   59,         59,         60  },          // Heshvan
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   88,         89,         90  },          // Kislev
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  117,        118,        119  },          // Tevet
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  147,        148,        149  },          // Shevat
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  147,        148,        149  },          // (Adar I placeholder)
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  176,        177,        178  },          // Adar
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  206,        207,        208  },          // Nisan
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  235,        236,        237  },          // Iyar
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  265,        266,        267  },          // Sivan
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  294,        295,        296  },          // Tammuz
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  324,        325,        326  },          // Av
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  353,        354,        355  },          // Elul
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The cumulative # of days to the end of each month in a leap year
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int16_t  LEAP_MONTH_START[][3] = {
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Deficient  Normal     Complete
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {    0,          0,          0  },          // (placeholder)
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   30,         30,         30  },          // Tishri
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   59,         59,         60  },          // Heshvan
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {   88,         89,         90  },          // Kislev
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  117,        118,        119  },          // Tevet
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  147,        148,        149  },          // Shevat
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  177,        178,        179  },          // Adar I
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  206,        207,        208  },          // Adar II
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  236,        237,        238  },          // Nisan
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  265,        266,        267  },          // Iyar
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  295,        296,        297  },          // Sivan
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  324,        325,        326  },          // Tammuz
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  354,        355,        356  },          // Av
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {  383,        384,        385  },          // Elul
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_NAMESPACE_QUALIFIER CalendarCache *gCache =  NULL;
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_BEGIN
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool calendar_hebrew_cleanup(void) {
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete gCache;
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    gCache = NULL;
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return TRUE;
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_END
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Constructors...
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Constructs a default <code>HebrewCalendar</code> using the current time
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* in the default time zone with the default locale.
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)HebrewCalendar::HebrewCalendar(const Locale& aLocale, UErrorCode& success)
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   Calendar(TimeZone::createDefault(), aLocale, success)
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)HebrewCalendar::~HebrewCalendar() {
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const char *HebrewCalendar::getType() const {
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return "hebrew";
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Calendar* HebrewCalendar::clone() const {
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return new HebrewCalendar(*this);
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)HebrewCalendar::HebrewCalendar(const HebrewCalendar& other) : Calendar(other) {
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Rolling and adding functions overridden from Calendar
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// These methods call through to the default implementation in IBMCalendar
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// for most of the fields and only handle the unusual ones themselves.
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Add a signed amount to a specified field, using this calendar's rules.
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* For example, to add three days to the current date, you can call
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <code>add(Calendar.DATE, 3)</code>.
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* When adding to certain fields, the values of other fields may conflict and
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* need to be changed.  For example, when adding one to the {@link #MONTH MONTH} field
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* for the date "30 Av 5758", the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* must be adjusted so that the result is "29 Elul 5758" rather than the invalid
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* "30 Elul 5758".
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* This method is able to add to
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* and {@link #ZONE_OFFSET ZONE_OFFSET}.
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <b>Note:</b> You should always use {@link #roll roll} and add rather
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* than attempting to perform arithmetic operations directly on the fields
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* of a <tt>HebrewCalendar</tt>.  Since the {@link #MONTH MONTH} field behaves
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* discontinuously in non-leap years, simple arithmetic can give invalid results.
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param field     the time field.
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param amount    the amount to add to the field.
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @exception   IllegalArgumentException if the field is invalid or refers
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*              to a field that cannot be handled by this method.
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void HebrewCalendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status)
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(status)) {
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (field) {
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  case UCAL_MONTH:
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      {
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          // We can't just do a set(MONTH, get(MONTH) + amount).  The
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          // reason is ADAR_1.  Suppose amount is +2 and we land in
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          // ADAR_1 -- then we have to bump to ADAR_2 aka ADAR.  But
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          // if amount is -2 and we land in ADAR_1, then we have to
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          // bump the other way -- down to SHEVAT.  - Alan 11/00
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          int32_t month = get(UCAL_MONTH, status);
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          int32_t year = get(UCAL_YEAR, status);
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          UBool acrossAdar1;
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if (amount > 0) {
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              acrossAdar1 = (month < ADAR_1); // started before ADAR_1?
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              month += amount;
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              for (;;) {
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  if (acrossAdar1 && month>=ADAR_1 && !isLeapYear(year)) {
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      ++month;
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  }
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  if (month <= ELUL) {
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      break;
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  }
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  month -= ELUL+1;
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  ++year;
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  acrossAdar1 = TRUE;
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              }
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          } else {
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              acrossAdar1 = (month > ADAR_1); // started after ADAR_1?
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              month += amount;
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              for (;;) {
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  if (acrossAdar1 && month<=ADAR_1 && !isLeapYear(year)) {
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      --month;
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  }
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  if (month >= 0) {
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      break;
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  }
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  month += ELUL+1;
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  --year;
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  acrossAdar1 = TRUE;
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              }
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          set(UCAL_MONTH, month);
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          set(UCAL_YEAR, year);
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          pinField(UCAL_DAY_OF_MONTH, status);
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          break;
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  default:
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      Calendar::add(field, amount, status);
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      break;
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @deprecated ICU 2.6 use UCalendarDateFields instead of EDateFields
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void HebrewCalendar::add(EDateFields field, int32_t amount, UErrorCode& status)
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    add((UCalendarDateFields)field, amount, status);
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Rolls (up/down) a specified amount time on the given field.  For
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* example, to roll the current date up by three days, you can call
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <code>roll(Calendar.DATE, 3)</code>.  If the
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* field is rolled past its maximum allowable value, it will "wrap" back
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* to its minimum and continue rolling.
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* For example, calling <code>roll(Calendar.DATE, 10)</code>
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* on a Hebrew calendar set to "25 Av 5758" will result in the date "5 Av 5758".
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* When rolling certain fields, the values of other fields may conflict and
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* need to be changed.  For example, when rolling the {@link #MONTH MONTH} field
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* upward by one for the date "30 Av 5758", the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* must be adjusted so that the result is "29 Elul 5758" rather than the invalid
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* "30 Elul".
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* This method is able to roll
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* additional fields in their overrides of <code>roll</code>.
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <b>Note:</b> You should always use roll and {@link #add add} rather
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* than attempting to perform arithmetic operations directly on the fields
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* of a <tt>HebrewCalendar</tt>.  Since the {@link #MONTH MONTH} field behaves
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* discontinuously in non-leap years, simple arithmetic can give invalid results.
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param field     the time field.
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param amount    the amount by which the field should be rolled.
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @exception   IllegalArgumentException if the field is invalid or refers
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*              to a field that cannot be handled by this method.
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void HebrewCalendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& status)
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(status)) {
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (field) {
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  case UCAL_MONTH:
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      {
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          int32_t month = get(UCAL_MONTH, status);
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          int32_t year = get(UCAL_YEAR, status);
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          UBool leapYear = isLeapYear(year);
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          int32_t yearLength = monthsInYear(year);
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          int32_t newMonth = month + (amount % yearLength);
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          //
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          // If it's not a leap year and we're rolling past the missing month
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          // of ADAR_1, we need to roll an extra month to make up for it.
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          //
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if (!leapYear) {
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              if (amount > 0 && month < ADAR_1 && newMonth >= ADAR_1) {
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  newMonth++;
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              } else if (amount < 0 && month > ADAR_1 && newMonth <= ADAR_1) {
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  newMonth--;
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              }
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          }
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          set(UCAL_MONTH, (newMonth + 13) % 13);
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          pinField(UCAL_DAY_OF_MONTH, status);
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          return;
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  default:
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      Calendar::roll(field, amount, status);
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void HebrewCalendar::roll(EDateFields field, int32_t amount, UErrorCode& status) {
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    roll((UCalendarDateFields)field, amount, status);
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Support methods
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Hebrew date calculations are performed in terms of days, hours, and
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t HOUR_PARTS = 1080;
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t DAY_PARTS  = 24*HOUR_PARTS;
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// An approximate value for the length of a lunar month.
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// It is used to calculate the approximate year and month of a given
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// absolute date.
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t  MONTH_DAYS = 29;
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t MONTH_FRACT = 12*HOUR_PARTS + 793;
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t MONTH_PARTS = MONTH_DAYS*DAY_PARTS + MONTH_FRACT;
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// The time of the new moon (in parts) on 1 Tishri, year 1 (the epoch)
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// counting from noon on the day before.  BAHARAD is an abbreviation of
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Bet (Monday), Hey (5 hours from sunset), Resh-Daled (204).
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t BAHARAD = 11*HOUR_PARTS + 204;
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Finds the day # of the first day in the given Hebrew year.
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* To do this, we want to calculate the time of the Tishri 1 new moon
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* in that year.
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The algorithm here is similar to ones described in a number of
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* references, including:
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <ul>
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>"Calendrical Calculations", by Nachum Dershowitz & Edward Reingold,
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*     Cambridge University Press, 1997, pages 85-91.
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>Hebrew Calendar Science and Myths,
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*     <a href="http://www.geocities.com/Athens/1584/">
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*     http://www.geocities.com/Athens/1584/</a>
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>The Calendar FAQ,
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*      <a href="http://www.faqs.org/faqs/calendars/faq/">
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*      http://www.faqs.org/faqs/calendars/faq/</a>
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* </ul>
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::startOfYear(int32_t year, UErrorCode &status)
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucln_i18n_registerCleanup(UCLN_I18N_HEBREW_CALENDAR, calendar_hebrew_cleanup);
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t day = CalendarCache::get(&gCache, year, status);
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (day == 0) {
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t months = (235 * year - 234) / 19;           // # of months before year
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int64_t frac = (int64_t)months * MONTH_FRACT + BAHARAD;  // Fractional part of day #
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        day  = months * 29 + (int32_t)(frac / DAY_PARTS);        // Whole # part of calculation
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        frac = frac % DAY_PARTS;                        // Time of day
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t wd = (day % 7);                        // Day of week (0 == Monday)
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (wd == 2 || wd == 4 || wd == 6) {
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // If the 1st is on Sun, Wed, or Fri, postpone to the next day
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            day += 1;
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            wd = (day % 7);
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (wd == 1 && frac > 15*HOUR_PARTS+204 && !isLeapYear(year) ) {
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // If the new moon falls after 3:11:20am (15h204p from the previous noon)
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // on a Tuesday and it is not a leap year, postpone by 2 days.
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // This prevents 356-day years.
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            day += 2;
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (wd == 0 && frac > 21*HOUR_PARTS+589 && isLeapYear(year-1) ) {
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // If the new moon falls after 9:32:43 1/3am (21h589p from yesterday noon)
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // on a Monday and *last* year was a leap year, postpone by 1 day.
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Prevents 382-day years.
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            day += 1;
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        CalendarCache::put(&gCache, year, day, status);
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return day;
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Find the day of the week for a given day
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param day   The # of days since the start of the Hebrew calendar,
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*              1-based (i.e. 1/1/1 AM is day 1).
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::absoluteDayToDayOfWeek(int32_t day)
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // We know that 1/1/1 AM is a Monday, which makes the math easy...
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (day % 7) + 1;
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Returns the the type of a given year.
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*  0   "Deficient" year with 353 or 383 days
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*  1   "Normal"    year with 354 or 384 days
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*  2   "Complete"  year with 355 or 385 days
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::yearType(int32_t year) const
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t yearLength = handleGetYearLength(year);
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (yearLength > 380) {
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        yearLength -= 30;        // Subtract length of leap month.
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int type = 0;
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (yearLength) {
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  case 353:
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      type = 0; break;
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  case 354:
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      type = 1; break;
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  case 355:
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      type = 2; break;
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  default:
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      //throw new RuntimeException("Illegal year length " + yearLength + " in year " + year);
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      type = 1;
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return type;
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Determine whether a given Hebrew year is a leap year
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The rule here is that if (year % 19) == 0, 3, 6, 8, 11, 14, or 17.
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The formula below performs the same test, believe it or not.
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool HebrewCalendar::isLeapYear(int32_t year) {
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //return (year * 12 + 17) % 19 >= 12;
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t x = (year*12 + 17) % 19;
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return x >= ((x < 0) ? -7 : 12);
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::monthsInYear(int32_t year) {
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return isLeapYear(year) ? 13 : 12;
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Calendar framework
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const {
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return LIMITS[field][limitType];
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Returns the length of the given month in the given year
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Resolve out-of-range months.  This is necessary in order to
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // obtain the correct year.  We correct to
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // a 12- or 13-month year (add/subtract 12 or 13, depending
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // on the year) but since we _always_ number from 0..12, and
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the leap year determines whether or not month 5 (Adar 1)
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // is present, we allow 0..12 in any given year.
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (month < 0) {
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        month += monthsInYear(--extendedYear);
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Careful: allow 0..12 in all years
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (month > 12) {
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        month -= monthsInYear(extendedYear++);
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (month) {
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case HESHVAN:
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case KISLEV:
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      // These two month lengths can vary
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return MONTH_LENGTH[month][yearType(extendedYear)];
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    default:
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      // The rest are a fixed length
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return MONTH_LENGTH[month][0];
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Returns the number of days in the given Hebrew year
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::handleGetYearLength(int32_t eyear) const {
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return startOfYear(eyear+1, status) - startOfYear(eyear, status);
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Functions for converting from milliseconds to field values
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Subclasses may override this method to compute several fields
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* specific to each calendar system.  These are:
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <ul><li>ERA
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>YEAR
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>MONTH
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>DAY_OF_MONTH
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>DAY_OF_YEAR
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>EXTENDED_YEAR</ul>
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields,
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* which will be set when this method is called.  Subclasses can
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* also call the getGregorianXxx() methods to obtain Gregorian
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* calendar equivalents for the given Julian day.
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <p>In addition, subclasses should compute any subclass-specific
553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* fields, that is, fields from BASE_FIELD_COUNT to
554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* getFieldCount() - 1.
555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void HebrewCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) {
558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t d = julianDay - 347997;
559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    double m = ((d * (double)DAY_PARTS)/ (double) MONTH_PARTS);         // Months (approx)
560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t year = (int32_t)( ((19. * m + 234.) / 235.) + 1.);     // Years (approx)
561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t ys  = startOfYear(year, status);                   // 1st day of year
562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t dayOfYear = (d - ys);
563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Because of the postponement rules, it's possible to guess wrong.  Fix it.
565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (dayOfYear < 1) {
566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        year--;
567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ys  = startOfYear(year, status);
568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        dayOfYear = (d - ys);
569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Now figure out which month we're in, and the date within that month
572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t type = yearType(year);
573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool isLeap = isLeapYear(year);
574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t month = 0;
576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t momax = sizeof(MONTH_START) / (3 * sizeof(MONTH_START[0][0]));
577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (month < momax && dayOfYear > (  isLeap ? LEAP_MONTH_START[month][type] : MONTH_START[month][type] ) ) {
578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        month++;
579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (month >= momax || month<=0) {
581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // TODO: I found dayOfYear could be out of range when
582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // a large value is set to julianDay.  I patched startOfYear
583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // to reduce the chace, but it could be still reproduced either
584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // by startOfYear or other places.  For now, we check
585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // the month is in valid range to avoid out of array index
586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // access problem here.  However, we need to carefully review
587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // the calendar implementation to check the extreme limit of
588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // each calendar field and the code works well for any values
589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // in the valid value range.  -yoshito
590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_ILLEGAL_ARGUMENT_ERROR;
591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    month--;
594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int dayOfMonth = dayOfYear - (isLeap ? LEAP_MONTH_START[month][type] : MONTH_START[month][type]);
595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    internalSet(UCAL_ERA, 0);
597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    internalSet(UCAL_YEAR, year);
598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    internalSet(UCAL_EXTENDED_YEAR, year);
599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    internalSet(UCAL_MONTH, month);
600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    internalSet(UCAL_DAY_OF_MONTH, dayOfMonth);
601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Functions for converting from field values to milliseconds
606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------
607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::handleGetExtendedYear() {
612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t year;
613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        year = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        year = internalGet(UCAL_YEAR, 1); // Default to year 1
617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return year;
619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Return JD of start of given month/year.
623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @internal
624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /*useMonth*/) const {
626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Resolve out-of-range months.  This is necessary in order to
628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // obtain the correct year.  We correct to
629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // a 12- or 13-month year (add/subtract 12 or 13, depending
630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // on the year) but since we _always_ number from 0..12, and
631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the leap year determines whether or not month 5 (Adar 1)
632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // is present, we allow 0..12 in any given year.
633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (month < 0) {
634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        month += monthsInYear(--eyear);
635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Careful: allow 0..12 in all years
637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (month > 12) {
638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        month -= monthsInYear(eyear++);
639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t day = startOfYear(eyear, status);
642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(status)) {
644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (month != 0) {
648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (isLeapYear(eyear)) {
649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            day += LEAP_MONTH_START[month][yearType(eyear)];
650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            day += MONTH_START[month][yearType(eyear)];
652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (int) (day + 347997);
656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)HebrewCalendar::inDaylightTime(UErrorCode& status) const
660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // copied from GregorianCalendar
662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status) || !getTimeZone().useDaylightTime())
663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return FALSE;
664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Force an update of the state of the Calendar.
666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ((HebrewCalendar*)this)->complete(status); // cast away const
667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// default century
672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UDate     HebrewCalendar::fgSystemDefaultCentury        = DBL_MIN;
673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int32_t   HebrewCalendar::fgSystemDefaultCenturyYear    = -1;
674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate           HebrewCalendar::fgSystemDefaultCenturyStart       = DBL_MIN;
676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t         HebrewCalendar::fgSystemDefaultCenturyStartYear   = -1;
677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool HebrewCalendar::haveDefaultCentury() const
680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return TRUE;
682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate HebrewCalendar::defaultCenturyStart() const
685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return internalGetDefaultCenturyStart();
687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t HebrewCalendar::defaultCenturyStartYear() const
690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return internalGetDefaultCenturyStartYear();
692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate
695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)HebrewCalendar::internalGetDefaultCenturyStart() const
696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // lazy-evaluate systemDefaultCenturyStart
698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool needsUpdate;
699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (needsUpdate) {
702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        initializeSystemDefaultCentury();
703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // use defaultCenturyStart unless it's the flag value;
706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // then use systemDefaultCenturyStart
707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fgSystemDefaultCenturyStart;
709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)HebrewCalendar::internalGetDefaultCenturyStartYear() const
713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // lazy-evaluate systemDefaultCenturyStartYear
715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool needsUpdate;
716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (needsUpdate) {
719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        initializeSystemDefaultCentury();
720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // use defaultCenturyStart unless it's the flag value;
723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // then use systemDefaultCenturyStartYear
724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fgSystemDefaultCenturyStartYear;
726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)HebrewCalendar::initializeSystemDefaultCentury()
730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // initialize systemDefaultCentury and systemDefaultCenturyYear based
732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // on the current time.  They'll be set to 80 years before
733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the current time.
734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HebrewCalendar calendar(Locale("@calendar=hebrew"),status);
736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_SUCCESS(status))
737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        calendar.setTime(Calendar::getNow(), status);
739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        calendar.add(UCAL_YEAR, -80, status);
740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UDate    newStart =  calendar.getTime(status);
741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t  newYear  =  calendar.get(UCAL_YEAR, status);
742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_lock(NULL);
743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury) {
744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fgSystemDefaultCenturyStartYear = newYear;
745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fgSystemDefaultCenturyStart = newStart;
746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_unlock(NULL);
748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // We have no recourse upon failure unless we want to propagate the failure
750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // out.
751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UOBJECT_DEFINE_RTTI_IMPLEMENTATION(HebrewCalendar)
754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END
756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif // UCONFIG_NO_FORMATTING
758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
759