diff --git a/icu4c/source/i18n/buddhcal.cpp b/icu4c/source/i18n/buddhcal.cpp index 89cf6426b0a..5e2aea9466e 100644 --- a/icu4c/source/i18n/buddhcal.cpp +++ b/icu4c/source/i18n/buddhcal.cpp @@ -17,6 +17,7 @@ #include "buddhcal.h" #include "unicode/gregocal.h" +#include "mutex.h" #include U_NAMESPACE_BEGIN @@ -94,16 +95,6 @@ BuddhistCalendar::monthLength(int32_t month) const return monthLength(month, year); } -#if 0 -UBool -BuddhistCalendar::isLeapYear(int32_t year) const -{ - return (year >= fGregorianCutoverYear ? - ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0))) : // Gregorian - (year%4 == 0)); // Julian -} -#endif - int32_t BuddhistCalendar::internalGetEra() const { return isSet(UCAL_ERA) ? internalGet(UCAL_ERA) : BE; @@ -196,9 +187,16 @@ UDate BuddhistCalendar::internalGetDefaultCenturyStart() const { // lazy-evaluate systemDefaultCenturyStart - if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury) + UBool needsUpdate; + { + Mutex m; + needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury); + } + + if (needsUpdate) { initializeSystemDefaultCentury(); - + } + // use defaultCenturyStart unless it's the flag value; // then use systemDefaultCenturyStart @@ -208,14 +206,21 @@ BuddhistCalendar::internalGetDefaultCenturyStart() const int32_t BuddhistCalendar::internalGetDefaultCenturyStartYear() const { - // lazy-evaluate systemDefaultCenturyStartYear - if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury) - initializeSystemDefaultCentury(); + // lazy-evaluate systemDefaultCenturyStartYear + UBool needsUpdate; + { + Mutex m; + needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury); + } - // use defaultCenturyStart unless it's the flag value; - // then use systemDefaultCenturyStartYear + if (needsUpdate) { + initializeSystemDefaultCentury(); + } - return fgSystemDefaultCenturyStartYear; + // use defaultCenturyStart unless it's the flag value; + // then use systemDefaultCenturyStartYear + + return fgSystemDefaultCenturyStartYear; } void @@ -233,8 +238,13 @@ BuddhistCalendar::initializeSystemDefaultCentury() { calendar->setTime(Calendar::getNow(), status); calendar->add(UCAL_YEAR, -80, status); - fgSystemDefaultCenturyStart = calendar->getTime(status); - fgSystemDefaultCenturyStartYear = calendar->get(UCAL_YEAR, status); + UDate newStart = calendar->getTime(status); + int32_t newYear = calendar->get(UCAL_YEAR, status); + { + Mutex m; + fgSystemDefaultCenturyStart = newStart; + fgSystemDefaultCenturyStartYear = newYear; + } delete calendar; } // We have no recourse upon failure unless we want to propagate the failure diff --git a/icu4c/source/i18n/gregocal.cpp b/icu4c/source/i18n/gregocal.cpp index 1d1f399dd5e..3feda612407 100644 --- a/icu4c/source/i18n/gregocal.cpp +++ b/icu4c/source/i18n/gregocal.cpp @@ -46,10 +46,6 @@ #include "unicode/smpdtfmt.h" /* for the public field (!) SimpleDateFormat::fgSystemDefaultCentury */ #include "mutex.h" -#ifdef U_DEBUG_GREGOCAL -#include -#endif - // ***************************************************************************** // class GregorianCalendar @@ -734,9 +730,6 @@ GregorianCalendar::validateFields() const field != UCAL_DAY_OF_YEAR && isSet((UCalendarDateFields)field) && ! boundsCheck(internalGet((UCalendarDateFields)field), (UCalendarDateFields)field)) -#ifdef U_DEBUG_GREGOCAL - fprintf(stderr, " field %d set to %d but out of bounds\n", field, internalGet((UCalendarDateFields)field));fflush(stderr); -#endif return FALSE; } @@ -746,9 +739,6 @@ GregorianCalendar::validateFields() const int32_t date = internalGet(UCAL_DATE); if (date < getMinimum(UCAL_DATE) || date > monthLength(internalGet(UCAL_MONTH))) { -#ifdef U_DEBUG_GREGOCAL - fprintf(stderr, " date %d out of bounds\n", internalGet(UCAL_DATE));fflush(stderr); -#endif return FALSE; } } @@ -756,9 +746,6 @@ GregorianCalendar::validateFields() const if (isSet(UCAL_DAY_OF_YEAR)) { int32_t days = internalGet(UCAL_DAY_OF_YEAR); if (days < 1 || days > yearLength()) { -#ifdef U_DEBUG_GREGOCAL - fprintf(stderr, " doy %d out of bounds\n", internalGet(UCAL_DAY_OF_YEAR));fflush(stderr); -#endif return FALSE; } } @@ -767,9 +754,6 @@ GregorianCalendar::validateFields() const // We've checked against minimum and maximum above already. if (isSet(UCAL_DAY_OF_WEEK_IN_MONTH) && 0 == internalGet(UCAL_DAY_OF_WEEK_IN_MONTH)) { -#ifdef U_DEBUG_GREGOCAL - fprintf(stderr, " DOWIM == %d, should be 0\n", internalGet(UCAL_DAY_OF_WEEK_IN_MONTH));fflush(stderr); -#endif return FALSE; } @@ -812,9 +796,6 @@ GregorianCalendar::getGregorianYear(UErrorCode &status) const year = 1 - year; // Even in lenient mode we disallow ERA values other than AD & BC else if (era != AD) { -#ifdef U_DEBUG_GREGOCAL - fprintf(stderr,"Era = %d, not AD/BC\n", era); fflush(stderr); -#endif status = U_ILLEGAL_ARGUMENT_ERROR; return kEpochYear; } @@ -829,9 +810,6 @@ GregorianCalendar::computeTime(UErrorCode& status) return; if (! isLenient() && ! validateFields()) { -#ifdef U_DEBUG_GREGOCAL - fprintf(stderr,"validate failed\n"); fflush(stderr); -#endif status = U_ILLEGAL_ARGUMENT_ERROR; return; } @@ -1066,6 +1044,7 @@ int32_t GregorianCalendar::computeDOYfromWOY(double julianDayOfYear) const { double GregorianCalendar::computeJulianDay(UBool isGregorian, int32_t year) { + // Assumes 'year' is gregorian. // Find the most recent set of fields specifying the day within // the year. These may be any of the following combinations: // MONTH* + DAY_OF_MONTH* diff --git a/icu4c/source/i18n/japancal.cpp b/icu4c/source/i18n/japancal.cpp index ea6e5ccf660..11f3459d233 100644 --- a/icu4c/source/i18n/japancal.cpp +++ b/icu4c/source/i18n/japancal.cpp @@ -339,9 +339,10 @@ JapaneseCalendar::monthLength(int32_t month, int32_t year) const int32_t JapaneseCalendar::monthLength(int32_t month) const { - int32_t year = internalGet(UCAL_YEAR); - // ignore era - return monthLength(month, year); + UErrorCode status = U_ZERO_ERROR; + int32_t year = internalGet(UCAL_YEAR); + // ignore era + return GregorianCalendar::monthLength(month, getGregorianYear(status)); } int32_t JapaneseCalendar::getDefaultMonthInYear() const @@ -357,7 +358,7 @@ int32_t JapaneseCalendar::getDefaultMonthInYear() const if(year == kEraInfo[era].year) { // Yes, we're in the first year of this era. - return kEraInfo[era].month; + return kEraInfo[era].month-1; } if(era < kCurrentEra) { @@ -376,7 +377,7 @@ int32_t JapaneseCalendar::getDefaultDayInMonth(int32_t month) const int32_t day = GregorianCalendar::getDefaultDayInMonth(month); if(year == kEraInfo[era].year) { - if(month == kEraInfo[era].month) { + if(month == (kEraInfo[era].month-1)) { return kEraInfo[era].day; } } @@ -393,14 +394,14 @@ int32_t JapaneseCalendar::internalGetEra() const int32_t JapaneseCalendar::getGregorianYear(UErrorCode &status) const { - int32_t year = (fStamp[UCAL_YEAR] != kUnset) ? internalGet(UCAL_YEAR) : 0; + int32_t year = (fStamp[UCAL_YEAR] != kUnset) ? internalGet(UCAL_YEAR) : 1; // default year = 1 int32_t era = kCurrentEra; if (fStamp[UCAL_ERA] != kUnset) { era = internalGet(UCAL_ERA); } if ((era<0)||(era>kCurrentEra)) { - status = U_BRK_INIT_ERROR; + status = U_ILLEGAL_ARGUMENT_ERROR; return 0 ; } return year + kEraInfo[era].year - 1; @@ -477,7 +478,7 @@ void JapaneseCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& stat } #ifdef U_DEBUG_JCAL - fprintf(stderr, " low=%d,.. %d\n", low, year); + fprintf(stderr, " low[era]=%d,.. %d\n", low, year); #endif // Now we've found the last era that starts before this date, so // adjust the year to count from the start of that era. Note that @@ -486,6 +487,10 @@ void JapaneseCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& stat internalSet(UCAL_ERA, low); internalSet(UCAL_YEAR, year - kEraInfo[low].year + 1); +#ifdef U_DEBUG_JCAL + fprintf(stderr, " Set ERA=%d, year=%d\n", low, year-kEraInfo[low].year+1); +#endif + } /*