ICU-5349 Use UMTX_CHECK when it's helpful.

X-SVN-Rev: 20269
This commit is contained in:
George Rhoten 2006-09-08 04:02:23 +00:00
parent daba19ab1f
commit b5781126c8
6 changed files with 3364 additions and 3384 deletions

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2003-2004, International Business Machines Corporation and *
* Copyright (C) 2003-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@ -17,7 +17,7 @@
#include "buddhcal.h"
#include "unicode/gregocal.h"
#include "mutex.h"
#include "umutex.h"
#include <float.h>
U_NAMESPACE_BEGIN
@ -31,7 +31,7 @@ static const int32_t kBuddhistEraStart = -543; // 544 BC (Gregorian)
static const int32_t kGregorianEpoch = 1970;
BuddhistCalendar::BuddhistCalendar(const Locale& aLocale, UErrorCode& success)
: GregorianCalendar(aLocale, success)
: GregorianCalendar(aLocale, success)
{
setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
}
@ -41,50 +41,50 @@ BuddhistCalendar::~BuddhistCalendar()
}
BuddhistCalendar::BuddhistCalendar(const BuddhistCalendar& source)
: GregorianCalendar(source)
: GregorianCalendar(source)
{
}
BuddhistCalendar& BuddhistCalendar::operator= ( const BuddhistCalendar& right)
{
GregorianCalendar::operator=(right);
return *this;
GregorianCalendar::operator=(right);
return *this;
}
Calendar* BuddhistCalendar::clone(void) const
{
return new BuddhistCalendar(*this);
return new BuddhistCalendar(*this);
}
const char *BuddhistCalendar::getType() const
{
return "buddhist";
return "buddhist";
}
int32_t
BuddhistCalendar::getMaximum(UCalendarDateFields field) const
{
if(field == UCAL_ERA) {
return kMaxEra;
} else {
return GregorianCalendar::getMaximum(field);
}
if(field == UCAL_ERA) {
return kMaxEra;
} else {
return GregorianCalendar::getMaximum(field);
}
}
int32_t
BuddhistCalendar::getLeastMaximum(UCalendarDateFields field) const
{
if(field == UCAL_ERA) {
return kMaxEra;
} else {
return GregorianCalendar::getLeastMaximum(field);
}
if(field == UCAL_ERA) {
return kMaxEra;
} else {
return GregorianCalendar::getLeastMaximum(field);
}
}
int32_t
BuddhistCalendar::monthLength(int32_t month, int32_t year) const
{
return GregorianCalendar::monthLength(month,year);
return GregorianCalendar::monthLength(month,year);
}
@ -98,82 +98,82 @@ BuddhistCalendar::monthLength(int32_t month) const
int32_t BuddhistCalendar::internalGetEra() const
{
return internalGet(UCAL_ERA, BE);
return internalGet(UCAL_ERA, BE);
}
int32_t
BuddhistCalendar::getGregorianYear(UErrorCode &status) const
{
int32_t year = (fStamp[UCAL_YEAR] != kUnset) ? internalGet(UCAL_YEAR) : kGregorianEpoch+kBuddhistEraStart;
int32_t era = BE;
if (fStamp[UCAL_ERA] != kUnset) {
era = internalGet(UCAL_ERA);
if (era != BE) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return kGregorianEpoch + kBuddhistEraStart;
int32_t year = (fStamp[UCAL_YEAR] != kUnset) ? internalGet(UCAL_YEAR) : kGregorianEpoch+kBuddhistEraStart;
int32_t era = BE;
if (fStamp[UCAL_ERA] != kUnset) {
era = internalGet(UCAL_ERA);
if (era != BE) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return kGregorianEpoch + kBuddhistEraStart;
}
}
}
return year + kBuddhistEraStart;
return year + kBuddhistEraStart;
}
int32_t BuddhistCalendar::handleGetExtendedYear()
{
int32_t year;
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
year = internalGet(UCAL_EXTENDED_YEAR, 1);
} else {
// Ignore the era, as there is only one
year = internalGet(UCAL_YEAR, 1);
}
return year;
int32_t year;
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
year = internalGet(UCAL_EXTENDED_YEAR, 1);
} else {
// Ignore the era, as there is only one
year = internalGet(UCAL_YEAR, 1);
}
return year;
}
int32_t BuddhistCalendar::handleComputeMonthStart(int32_t eyear, int32_t month,
UBool useMonth) const
UBool useMonth) const
{
return GregorianCalendar::handleComputeMonthStart(eyear+kBuddhistEraStart, month, useMonth);
return GregorianCalendar::handleComputeMonthStart(eyear+kBuddhistEraStart, month, useMonth);
}
void BuddhistCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
{
GregorianCalendar::handleComputeFields(julianDay, status);
int32_t y = internalGet(UCAL_EXTENDED_YEAR) - kBuddhistEraStart;
internalSet(UCAL_EXTENDED_YEAR, y);
internalSet(UCAL_ERA, 0);
internalSet(UCAL_YEAR, y);
GregorianCalendar::handleComputeFields(julianDay, status);
int32_t y = internalGet(UCAL_EXTENDED_YEAR) - kBuddhistEraStart;
internalSet(UCAL_EXTENDED_YEAR, y);
internalSet(UCAL_ERA, 0);
internalSet(UCAL_YEAR, y);
}
int32_t BuddhistCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
{
if(field == UCAL_ERA) {
return BE;
} else {
return GregorianCalendar::handleGetLimit(field,limitType);
}
if(field == UCAL_ERA) {
return BE;
} else {
return GregorianCalendar::handleGetLimit(field,limitType);
}
}
#if 0
void BuddhistCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& status)
{
//Calendar::timeToFields(theTime, quick, status);
//Calendar::timeToFields(theTime, quick, status);
int32_t era = internalGet(UCAL_ERA);
int32_t year = internalGet(UCAL_YEAR);
int32_t era = internalGet(UCAL_ERA);
int32_t year = internalGet(UCAL_YEAR);
if(era == GregorianCalendar::BC) {
year = 1-year;
era = BuddhistCalendar::BE;
} else if(era == GregorianCalendar::AD) {
era = BuddhistCalendar::BE;
} else {
status = U_INTERNAL_PROGRAM_ERROR;
}
if(era == GregorianCalendar::BC) {
year = 1-year;
era = BuddhistCalendar::BE;
} else if(era == GregorianCalendar::AD) {
era = BuddhistCalendar::BE;
} else {
status = U_INTERNAL_PROGRAM_ERROR;
}
year = year - kBuddhistEraStart;
internalSet(UCAL_ERA, era);
internalSet(UCAL_YEAR, year);
year = year - kBuddhistEraStart;
internalSet(UCAL_ERA, era);
internalSet(UCAL_YEAR, year);
}
#endif
@ -184,16 +184,16 @@ void BuddhistCalendar::add(UCalendarDateFields field, int32_t amount, UErrorCode
if (amount == 0)
return; // Do nothing!
if(field == UCAL_YEAR /* || field == UCAL_YEAR_WOY */) {
int32_t year = get(field, status); // not internalGet -- force completion
year += amount;
set(field,year);
pinDayOfMonth();
} else {
GregorianCalendar::add(field,amount,status);
GregorianCalendar::add(field,amount,status);
}
}
@ -209,85 +209,80 @@ int32_t BuddhistCalendar::fgSystemDefaultCenturyStartYear = -1;
UBool BuddhistCalendar::haveDefaultCentury() const
{
return TRUE;
return TRUE;
}
UDate BuddhistCalendar::defaultCenturyStart() const
{
return internalGetDefaultCenturyStart();
return internalGetDefaultCenturyStart();
}
int32_t BuddhistCalendar::defaultCenturyStartYear() const
{
return internalGetDefaultCenturyStartYear();
return internalGetDefaultCenturyStartYear();
}
UDate
BuddhistCalendar::internalGetDefaultCenturyStart() const
{
// lazy-evaluate systemDefaultCenturyStart
UBool needsUpdate;
{
Mutex m;
needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
}
// lazy-evaluate systemDefaultCenturyStart
UBool needsUpdate;
UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
if (needsUpdate) {
initializeSystemDefaultCentury();
}
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStart
return fgSystemDefaultCenturyStart;
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStart
return fgSystemDefaultCenturyStart;
}
int32_t
BuddhistCalendar::internalGetDefaultCenturyStartYear() const
{
// lazy-evaluate systemDefaultCenturyStartYear
UBool needsUpdate;
{
Mutex m;
needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
}
// lazy-evaluate systemDefaultCenturyStartYear
UBool needsUpdate;
UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
if (needsUpdate) {
initializeSystemDefaultCentury();
}
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStartYear
return fgSystemDefaultCenturyStartYear;
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStartYear
return fgSystemDefaultCenturyStartYear;
}
void
BuddhistCalendar::initializeSystemDefaultCentury()
{
// initialize systemDefaultCentury and systemDefaultCenturyYear based
// on the current time. They'll be set to 80 years before
// the current time.
// No point in locking as it should be idempotent.
if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
{
UErrorCode status = U_ZERO_ERROR;
BuddhistCalendar calendar(Locale("@calendar=buddhist"),status);
if (U_SUCCESS(status))
// initialize systemDefaultCentury and systemDefaultCenturyYear based
// on the current time. They'll be set to 80 years before
// the current time.
// No point in locking as it should be idempotent.
if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
{
calendar.setTime(Calendar::getNow(), status);
calendar.add(UCAL_YEAR, -80, status);
UDate newStart = calendar.getTime(status);
int32_t newYear = calendar.get(UCAL_YEAR, status);
{
Mutex m;
fgSystemDefaultCenturyStart = newStart;
fgSystemDefaultCenturyStartYear = newYear;
}
UErrorCode status = U_ZERO_ERROR;
BuddhistCalendar calendar(Locale("@calendar=buddhist"),status);
if (U_SUCCESS(status))
{
calendar.setTime(Calendar::getNow(), status);
calendar.add(UCAL_YEAR, -80, status);
UDate newStart = calendar.getTime(status);
int32_t newYear = calendar.get(UCAL_YEAR, status);
{
umtx_lock(NULL);
fgSystemDefaultCenturyStart = newStart;
fgSystemDefaultCenturyStartYear = newYear;
umtx_unlock(NULL);
}
}
// We have no recourse upon failure unless we want to propagate the failure
// out.
}
// We have no recourse upon failure unless we want to propagate the failure
// out.
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,23 @@
/*
* Copyright (C) 2003-2006, International Business Machines Corporation
* and others. All Rights Reserved.
******************************************************************************
*
* File ISLAMCAL.H
*
* Modification History:
*
* Date Name Description
* 10/14/2003 srl ported from java IslamicCalendar
*****************************************************************************
*/
******************************************************************************
* Copyright (C) 2003-2006, International Business Machines Corporation
* and others. All Rights Reserved.
******************************************************************************
*
* File ISLAMCAL.H
*
* Modification History:
*
* Date Name Description
* 10/14/2003 srl ported from java IslamicCalendar
*****************************************************************************
*/
#include "islamcal.h"
#if !UCONFIG_NO_FORMATTING
#include "mutex.h"
#include "umutex.h"
#include <float.h>
#include "gregoimp.h" // Math
#include "astro.h" // CalendarAstronomer
@ -31,15 +32,15 @@ static const UDate HIJRA_MILLIS = -42521587200000.0; // 7/16/622 AD 00:00
# include <stdarg.h>
static void debug_islamcal_loc(const char *f, int32_t l)
{
fprintf(stderr, "%s:%d: ", f, l);
fprintf(stderr, "%s:%d: ", f, l);
}
static void debug_islamcal_msg(const char *pat, ...)
{
va_list ap;
va_start(ap, pat);
vfprintf(stderr, pat, ap);
fflush(stderr);
va_list ap;
va_start(ap, pat);
vfprintf(stderr, pat, ap);
fflush(stderr);
}
// must use double parens, i.e.: U_DEBUG_ISLAMCAL_MSG(("four is: %d",4));
#define U_DEBUG_ISLAMCAL_MSG(x) {debug_islamcal_loc(__FILE__,__LINE__);debug_islamcal_msg x;}
@ -78,22 +79,22 @@ U_NAMESPACE_BEGIN
//-------------------------------------------------------------------------
const char *IslamicCalendar::getType() const {
if(civil==CIVIL) {
return "islamic-civil";
} else {
return "islamic";
}
if(civil==CIVIL) {
return "islamic-civil";
} else {
return "islamic";
}
}
Calendar* IslamicCalendar::clone() const {
return new IslamicCalendar(*this);
return new IslamicCalendar(*this);
}
IslamicCalendar::IslamicCalendar(const Locale& aLocale, UErrorCode& success, ECivil beCivil)
: Calendar(TimeZone::createDefault(), aLocale, success),
civil(beCivil)
: Calendar(TimeZone::createDefault(), aLocale, success),
civil(beCivil)
{
setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
}
IslamicCalendar::IslamicCalendar(const IslamicCalendar& other) : Calendar(other), civil(other.civil) {
@ -104,71 +105,71 @@ IslamicCalendar::~IslamicCalendar()
}
/**
* Determines whether this object uses the fixed-cycle Islamic civil calendar
* or an approximation of the religious, astronomical calendar.
*
* @param beCivil <code>true</code> to use the civil calendar,
* <code>false</code> to use the astronomical calendar.
* @draft ICU 2.4
*/
* Determines whether this object uses the fixed-cycle Islamic civil calendar
* or an approximation of the religious, astronomical calendar.
*
* @param beCivil <code>true</code> to use the civil calendar,
* <code>false</code> to use the astronomical calendar.
* @draft ICU 2.4
*/
void IslamicCalendar::setCivil(ECivil beCivil, UErrorCode &status)
{
if (civil != beCivil) {
// The fields of the calendar will become invalid, because the calendar
// rules are different
UDate m = getTimeInMillis(status);
civil = beCivil;
clear();
setTimeInMillis(m, status);
}
if (civil != beCivil) {
// The fields of the calendar will become invalid, because the calendar
// rules are different
UDate m = getTimeInMillis(status);
civil = beCivil;
clear();
setTimeInMillis(m, status);
}
}
/**
* Returns <code>true</code> if this object is using the fixed-cycle civil
* calendar, or <code>false</code> if using the religious, astronomical
* calendar.
* @draft ICU 2.4
*/
* Returns <code>true</code> if this object is using the fixed-cycle civil
* calendar, or <code>false</code> if using the religious, astronomical
* calendar.
* @draft ICU 2.4
*/
UBool IslamicCalendar::isCivil() {
return (civil == CIVIL);
return (civil == CIVIL);
}
//-------------------------------------------------------------------------
// Minimum / Maximum access functions
//-------------------------------------------------------------------------
static const int32_t LIMITS[UCAL_FIELD_COUNT][4] = {
// Minimum Greatest Least Maximum
// Minimum Maximum
{ 0, 0, 0, 0 }, // ERA
{ 1, 1, 5000000, 5000000 }, // YEAR
{ 0, 0, 11, 11 }, // MONTH
{ 1, 1, 51, 52 }, // WEEK_OF_YEAR
{ 0, 0, 5, 6 }, // WEEK_OF_MONTH
{ 1, 1, 29, 30 }, // DAY_OF_MONTH
{ 1, 1, 354, 355 }, // DAY_OF_YEAR
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK
{ -1, -1, 4, 5 }, // DAY_OF_WEEK_IN_MONTH
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET
{ 1, 1, 5000001, 5000001 }, // YEAR_WOY
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL
{ 1, 1, 5000000, 5000000 }, // EXTENDED_YEAR
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1} // MILLISECONDS_IN_DAY
// Minimum Greatest Least Maximum
// Minimum Maximum
{ 0, 0, 0, 0 }, // ERA
{ 1, 1, 5000000, 5000000 }, // YEAR
{ 0, 0, 11, 11 }, // MONTH
{ 1, 1, 51, 52 }, // WEEK_OF_YEAR
{ 0, 0, 5, 6 }, // WEEK_OF_MONTH
{ 1, 1, 29, 30 }, // DAY_OF_MONTH
{ 1, 1, 354, 355 }, // DAY_OF_YEAR
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK
{ -1, -1, 4, 5 }, // DAY_OF_WEEK_IN_MONTH
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET
{ 1, 1, 5000001, 5000001 }, // YEAR_WOY
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL
{ 1, 1, 5000000, 5000000 }, // EXTENDED_YEAR
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1} // MILLISECONDS_IN_DAY
};
/**
* @draft ICU 2.4
*/
* @draft ICU 2.4
*/
int32_t IslamicCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const {
return LIMITS[field][limitType];
return LIMITS[field][limitType];
}
//-------------------------------------------------------------------------
@ -176,113 +177,113 @@ int32_t IslamicCalendar::handleGetLimit(UCalendarDateFields field, ELimitType li
//
/**
* Determine whether a year is a leap year in the Islamic civil calendar
*/
* Determine whether a year is a leap year in the Islamic civil calendar
*/
UBool IslamicCalendar::civilLeapYear(int32_t year)
{
return (14 + 11 * year) % 30 < 11;
return (14 + 11 * year) % 30 < 11;
}
/**
* Return the day # on which the given year starts. Days are counted
* from the Hijri epoch, origin 0.
*/
* Return the day # on which the given year starts. Days are counted
* from the Hijri epoch, origin 0.
*/
int32_t IslamicCalendar::yearStart(int32_t year) {
if (civil == CIVIL) {
return (year-1)*354 + Math::floorDivide((3+11*year),30);
} else {
return trueMonthStart(12*(year-1));
}
if (civil == CIVIL) {
return (year-1)*354 + Math::floorDivide((3+11*year),30);
} else {
return trueMonthStart(12*(year-1));
}
}
/**
* Return the day # on which the given month starts. Days are counted
* from the Hijri epoch, origin 0.
*
* @param year The hijri year
* @param year The hijri month, 0-based
*/
* Return the day # on which the given month starts. Days are counted
* from the Hijri epoch, origin 0.
*
* @param year The hijri year
* @param year The hijri month, 0-based
*/
int32_t IslamicCalendar::monthStart(int32_t year, int32_t month) const {
if (civil == CIVIL) {
return (int32_t)uprv_ceil(29.5*month)
+ (year-1)*354 + (int32_t)Math::floorDivide((3+11*year),30);
} else {
return trueMonthStart(12*(year-1) + month);
}
if (civil == CIVIL) {
return (int32_t)uprv_ceil(29.5*month)
+ (year-1)*354 + (int32_t)Math::floorDivide((3+11*year),30);
} else {
return trueMonthStart(12*(year-1) + month);
}
}
/**
* Find the day number on which a particular month of the true/lunar
* Islamic calendar starts.
*
* @param month The month in question, origin 0 from the Hijri epoch
*
* @return The day number on which the given month starts.
*/
* Find the day number on which a particular month of the true/lunar
* Islamic calendar starts.
*
* @param month The month in question, origin 0 from the Hijri epoch
*
* @return The day number on which the given month starts.
*/
int32_t IslamicCalendar::trueMonthStart(int32_t month) const
{
UErrorCode status = U_ZERO_ERROR;
int32_t start = CalendarCache::get(&gMonthCache, month, status);
if (start==0) {
// Make a guess at when the month started, using the average length
UDate origin = HIJRA_MILLIS
+ uprv_floor(month * CalendarAstronomer::SYNODIC_MONTH - 1) * kOneDay;
double age = moonAge(origin);
if (moonAge(origin) >= 0) {
// The month has already started
do {
origin -= kOneDay;
age = moonAge(origin);
} while (age >= 0);
UErrorCode status = U_ZERO_ERROR;
int32_t start = CalendarCache::get(&gMonthCache, month, status);
if (start==0) {
// Make a guess at when the month started, using the average length
UDate origin = HIJRA_MILLIS
+ uprv_floor(month * CalendarAstronomer::SYNODIC_MONTH - 1) * kOneDay;
double age = moonAge(origin);
if (moonAge(origin) >= 0) {
// The month has already started
do {
origin -= kOneDay;
age = moonAge(origin);
} while (age >= 0);
}
else {
// Preceding month has not ended yet.
do {
origin += kOneDay;
age = moonAge(origin);
} while (age < 0);
}
start = (int32_t)Math::floorDivide((origin - HIJRA_MILLIS), (double)kOneDay) + 1;
CalendarCache::put(&gMonthCache, month, start, status);
}
else {
// Preceding month has not ended yet.
do {
origin += kOneDay;
age = moonAge(origin);
} while (age < 0);
if(U_FAILURE(status)) {
start = 0;
}
start = (int32_t)Math::floorDivide((origin - HIJRA_MILLIS), (double)kOneDay) + 1;
CalendarCache::put(&gMonthCache, month, start, status);
}
if(U_FAILURE(status)) {
start = 0;
}
return start;
return start;
}
/**
* Return the "age" of the moon at the given time; this is the difference
* in ecliptic latitude between the moon and the sun. This method simply
* calls CalendarAstronomer.moonAge, converts to degrees,
* and adjusts the result to be in the range [-180, 180].
*
* @param time The time at which the moon's age is desired,
* in millis since 1/1/1970.
*/
* Return the "age" of the moon at the given time; this is the difference
* in ecliptic latitude between the moon and the sun. This method simply
* calls CalendarAstronomer.moonAge, converts to degrees,
* and adjusts the result to be in the range [-180, 180].
*
* @param time The time at which the moon's age is desired,
* in millis since 1/1/1970.
*/
double IslamicCalendar::moonAge(UDate time)
{
double age = 0;
double age = 0;
umtx_lock(&astroLock);
if(gIslamicCalendarAstro == NULL) {
gIslamicCalendarAstro = new CalendarAstronomer();
}
gIslamicCalendarAstro->setTime(time);
age = gIslamicCalendarAstro->getMoonAge();
ucln_i18n_registerCleanup(UCLN_I18N_ISLAMIC_CALENDAR, calendar_islamic_cleanup);
umtx_unlock(&astroLock);
umtx_lock(&astroLock);
if(gIslamicCalendarAstro == NULL) {
gIslamicCalendarAstro = new CalendarAstronomer();
}
gIslamicCalendarAstro->setTime(time);
age = gIslamicCalendarAstro->getMoonAge();
ucln_i18n_registerCleanup(UCLN_I18N_ISLAMIC_CALENDAR, calendar_islamic_cleanup);
umtx_unlock(&astroLock);
// Convert to degrees and normalize...
age = age * 180 / CalendarAstronomer::PI;
if (age > 180) {
age = age - 360;
}
// Convert to degrees and normalize...
age = age * 180 / CalendarAstronomer::PI;
if (age > 180) {
age = age - 360;
}
return age;
return age;
}
//----------------------------------------------------------------------
@ -290,60 +291,60 @@ double IslamicCalendar::moonAge(UDate time)
//----------------------------------------------------------------------
/**
* Return the length (in days) of the given month.
*
* @param year The hijri year
* @param year The hijri month, 0-based
* @draft ICU 2.4
*/
* Return the length (in days) of the given month.
*
* @param year The hijri year
* @param year The hijri month, 0-based
* @draft ICU 2.4
*/
int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {
int32_t length = 0;
if (civil == CIVIL) {
length = 29 + (month+1) % 2;
if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
length++;
int32_t length = 0;
if (civil == CIVIL) {
length = 29 + (month+1) % 2;
if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
length++;
}
} else {
month = 12*(extendedYear-1) + month;
length = trueMonthStart(month+1) - trueMonthStart(month) ;
}
} else {
month = 12*(extendedYear-1) + month;
length = trueMonthStart(month+1) - trueMonthStart(month) ;
}
return length;
return length;
}
/**
* Return the number of days in the given Islamic year
* @draft ICU 2.4
*/
* Return the number of days in the given Islamic year
* @draft ICU 2.4
*/
int32_t IslamicCalendar::handleGetYearLength(int32_t extendedYear) const {
if (civil == CIVIL) {
return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
} else {
int32_t month = 12*(extendedYear-1);
return (trueMonthStart(month + 12) - trueMonthStart(month));
}
if (civil == CIVIL) {
return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
} else {
int32_t month = 12*(extendedYear-1);
return (trueMonthStart(month + 12) - trueMonthStart(month));
}
}
//-------------------------------------------------------------------------
// Functions for converting from field values to milliseconds....
//-------------------------------------------------------------------------
// Return JD of start of given month/year
/**
* @draft ICU 2.4
*/
* @draft ICU 2.4
*/
int32_t IslamicCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /* useMonth */) const {
return monthStart(eyear, month) + 1948439;
return monthStart(eyear, month) + 1948439;
}
//-------------------------------------------------------------------------
// Functions for converting from milliseconds to field values
//-------------------------------------------------------------------------
/**
* @draft ICU 2.4
*/
/**
* @draft ICU 2.4
*/
int32_t IslamicCalendar::handleGetExtendedYear() {
int32_t year;
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
@ -355,26 +356,26 @@ int32_t IslamicCalendar::handleGetExtendedYear() {
}
/**
* Override Calendar to compute several fields specific to the Islamic
* calendar system. These are:
*
* <ul><li>ERA
* <li>YEAR
* <li>MONTH
* <li>DAY_OF_MONTH
* <li>DAY_OF_YEAR
* <li>EXTENDED_YEAR</ul>
*
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
* method is called. The getGregorianXxx() methods return Gregorian
* calendar equivalents for the given Julian day.
* @draft ICU 2.4
*/
* Override Calendar to compute several fields specific to the Islamic
* calendar system. These are:
*
* <ul><li>ERA
* <li>YEAR
* <li>MONTH
* <li>DAY_OF_MONTH
* <li>DAY_OF_YEAR
* <li>EXTENDED_YEAR</ul>
*
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
* method is called. The getGregorianXxx() methods return Gregorian
* calendar equivalents for the given Julian day.
* @draft ICU 2.4
*/
void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) {
int32_t year, month, dayOfMonth, dayOfYear;
UDate startDate;
int32_t days = julianDay - 1948440;
if (civil == CIVIL) {
// Use the civil calendar approximation, which is just arithmetic
year = (int)Math::floorDivide( (double)(30 * days + 10646) , 10631.0 );
@ -398,11 +399,11 @@ void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*statu
// If it was after the date in question, back up a month and try again
months--;
}
year = months / 12 + 1;
month = months % 12;
}
dayOfMonth = (days - monthStart(year, month)) + 1;
// Now figure out the day of the year.
@ -419,14 +420,14 @@ void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*statu
UBool
IslamicCalendar::inDaylightTime(UErrorCode& status) const
{
// copied from GregorianCalendar
if (U_FAILURE(status) || !getTimeZone().useDaylightTime())
return FALSE;
// copied from GregorianCalendar
if (U_FAILURE(status) || !getTimeZone().useDaylightTime())
return FALSE;
// Force an update of the state of the Calendar.
((IslamicCalendar*)this)->complete(status); // cast away const
((IslamicCalendar*)this)->complete(status); // cast away const
return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
}
// default century
@ -439,85 +440,80 @@ int32_t IslamicCalendar::fgSystemDefaultCenturyStartYear = -1;
UBool IslamicCalendar::haveDefaultCentury() const
{
return TRUE;
return TRUE;
}
UDate IslamicCalendar::defaultCenturyStart() const
{
return internalGetDefaultCenturyStart();
return internalGetDefaultCenturyStart();
}
int32_t IslamicCalendar::defaultCenturyStartYear() const
{
return internalGetDefaultCenturyStartYear();
return internalGetDefaultCenturyStartYear();
}
UDate
IslamicCalendar::internalGetDefaultCenturyStart() const
{
// lazy-evaluate systemDefaultCenturyStart
UBool needsUpdate;
{
Mutex m;
needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
}
// lazy-evaluate systemDefaultCenturyStart
UBool needsUpdate;
UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
if (needsUpdate) {
initializeSystemDefaultCentury();
}
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStart
return fgSystemDefaultCenturyStart;
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStart
return fgSystemDefaultCenturyStart;
}
int32_t
IslamicCalendar::internalGetDefaultCenturyStartYear() const
{
// lazy-evaluate systemDefaultCenturyStartYear
UBool needsUpdate;
{
Mutex m;
needsUpdate = (fgSystemDefaultCenturyStart == fgSystemDefaultCentury);
}
// lazy-evaluate systemDefaultCenturyStartYear
UBool needsUpdate;
UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
if (needsUpdate) {
initializeSystemDefaultCentury();
}
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStartYear
return fgSystemDefaultCenturyStartYear;
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStartYear
return fgSystemDefaultCenturyStartYear;
}
void
IslamicCalendar::initializeSystemDefaultCentury()
{
// initialize systemDefaultCentury and systemDefaultCenturyYear based
// on the current time. They'll be set to 80 years before
// the current time.
// No point in locking as it should be idempotent.
if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
{
UErrorCode status = U_ZERO_ERROR;
IslamicCalendar calendar(Locale("@calendar=islamic-civil"),status);
if (U_SUCCESS(status))
// initialize systemDefaultCentury and systemDefaultCenturyYear based
// on the current time. They'll be set to 80 years before
// the current time.
// No point in locking as it should be idempotent.
if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
{
calendar.setTime(Calendar::getNow(), status);
calendar.add(UCAL_YEAR, -80, status);
UDate newStart = calendar.getTime(status);
int32_t newYear = calendar.get(UCAL_YEAR, status);
{
Mutex m;
fgSystemDefaultCenturyStart = newStart;
fgSystemDefaultCenturyStartYear = newYear;
}
UErrorCode status = U_ZERO_ERROR;
IslamicCalendar calendar(Locale("@calendar=islamic-civil"),status);
if (U_SUCCESS(status))
{
calendar.setTime(Calendar::getNow(), status);
calendar.add(UCAL_YEAR, -80, status);
UDate newStart = calendar.getTime(status);
int32_t newYear = calendar.get(UCAL_YEAR, status);
{
umtx_lock(NULL);
fgSystemDefaultCenturyStart = newStart;
fgSystemDefaultCenturyStartYear = newYear;
umtx_unlock(NULL);
}
}
// We have no recourse upon failure unless we want to propagate the failure
// out.
}
// We have no recourse upon failure unless we want to propagate the failure
// out.
}
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicCalendar)

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2003-2005, International Business Machines Corporation and *
* Copyright (C) 2003-2006, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@ -17,7 +17,7 @@
#include "japancal.h"
#include "unicode/gregocal.h"
#include "mutex.h"
#include "umutex.h"
#include "uassert.h"
//#define U_DEBUG_JCAL
@ -33,255 +33,255 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(JapaneseCalendar)
// Gregorian date of each emperor's ascension
// Years are AD, months are 1-based.
static const struct {
int16_t year;
int8_t month;
int8_t day;
int16_t year;
int8_t month;
int8_t day;
} kEraInfo[] = {
// Year Month Day
{ 645, 6, 19 }, // Taika 0
{ 650, 2, 15 }, // Hakuchi 1
{ 672, 1, 1 }, // Hakuho 2
{ 686, 7, 20 }, // Shucho 3
{ 701, 3, 21 }, // Taiho 4
{ 704, 5, 10 }, // Keiun 5
{ 708, 1, 11 }, // Wado 6
{ 715, 9, 2 }, // Reiki 7
{ 717, 11, 17 }, // Yoro 8
{ 724, 2, 4 }, // Jinki 9
{ 729, 8, 5 }, // Tempyo 10
{ 749, 4, 14 }, // Tempyo-kampo 11
{ 749, 7, 2 }, // Tempyo-shoho 12
{ 757, 8, 18 }, // Tempyo-hoji 13
{ 765, 1, 7 }, // Tempho-jingo 14
{ 767, 8, 16 }, // Jingo-keiun 15
{ 770, 10, 1 }, // Hoki 16
{ 781, 1, 1 }, // Ten-o 17
{ 782, 8, 19 }, // Enryaku 18
{ 806, 5, 18 }, // Daido 19
{ 810, 9, 19 }, // Konin 20
{ 824, 1, 5 }, // Tencho
{ 834, 1, 3 }, // Showa
{ 848, 6, 13 }, // Kajo
{ 851, 4, 28 }, // Ninju
{ 854, 11, 30 }, // Saiko
{ 857, 2, 21 }, // Tennan
{ 859, 4, 15 }, // Jogan
{ 877, 4, 16 }, // Genkei
{ 885, 2, 21 }, // Ninna
{ 889, 4, 27 }, // Kampyo 30
{ 898, 4, 26 }, // Shotai
{ 901, 7, 15 }, // Engi
{ 923, 4, 11 }, // Encho
{ 931, 4, 26 }, // Shohei
{ 938, 5, 22 }, // Tengyo
{ 947, 4, 22 }, // Tenryaku
{ 957, 10, 27 }, // Tentoku
{ 961, 2, 16 }, // Owa
{ 964, 7, 10 }, // Koho
{ 968, 8, 13 }, // Anna 40
{ 970, 3, 25 }, // Tenroku
{ 973, 12, 20 }, // Ten-en
{ 976, 7, 13 }, // Jogen
{ 978, 11, 29 }, // Tengen
{ 983, 4, 15 }, // Eikan
{ 985, 4, 27 }, // Kanna
{ 987, 4, 5 }, // Ei-en
{ 989, 8, 8 }, // Eiso
{ 990, 11, 7 }, // Shoryaku
{ 995, 2, 22 }, // Chotoku 50
{ 999, 1, 13 }, // Choho
{ 1004, 7, 20 }, // Kanko
{ 1012, 12, 25 }, // Chowa
{ 1017, 4, 23 }, // Kannin
{ 1021, 2, 2 }, // Jian
{ 1024, 7, 13 }, // Manju
{ 1028, 7, 25 }, // Chogen
{ 1037, 4, 21 }, // Choryaku
{ 1040, 11, 10 }, // Chokyu
{ 1044, 11, 24 }, // Kantoku 60
{ 1046, 4, 14 }, // Eisho
{ 1053, 1, 11 }, // Tengi
{ 1058, 8, 29 }, // Kohei
{ 1065, 8, 2 }, // Jiryaku
{ 1069, 4, 13 }, // Enkyu
{ 1074, 8, 23 }, // Shoho
{ 1077, 11, 17 }, // Shoryaku
{ 1081, 2, 10 }, // Eiho
{ 1084, 2, 7 }, // Otoku
{ 1087, 4, 7 }, // Kanji 70
{ 1094, 12, 15 }, // Kaho
{ 1096, 12, 17 }, // Eicho
{ 1097, 11, 21 }, // Shotoku
{ 1099, 8, 28 }, // Kowa
{ 1104, 2, 10 }, // Choji
{ 1106, 4, 9 }, // Kasho
{ 1108, 8, 3 }, // Tennin
{ 1110, 7, 13 }, // Ten-ei
{ 1113, 7, 13 }, // Eikyu
{ 1118, 4, 3 }, // Gen-ei 80
{ 1120, 4, 10 }, // Hoan
{ 1124, 4, 3 }, // Tenji
{ 1126, 1, 22 }, // Daiji
{ 1131, 1, 29 }, // Tensho
{ 1132, 8, 11 }, // Chosho
{ 1135, 4, 27 }, // Hoen
{ 1141, 7, 10 }, // Eiji
{ 1142, 4, 28 }, // Koji
{ 1144, 2, 23 }, // Tenyo
{ 1145, 7, 22 }, // Kyuan 90
{ 1151, 1, 26 }, // Ninpei
{ 1154, 10, 28 }, // Kyuju
{ 1156, 4, 27 }, // Hogen
{ 1159, 4, 20 }, // Heiji
{ 1160, 1, 10 }, // Eiryaku
{ 1161, 9, 4 }, // Oho
{ 1163, 3, 29 }, // Chokan
{ 1165, 6, 5 }, // Eiman
{ 1166, 8, 27 }, // Nin-an
{ 1169, 4, 8 }, // Kao 100
{ 1171, 4, 21 }, // Shoan
{ 1175, 7, 28 }, // Angen
{ 1177, 8, 4 }, // Jisho
{ 1181, 7, 14 }, // Yowa
{ 1182, 5, 27 }, // Juei
{ 1184, 4, 16 }, // Genryuku
{ 1185, 8, 14 }, // Bunji
{ 1190, 4, 11 }, // Kenkyu
{ 1199, 4, 27 }, // Shoji
{ 1201, 2, 13 }, // Kennin 110
{ 1204, 2, 20 }, // Genkyu
{ 1206, 4, 27 }, // Ken-ei
{ 1207, 10, 25 }, // Shogen
{ 1211, 3, 9 }, // Kenryaku
{ 1213, 12, 6 }, // Kenpo
{ 1219, 4, 12 }, // Shokyu
{ 1222, 4, 13 }, // Joo
{ 1224, 11, 20 }, // Gennin
{ 1225, 4, 20 }, // Karoku
{ 1227, 12, 10 }, // Antei 120
{ 1229, 3, 5 }, // Kanki
{ 1232, 4, 2 }, // Joei
{ 1233, 4, 15 }, // Tempuku
{ 1234, 11, 5 }, // Bunryaku
{ 1235, 9, 19 }, // Katei
{ 1238, 11, 23 }, // Ryakunin
{ 1239, 2, 7 }, // En-o
{ 1240, 7, 16 }, // Ninji
{ 1243, 2, 26 }, // Kangen
{ 1247, 2, 28 }, // Hoji 130
{ 1249, 3, 18 }, // Kencho
{ 1256, 10, 5 }, // Kogen
{ 1257, 3, 14 }, // Shoka
{ 1259, 3, 26 }, // Shogen
{ 1260, 4, 13 }, // Bun-o
{ 1261, 2, 20 }, // Kocho
{ 1264, 2, 28 }, // Bun-ei
{ 1275, 4, 25 }, // Kenji
{ 1278, 2, 29 }, // Koan
{ 1288, 4, 28 }, // Shoo 140
{ 1293, 8, 55 }, // Einin
{ 1299, 4, 25 }, // Shoan
{ 1302, 11, 21 }, // Kengen
{ 1303, 8, 5 }, // Kagen
{ 1306, 12, 14 }, // Tokuji
{ 1308, 10, 9 }, // Enkei
{ 1311, 4, 28 }, // Ocho
{ 1312, 3, 20 }, // Showa
{ 1317, 2, 3 }, // Bunpo
{ 1319, 4, 28 }, // Geno 150
{ 1321, 2, 23 }, // Genkyo
{ 1324, 12, 9 }, // Shochu
{ 1326, 4, 26 }, // Kareki
{ 1329, 8, 29 }, // Gentoku
{ 1331, 8, 9 }, // Genko
{ 1334, 1, 29 }, // Kemmu
{ 1336, 2, 29 }, // Engen
{ 1340, 4, 28 }, // Kokoku
{ 1346, 12, 8 }, // Shohei
{ 1370, 7, 24 }, // Kentoku 160
{ 1372, 4, 1 }, // Bunch\u0169
{ 1375, 5, 27 }, // Tenju
{ 1379, 3, 22 }, // Koryaku
{ 1381, 2, 10 }, // Kowa
{ 1384, 4, 28 }, // Gench\u0169
{ 1384, 2, 27 }, // Meitoku
{ 1387, 8, 23 }, // Kakei
{ 1389, 2, 9 }, // Koo
{ 1390, 3, 26 }, // Meitoku
{ 1394, 7, 5 }, // Oei 170
{ 1428, 4, 27 }, // Shocho
{ 1429, 9, 5 }, // Eikyo
{ 1441, 2, 17 }, // Kakitsu
{ 1444, 2, 5 }, // Bun-an
{ 1449, 7, 28 }, // Hotoku
{ 1452, 7, 25 }, // Kyotoku
{ 1455, 7, 25 }, // Kosho
{ 1457, 9, 28 }, // Choroku
{ 1460, 12, 21 }, // Kansho
{ 1466, 2, 28 }, // Bunsho 180
{ 1467, 3, 3 }, // Onin
{ 1469, 4, 28 }, // Bunmei
{ 1487, 7, 29 }, // Chokyo
{ 1489, 8, 21 }, // Entoku
{ 1492, 7, 19 }, // Meio
{ 1501, 2, 29 }, // Bunki
{ 1504, 2, 30 }, // Eisho
{ 1521, 8, 23 }, // Taiei
{ 1528, 8, 20 }, // Kyoroku
{ 1532, 7, 29 }, // Tenmon 190
{ 1555, 10, 23 }, // Koji
{ 1558, 2, 28 }, // Eiroku
{ 1570, 4, 23 }, // Genki
{ 1573, 7, 28 }, // Tensho
{ 1592, 12, 8 }, // Bunroku
{ 1596, 10, 27 }, // Keicho
{ 1615, 7, 13 }, // Genwa
{ 1624, 2, 30 }, // Kan-ei
{ 1644, 12, 16 }, // Shoho
{ 1648, 2, 15 }, // Keian 200
{ 1652, 9, 18 }, // Shoo
{ 1655, 4, 13 }, // Meiryaku
{ 1658, 7, 23 }, // Manji
{ 1661, 4, 25 }, // Kanbun
{ 1673, 9, 21 }, // Enpo
{ 1681, 9, 29 }, // Tenwa
{ 1684, 2, 21 }, // Jokyo
{ 1688, 9, 30 }, // Genroku
{ 1704, 3, 13 }, // Hoei
{ 1711, 4, 25 }, // Shotoku 210
{ 1716, 6, 22 }, // Kyoho
{ 1736, 4, 28 }, // Genbun
{ 1741, 2, 27 }, // Kanpo
{ 1744, 2, 21 }, // Enkyo
{ 1748, 7, 12 }, // Kan-en
{ 1751, 10, 27 }, // Horyaku
{ 1764, 6, 2 }, // Meiwa
{ 1772, 11, 16 }, // An-ei
{ 1781, 4, 2 }, // Tenmei
{ 1789, 1, 25 }, // Kansei 220
{ 1801, 2, 5 }, // Kyowa
{ 1804, 2, 11 }, // Bunka
{ 1818, 4, 22 }, // Bunsei
{ 1830, 12, 10 }, // Tenpo
{ 1844, 12, 2 }, // Koka
{ 1848, 2, 28 }, // Kaei
{ 1854, 11, 27 }, // Ansei
{ 1860, 3, 18 }, // Man-en
{ 1861, 2, 19 }, // Bunkyu
{ 1864, 2, 20 }, // Genji 230
{ 1865, 4, 7 }, // Keio 231
{ 1868, 9, 8 }, // Meiji 232
{ 1912, 7, 30 }, // Taisho 233
{ 1926, 12, 25 }, // Showa 234
{ 1989, 1, 8 } // Heisei 235
};
// Year Month Day
{ 645, 6, 19 }, // Taika 0
{ 650, 2, 15 }, // Hakuchi 1
{ 672, 1, 1 }, // Hakuho 2
{ 686, 7, 20 }, // Shucho 3
{ 701, 3, 21 }, // Taiho 4
{ 704, 5, 10 }, // Keiun 5
{ 708, 1, 11 }, // Wado 6
{ 715, 9, 2 }, // Reiki 7
{ 717, 11, 17 }, // Yoro 8
{ 724, 2, 4 }, // Jinki 9
{ 729, 8, 5 }, // Tempyo 10
{ 749, 4, 14 }, // Tempyo-kampo 11
{ 749, 7, 2 }, // Tempyo-shoho 12
{ 757, 8, 18 }, // Tempyo-hoji 13
{ 765, 1, 7 }, // Tempho-jingo 14
{ 767, 8, 16 }, // Jingo-keiun 15
{ 770, 10, 1 }, // Hoki 16
{ 781, 1, 1 }, // Ten-o 17
{ 782, 8, 19 }, // Enryaku 18
{ 806, 5, 18 }, // Daido 19
{ 810, 9, 19 }, // Konin 20
{ 824, 1, 5 }, // Tencho
{ 834, 1, 3 }, // Showa
{ 848, 6, 13 }, // Kajo
{ 851, 4, 28 }, // Ninju
{ 854, 11, 30 }, // Saiko
{ 857, 2, 21 }, // Tennan
{ 859, 4, 15 }, // Jogan
{ 877, 4, 16 }, // Genkei
{ 885, 2, 21 }, // Ninna
{ 889, 4, 27 }, // Kampyo 30
{ 898, 4, 26 }, // Shotai
{ 901, 7, 15 }, // Engi
{ 923, 4, 11 }, // Encho
{ 931, 4, 26 }, // Shohei
{ 938, 5, 22 }, // Tengyo
{ 947, 4, 22 }, // Tenryaku
{ 957, 10, 27 }, // Tentoku
{ 961, 2, 16 }, // Owa
{ 964, 7, 10 }, // Koho
{ 968, 8, 13 }, // Anna 40
{ 970, 3, 25 }, // Tenroku
{ 973, 12, 20 }, // Ten-en
{ 976, 7, 13 }, // Jogen
{ 978, 11, 29 }, // Tengen
{ 983, 4, 15 }, // Eikan
{ 985, 4, 27 }, // Kanna
{ 987, 4, 5 }, // Ei-en
{ 989, 8, 8 }, // Eiso
{ 990, 11, 7 }, // Shoryaku
{ 995, 2, 22 }, // Chotoku 50
{ 999, 1, 13 }, // Choho
{ 1004, 7, 20 }, // Kanko
{ 1012, 12, 25 }, // Chowa
{ 1017, 4, 23 }, // Kannin
{ 1021, 2, 2 }, // Jian
{ 1024, 7, 13 }, // Manju
{ 1028, 7, 25 }, // Chogen
{ 1037, 4, 21 }, // Choryaku
{ 1040, 11, 10 }, // Chokyu
{ 1044, 11, 24 }, // Kantoku 60
{ 1046, 4, 14 }, // Eisho
{ 1053, 1, 11 }, // Tengi
{ 1058, 8, 29 }, // Kohei
{ 1065, 8, 2 }, // Jiryaku
{ 1069, 4, 13 }, // Enkyu
{ 1074, 8, 23 }, // Shoho
{ 1077, 11, 17 }, // Shoryaku
{ 1081, 2, 10 }, // Eiho
{ 1084, 2, 7 }, // Otoku
{ 1087, 4, 7 }, // Kanji 70
{ 1094, 12, 15 }, // Kaho
{ 1096, 12, 17 }, // Eicho
{ 1097, 11, 21 }, // Shotoku
{ 1099, 8, 28 }, // Kowa
{ 1104, 2, 10 }, // Choji
{ 1106, 4, 9 }, // Kasho
{ 1108, 8, 3 }, // Tennin
{ 1110, 7, 13 }, // Ten-ei
{ 1113, 7, 13 }, // Eikyu
{ 1118, 4, 3 }, // Gen-ei 80
{ 1120, 4, 10 }, // Hoan
{ 1124, 4, 3 }, // Tenji
{ 1126, 1, 22 }, // Daiji
{ 1131, 1, 29 }, // Tensho
{ 1132, 8, 11 }, // Chosho
{ 1135, 4, 27 }, // Hoen
{ 1141, 7, 10 }, // Eiji
{ 1142, 4, 28 }, // Koji
{ 1144, 2, 23 }, // Tenyo
{ 1145, 7, 22 }, // Kyuan 90
{ 1151, 1, 26 }, // Ninpei
{ 1154, 10, 28 }, // Kyuju
{ 1156, 4, 27 }, // Hogen
{ 1159, 4, 20 }, // Heiji
{ 1160, 1, 10 }, // Eiryaku
{ 1161, 9, 4 }, // Oho
{ 1163, 3, 29 }, // Chokan
{ 1165, 6, 5 }, // Eiman
{ 1166, 8, 27 }, // Nin-an
{ 1169, 4, 8 }, // Kao 100
{ 1171, 4, 21 }, // Shoan
{ 1175, 7, 28 }, // Angen
{ 1177, 8, 4 }, // Jisho
{ 1181, 7, 14 }, // Yowa
{ 1182, 5, 27 }, // Juei
{ 1184, 4, 16 }, // Genryuku
{ 1185, 8, 14 }, // Bunji
{ 1190, 4, 11 }, // Kenkyu
{ 1199, 4, 27 }, // Shoji
{ 1201, 2, 13 }, // Kennin 110
{ 1204, 2, 20 }, // Genkyu
{ 1206, 4, 27 }, // Ken-ei
{ 1207, 10, 25 }, // Shogen
{ 1211, 3, 9 }, // Kenryaku
{ 1213, 12, 6 }, // Kenpo
{ 1219, 4, 12 }, // Shokyu
{ 1222, 4, 13 }, // Joo
{ 1224, 11, 20 }, // Gennin
{ 1225, 4, 20 }, // Karoku
{ 1227, 12, 10 }, // Antei 120
{ 1229, 3, 5 }, // Kanki
{ 1232, 4, 2 }, // Joei
{ 1233, 4, 15 }, // Tempuku
{ 1234, 11, 5 }, // Bunryaku
{ 1235, 9, 19 }, // Katei
{ 1238, 11, 23 }, // Ryakunin
{ 1239, 2, 7 }, // En-o
{ 1240, 7, 16 }, // Ninji
{ 1243, 2, 26 }, // Kangen
{ 1247, 2, 28 }, // Hoji 130
{ 1249, 3, 18 }, // Kencho
{ 1256, 10, 5 }, // Kogen
{ 1257, 3, 14 }, // Shoka
{ 1259, 3, 26 }, // Shogen
{ 1260, 4, 13 }, // Bun-o
{ 1261, 2, 20 }, // Kocho
{ 1264, 2, 28 }, // Bun-ei
{ 1275, 4, 25 }, // Kenji
{ 1278, 2, 29 }, // Koan
{ 1288, 4, 28 }, // Shoo 140
{ 1293, 8, 55 }, // Einin
{ 1299, 4, 25 }, // Shoan
{ 1302, 11, 21 }, // Kengen
{ 1303, 8, 5 }, // Kagen
{ 1306, 12, 14 }, // Tokuji
{ 1308, 10, 9 }, // Enkei
{ 1311, 4, 28 }, // Ocho
{ 1312, 3, 20 }, // Showa
{ 1317, 2, 3 }, // Bunpo
{ 1319, 4, 28 }, // Geno 150
{ 1321, 2, 23 }, // Genkyo
{ 1324, 12, 9 }, // Shochu
{ 1326, 4, 26 }, // Kareki
{ 1329, 8, 29 }, // Gentoku
{ 1331, 8, 9 }, // Genko
{ 1334, 1, 29 }, // Kemmu
{ 1336, 2, 29 }, // Engen
{ 1340, 4, 28 }, // Kokoku
{ 1346, 12, 8 }, // Shohei
{ 1370, 7, 24 }, // Kentoku 160
{ 1372, 4, 1 }, // Bunch\u0169
{ 1375, 5, 27 }, // Tenju
{ 1379, 3, 22 }, // Koryaku
{ 1381, 2, 10 }, // Kowa
{ 1384, 4, 28 }, // Gench\u0169
{ 1384, 2, 27 }, // Meitoku
{ 1387, 8, 23 }, // Kakei
{ 1389, 2, 9 }, // Koo
{ 1390, 3, 26 }, // Meitoku
{ 1394, 7, 5 }, // Oei 170
{ 1428, 4, 27 }, // Shocho
{ 1429, 9, 5 }, // Eikyo
{ 1441, 2, 17 }, // Kakitsu
{ 1444, 2, 5 }, // Bun-an
{ 1449, 7, 28 }, // Hotoku
{ 1452, 7, 25 }, // Kyotoku
{ 1455, 7, 25 }, // Kosho
{ 1457, 9, 28 }, // Choroku
{ 1460, 12, 21 }, // Kansho
{ 1466, 2, 28 }, // Bunsho 180
{ 1467, 3, 3 }, // Onin
{ 1469, 4, 28 }, // Bunmei
{ 1487, 7, 29 }, // Chokyo
{ 1489, 8, 21 }, // Entoku
{ 1492, 7, 19 }, // Meio
{ 1501, 2, 29 }, // Bunki
{ 1504, 2, 30 }, // Eisho
{ 1521, 8, 23 }, // Taiei
{ 1528, 8, 20 }, // Kyoroku
{ 1532, 7, 29 }, // Tenmon 190
{ 1555, 10, 23 }, // Koji
{ 1558, 2, 28 }, // Eiroku
{ 1570, 4, 23 }, // Genki
{ 1573, 7, 28 }, // Tensho
{ 1592, 12, 8 }, // Bunroku
{ 1596, 10, 27 }, // Keicho
{ 1615, 7, 13 }, // Genwa
{ 1624, 2, 30 }, // Kan-ei
{ 1644, 12, 16 }, // Shoho
{ 1648, 2, 15 }, // Keian 200
{ 1652, 9, 18 }, // Shoo
{ 1655, 4, 13 }, // Meiryaku
{ 1658, 7, 23 }, // Manji
{ 1661, 4, 25 }, // Kanbun
{ 1673, 9, 21 }, // Enpo
{ 1681, 9, 29 }, // Tenwa
{ 1684, 2, 21 }, // Jokyo
{ 1688, 9, 30 }, // Genroku
{ 1704, 3, 13 }, // Hoei
{ 1711, 4, 25 }, // Shotoku 210
{ 1716, 6, 22 }, // Kyoho
{ 1736, 4, 28 }, // Genbun
{ 1741, 2, 27 }, // Kanpo
{ 1744, 2, 21 }, // Enkyo
{ 1748, 7, 12 }, // Kan-en
{ 1751, 10, 27 }, // Horyaku
{ 1764, 6, 2 }, // Meiwa
{ 1772, 11, 16 }, // An-ei
{ 1781, 4, 2 }, // Tenmei
{ 1789, 1, 25 }, // Kansei 220
{ 1801, 2, 5 }, // Kyowa
{ 1804, 2, 11 }, // Bunka
{ 1818, 4, 22 }, // Bunsei
{ 1830, 12, 10 }, // Tenpo
{ 1844, 12, 2 }, // Koka
{ 1848, 2, 28 }, // Kaei
{ 1854, 11, 27 }, // Ansei
{ 1860, 3, 18 }, // Man-en
{ 1861, 2, 19 }, // Bunkyu
{ 1864, 2, 20 }, // Genji 230
{ 1865, 4, 7 }, // Keio 231
{ 1868, 9, 8 }, // Meiji 232
{ 1912, 7, 30 }, // Taisho 233
{ 1926, 12, 25 }, // Showa 234
{ 1989, 1, 8 } // Heisei 235
};
#define kEraCount (sizeof(kEraInfo)/sizeof(kEraInfo[0]))
const uint32_t JapaneseCalendar::kCurrentEra = (kEraCount-1);
JapaneseCalendar::JapaneseCalendar(const Locale& aLocale, UErrorCode& success)
: GregorianCalendar(aLocale, success)
: GregorianCalendar(aLocale, success)
{
setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
}
@ -291,247 +291,244 @@ JapaneseCalendar::~JapaneseCalendar()
}
JapaneseCalendar::JapaneseCalendar(const JapaneseCalendar& source)
: GregorianCalendar(source)
: GregorianCalendar(source)
{
}
JapaneseCalendar& JapaneseCalendar::operator= ( const JapaneseCalendar& right)
{
GregorianCalendar::operator=(right);
return *this;
GregorianCalendar::operator=(right);
return *this;
}
Calendar* JapaneseCalendar::clone(void) const
{
return new JapaneseCalendar(*this);
return new JapaneseCalendar(*this);
}
const char *JapaneseCalendar::getType() const
{
return "japanese";
return "japanese";
}
int32_t JapaneseCalendar::getDefaultMonthInYear()
{
UErrorCode status = U_ZERO_ERROR;
int32_t era = internalGetEra();
computeFields(status); // slow
int32_t year = getGregorianYear();
// TODO do we assume we can trust 'era'? What if it is denormalized?
UErrorCode status = U_ZERO_ERROR;
int32_t era = internalGetEra();
computeFields(status); // slow
int32_t year = getGregorianYear();
// TODO do we assume we can trust 'era'? What if it is denormalized?
int32_t month = GregorianCalendar::getDefaultMonthInYear();
int32_t month = GregorianCalendar::getDefaultMonthInYear();
// Find out if we are at the edge of an era
// Find out if we are at the edge of an era
if(year == kEraInfo[era].year) {
// Yes, we're in the first year of this era.
return kEraInfo[era].month-1;
}
if(year == kEraInfo[era].year) {
// Yes, we're in the first year of this era.
return kEraInfo[era].month-1;
}
return month;
return month;
}
int32_t JapaneseCalendar::getDefaultDayInMonth(int32_t month)
{
UErrorCode status = U_ZERO_ERROR;
int32_t era = internalGetEra();
computeFields(status); // slow
int32_t year = getGregorianYear();
int32_t day = GregorianCalendar::getDefaultDayInMonth(month);
if(year == kEraInfo[era].year) {
if(month == (kEraInfo[era].month-1)) {
return kEraInfo[era].day;
}
}
UErrorCode status = U_ZERO_ERROR;
int32_t era = internalGetEra();
computeFields(status); // slow
int32_t year = getGregorianYear();
int32_t day = GregorianCalendar::getDefaultDayInMonth(month);
return day;
if(year == kEraInfo[era].year) {
if(month == (kEraInfo[era].month-1)) {
return kEraInfo[era].day;
}
}
return day;
}
int32_t JapaneseCalendar::internalGetEra() const
{
return internalGet(UCAL_ERA, kCurrentEra);
return internalGet(UCAL_ERA, kCurrentEra);
}
int32_t JapaneseCalendar::handleGetExtendedYear()
{
int32_t year;
int32_t year;
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR &&
newerField(UCAL_EXTENDED_YEAR, UCAL_ERA) == UCAL_EXTENDED_YEAR) {
year = internalGet(UCAL_EXTENDED_YEAR, 1);
} else {
// Subtract one because year starts at 1
year = internalGet(UCAL_YEAR) + kEraInfo[internalGetEra()].year - 1;
}
return year;
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR &&
newerField(UCAL_EXTENDED_YEAR, UCAL_ERA) == UCAL_EXTENDED_YEAR) {
year = internalGet(UCAL_EXTENDED_YEAR, 1);
} else {
// Subtract one because year starts at 1
year = internalGet(UCAL_YEAR) + kEraInfo[internalGetEra()].year - 1;
}
return year;
}
void JapaneseCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
{
//Calendar::timeToFields(theTime, quick, status);
GregorianCalendar::handleComputeFields(julianDay, status);
int32_t year = internalGet(UCAL_EXTENDED_YEAR); // Gregorian year
//Calendar::timeToFields(theTime, quick, status);
GregorianCalendar::handleComputeFields(julianDay, status);
int32_t year = internalGet(UCAL_EXTENDED_YEAR); // Gregorian year
int32_t low = 0;
// Short circuit for recent years. Most modern computations will
// occur in the current era and won't require the binary search.
// Note that if the year is == the current era year, then we use
// the binary search to handle the month/dom comparison.
int32_t low = 0;
// Short circuit for recent years. Most modern computations will
// occur in the current era and won't require the binary search.
// Note that if the year is == the current era year, then we use
// the binary search to handle the month/dom comparison.
#ifdef U_DEBUG_JCAL
fprintf(stderr, "== %d \n", year);
fprintf(stderr, "== %d \n", year);
#endif
if (year > kEraInfo[kCurrentEra].year) {
low = kCurrentEra;
if (year > kEraInfo[kCurrentEra].year) {
low = kCurrentEra;
#ifdef U_DEBUG_JCAL
fprintf(stderr, " low=%d (special)\n", low);
fprintf(stderr, " low=%d (special)\n", low);
#endif
} else {
// Binary search
int32_t high = kEraCount;
#ifdef U_DEBUG_JCAL
fprintf(stderr, " high=%d\n", high);
#endif
while (low < high - 1) {
int32_t i = (low + high) / 2;
int32_t diff = year - kEraInfo[i].year;
} else {
// Binary search
int32_t high = kEraCount;
#ifdef U_DEBUG_JCAL
fprintf(stderr, " d=%d low=%d, high=%d. Considering %d:M%d D%d Y%d. { we are ?:M%d D%d Y%d }\n",
diff,low, high, i, kEraInfo[i].month-1, kEraInfo[i].day, kEraInfo[i].year, internalGet(UCAL_MONTH), internalGet(UCAL_DATE),year);
fprintf(stderr, " high=%d\n", high);
#endif
// If years are the same, then compare the months, and if those
// are the same, compare days of month. In the ERAS array
// months are 1-based for easier maintenance.
if (diff == 0) {
diff = internalGet(UCAL_MONTH) - (kEraInfo[i].month - 1);
while (low < high - 1) {
int32_t i = (low + high) / 2;
int32_t diff = year - kEraInfo[i].year;
#ifdef U_DEBUG_JCAL
fprintf(stderr, "diff now %d (M) = %d - %d - 1\n", diff, internalGet(UCAL_MONTH), kEraInfo[i].month);
fprintf(stderr, " d=%d low=%d, high=%d. Considering %d:M%d D%d Y%d. { we are ?:M%d D%d Y%d }\n",
diff,low, high, i, kEraInfo[i].month-1, kEraInfo[i].day, kEraInfo[i].year, internalGet(UCAL_MONTH), internalGet(UCAL_DATE),year);
#endif
if (diff == 0) {
diff = internalGet(UCAL_DATE) - kEraInfo[i].day;
// If years are the same, then compare the months, and if those
// are the same, compare days of month. In the ERAS array
// months are 1-based for easier maintenance.
if (diff == 0) {
diff = internalGet(UCAL_MONTH) - (kEraInfo[i].month - 1);
#ifdef U_DEBUG_JCAL
fprintf(stderr, "diff now %d (D)\n", diff);
fprintf(stderr, "diff now %d (M) = %d - %d - 1\n", diff, internalGet(UCAL_MONTH), kEraInfo[i].month);
#endif
if (diff == 0) {
diff = internalGet(UCAL_DATE) - kEraInfo[i].day;
#ifdef U_DEBUG_JCAL
fprintf(stderr, "diff now %d (D)\n", diff);
#endif
}
}
if (diff >= 0) {
low = i;
} else {
high = i;
}
#ifdef U_DEBUG_JCAL
fprintf(stderr, ". low=%d, high=%d, i=%d, diff=%d.. %d\n", low, high, i, diff, year);
#endif
}
}
if (diff >= 0) {
low = i;
} else {
high = i;
}
#ifdef U_DEBUG_JCAL
fprintf(stderr, ". low=%d, high=%d, i=%d, diff=%d.. %d\n", low, high, i, diff, year);
#endif
}
}
#ifdef U_DEBUG_JCAL
fprintf(stderr, " low[era]=%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
// all dates before the first era will fall into the first era by
// the algorithm.
internalSet(UCAL_ERA, low);
internalSet(UCAL_YEAR, year - kEraInfo[low].year + 1);
// 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
// all dates before the first era will fall into the first era by
// the algorithm.
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);
fprintf(stderr, " Set ERA=%d, year=%d\n", low, year-kEraInfo[low].year+1);
#endif
}
/*
Disable pivoting
Disable pivoting
*/
UBool JapaneseCalendar::haveDefaultCentury() const
{
return FALSE;
return FALSE;
}
UDate JapaneseCalendar::defaultCenturyStart() const
{
return 0;// WRONG
return 0;// WRONG
}
int32_t JapaneseCalendar::defaultCenturyStartYear() const
{
return 0;
return 0;
}
static int32_t gJapanCalendarLimits[2][4] = {
// Minimum Greatest min Least max Greatest max
{ 0, 0, JapaneseCalendar::kCurrentEra, JapaneseCalendar::kCurrentEra }, // ERA
{ 1, 1, 0, 0 }, // YEAR least-max/greatest-max computed at runtime
// Minimum Greatest min Least max Greatest max
{ 0, 0, JapaneseCalendar::kCurrentEra, JapaneseCalendar::kCurrentEra }, // ERA
{ 1, 1, 0, 0 }, // YEAR least-max/greatest-max computed at runtime
};
static UBool gJapanYearLimitsKnown = FALSE;
int32_t JapaneseCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const
{
switch(field) {
case UCAL_YEAR:
{
UBool needCalc = FALSE;
{
Mutex m;
needCalc = (gJapanYearLimitsKnown == FALSE);
}
if(needCalc) {
int32_t min = kEraInfo[1].year - kEraInfo[0].year;
int32_t max = min;
for (uint32_t i=2; i<kEraCount; i++) { // counting by year, not field (3's)
int32_t d = kEraInfo[i].year - kEraInfo[i-1].year;
U_ASSERT(d >= 0);
if (d < min) {
min = d;
}
if (d > max) {
max = d;
}
}
U_ASSERT(min >= 0 && max > min);
{
Mutex m;
if(gJapanYearLimitsKnown==FALSE) {
gJapanCalendarLimits[field][UCAL_LIMIT_LEAST_MAXIMUM] = ++min; // 1-based
gJapanCalendarLimits[field][UCAL_LIMIT_MAXIMUM] = ++max; // 1-based
gJapanYearLimitsKnown = TRUE;
}
}
}
return gJapanCalendarLimits[field][limitType];
}
switch(field) {
case UCAL_YEAR:
{
UBool needCalc;
UMTX_CHECK(NULL, (gJapanYearLimitsKnown == FALSE), needCalc);
if(needCalc) {
int32_t min = kEraInfo[1].year - kEraInfo[0].year;
int32_t max = min;
for (uint32_t i=2; i<kEraCount; i++) { // counting by year, not field (3's)
int32_t d = kEraInfo[i].year - kEraInfo[i-1].year;
U_ASSERT(d >= 0);
if (d < min) {
min = d;
}
if (d > max) {
max = d;
}
}
U_ASSERT(min >= 0 && max > min);
case UCAL_ERA:
return gJapanCalendarLimits[field][limitType];
umtx_lock(NULL);
if(gJapanYearLimitsKnown==FALSE) {
gJapanCalendarLimits[field][UCAL_LIMIT_LEAST_MAXIMUM] = ++min; // 1-based
gJapanCalendarLimits[field][UCAL_LIMIT_MAXIMUM] = ++max; // 1-based
gJapanYearLimitsKnown = TRUE;
}
umtx_unlock(NULL);
}
return gJapanCalendarLimits[field][limitType];
}
case UCAL_EXTENDED_YEAR: // extended year limits
switch(limitType) {
case UCAL_ERA:
return gJapanCalendarLimits[field][limitType];
case UCAL_EXTENDED_YEAR: // extended year limits
switch(limitType) {
case UCAL_LIMIT_GREATEST_MINIMUM:
case UCAL_LIMIT_MINIMUM:
return kEraInfo[0].year; /* minimum is 1st era year */
return kEraInfo[0].year; /* minimum is 1st era year */
case UCAL_LIMIT_LEAST_MAXIMUM:
case UCAL_LIMIT_MAXIMUM:
/* use Gregorian calendar max */
/* use Gregorian calendar max */
default:
return GregorianCalendar::handleGetLimit(field,limitType);
}
break;
return GregorianCalendar::handleGetLimit(field,limitType);
}
break;
default:
return GregorianCalendar::handleGetLimit(field,limitType);
}
default:
return GregorianCalendar::handleGetLimit(field,limitType);
}
}