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