ICU-2943 updates from the code review for calendar
X-SVN-Rev: 13758
This commit is contained in:
parent
562a37641a
commit
7864fab41d
@ -60,7 +60,7 @@ public:
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of BuddhistCalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @stable ICU 2.0
|
||||
* @internal
|
||||
*/
|
||||
BuddhistCalendar(const Locale& aLocale, UErrorCode& success);
|
||||
|
||||
@ -136,7 +136,7 @@ public:
|
||||
* @param status Output param set to success/failure code on exit. If any value
|
||||
* previously set in the time field is invalid, this will be set to
|
||||
* an error status.
|
||||
* @draft ICU 2.6.
|
||||
* @draft ICU 2.6
|
||||
*/
|
||||
virtual void add(UCalendarDateFields field, int32_t amount, UErrorCode& status);
|
||||
|
||||
@ -146,7 +146,7 @@ public:
|
||||
*
|
||||
* @param field The given time field.
|
||||
* @return The maximum value for the given time field.
|
||||
* @draft ICU 2.6.
|
||||
* @draft ICU 2.6
|
||||
*/
|
||||
int32_t getMaximum(UCalendarDateFields field) const;
|
||||
|
||||
@ -156,7 +156,7 @@ public:
|
||||
*
|
||||
* @param field The given time field.
|
||||
* @return The lowest maximum value for the given time field.
|
||||
* @draft ICU 2.6.
|
||||
* @draft ICU 2.6
|
||||
*/
|
||||
int32_t getLeastMaximum(UCalendarDateFields field) const;
|
||||
|
||||
|
@ -33,6 +33,9 @@
|
||||
#include "gregoimp.h"
|
||||
#include "buddhcal.h"
|
||||
#include "japancal.h"
|
||||
#if defined(SRL_HAVE_ISLAMIC)
|
||||
#include "islamcal.h"
|
||||
#endif
|
||||
#include "unicode/calendar.h"
|
||||
#include "cpputils.h"
|
||||
#include "iculserv.h"
|
||||
@ -157,6 +160,13 @@ protected:
|
||||
return new JapaneseCalendar(canLoc, status);
|
||||
} else if(!uprv_strcmp(fType, "buddhist")) {
|
||||
return new BuddhistCalendar(canLoc, status);
|
||||
#if defined (SRL_HAVE_ISLAMIC)
|
||||
} else if(!uprv_strcmp(fType, "islamic-civil")) {
|
||||
return new IslamicCalendar(canLoc, status);
|
||||
} else if(!uprv_strcmp(fType, "islamic")) {
|
||||
IslamicCalendar *i = new IslamicCalendar(canLoc, status);
|
||||
i->setCivil(FALSE, status);
|
||||
#endif
|
||||
} else {
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return NULL;
|
||||
@ -322,6 +332,10 @@ getService(void)
|
||||
newservice->registerFactory(new BasicCalendarFactory("japanese"),status);
|
||||
newservice->registerFactory(new BasicCalendarFactory("buddhist"),status);
|
||||
newservice->registerFactory(new BasicCalendarFactory("gregorian"),status);
|
||||
#if defined (SRL_HAVE_ISLAMIC)
|
||||
newservice->registerFactory(new BasicCalendarFactory("islamic"),status);
|
||||
newservice->registerFactory(new BasicCalendarFactory("islamic-civil"),status);
|
||||
#endif
|
||||
|
||||
#ifdef U_DEBUG_CALSVC
|
||||
fprintf(stderr, "Done..\n");
|
||||
@ -352,6 +366,15 @@ getService(void)
|
||||
return gService;
|
||||
}
|
||||
|
||||
URegistryKey Calendar::registerFactory(ICUServiceFactory* toAdopt, UErrorCode& status)
|
||||
{
|
||||
return getService()->registerFactory(toAdopt, status);
|
||||
}
|
||||
|
||||
UBool Calendar::unregister(URegistryKey key, UErrorCode& status) {
|
||||
return getService()->unregister(key, status);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
static const int32_t kCalendarLimits[UCAL_FIELD_COUNT][4] = {
|
||||
@ -441,7 +464,7 @@ Calendar::Calendar(UErrorCode& success)
|
||||
fIsTimeSet(FALSE),
|
||||
fAreFieldsSet(FALSE),
|
||||
fAreAllFieldsSet(FALSE),
|
||||
fNextStamp(kMinimumUserStamp),
|
||||
fNextStamp((int32_t)kMinimumUserStamp),
|
||||
fTime(0),
|
||||
fLenient(TRUE),
|
||||
fZone(0)
|
||||
@ -458,7 +481,7 @@ Calendar::Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success)
|
||||
fIsTimeSet(FALSE),
|
||||
fAreFieldsSet(FALSE),
|
||||
fAreAllFieldsSet(FALSE),
|
||||
fNextStamp(kMinimumUserStamp),
|
||||
fNextStamp((int32_t)kMinimumUserStamp),
|
||||
fTime(0),
|
||||
fLenient(TRUE),
|
||||
fZone(0)
|
||||
@ -485,7 +508,7 @@ Calendar::Calendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& succ
|
||||
fIsTimeSet(FALSE),
|
||||
fAreFieldsSet(FALSE),
|
||||
fAreAllFieldsSet(FALSE),
|
||||
fNextStamp(kMinimumUserStamp),
|
||||
fNextStamp((int32_t)kMinimumUserStamp),
|
||||
fTime(0),
|
||||
fLenient(TRUE),
|
||||
fZone(0)
|
||||
@ -613,13 +636,16 @@ Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
|
||||
if(c->getDynamicClassID() == UnicodeString::getStaticClassID()) {
|
||||
// recursed! Second lookup returned a UnicodeString.
|
||||
// Perhaps DefaultCalendar{} was set to another locale.
|
||||
#ifdef U_DEBUG_CALSVC
|
||||
fprintf(stderr, "err - recursed, 2nd lookup was unistring\n");
|
||||
#endif
|
||||
success = U_MISSING_RESOURCE_ERROR; // requested a calendar type which could NOT be found.
|
||||
delete c;
|
||||
delete zone;
|
||||
return NULL;
|
||||
}
|
||||
#ifdef U_DEBUG_CALSVC
|
||||
fprintf(stderr, "setting to locale %s\n", (const char*)aLocale.getName());
|
||||
fprintf(stderr, "%p: setting to locale %s\n", c, (const char*)aLocale.getName());
|
||||
#endif
|
||||
c->setWeekCountData(aLocale, success); // set the correct locale (this was an indirected calendar)
|
||||
} else {
|
||||
@ -974,7 +1000,7 @@ void Calendar::computeFields(UErrorCode &ec)
|
||||
// JULIAN_DAY field and also removes some inelegant code. - Liu
|
||||
// 11/6/00
|
||||
|
||||
int32_t days = (int32_t)Math::floorDivide(localMillis, kOneDay);
|
||||
int32_t days = (int32_t)Math::floorDivide(localMillis, (double)kOneDay);
|
||||
|
||||
internalSet(UCAL_JULIAN_DAY,days + kEpochStartAsJulianDay);
|
||||
|
||||
@ -1851,52 +1877,52 @@ Calendar::getMinimalDaysInFirstWeek() const
|
||||
|
||||
int32_t
|
||||
Calendar::getMinimum(EDateFields field) const {
|
||||
return getLimit((UCalendarDateFields) field,U_CAL_LIMIT_MINIMUM);
|
||||
return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MINIMUM);
|
||||
}
|
||||
|
||||
int32_t
|
||||
Calendar::getMinimum(UCalendarDateFields field) const
|
||||
{
|
||||
return getLimit(field,U_CAL_LIMIT_MINIMUM);
|
||||
return getLimit(field,UCAL_LIMIT_MINIMUM);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
int32_t
|
||||
Calendar::getMaximum(EDateFields field) const
|
||||
{
|
||||
return getLimit((UCalendarDateFields) field,U_CAL_LIMIT_MAXIMUM);
|
||||
return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MAXIMUM);
|
||||
}
|
||||
|
||||
int32_t
|
||||
Calendar::getMaximum(UCalendarDateFields field) const
|
||||
{
|
||||
return getLimit(field,U_CAL_LIMIT_MAXIMUM);
|
||||
return getLimit(field,UCAL_LIMIT_MAXIMUM);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
int32_t
|
||||
Calendar::getGreatestMinimum(EDateFields field) const
|
||||
{
|
||||
return getLimit((UCalendarDateFields)field,U_CAL_LIMIT_GREATEST_MINIMUM);
|
||||
return getLimit((UCalendarDateFields)field,UCAL_LIMIT_GREATEST_MINIMUM);
|
||||
}
|
||||
|
||||
int32_t
|
||||
Calendar::getGreatestMinimum(UCalendarDateFields field) const
|
||||
{
|
||||
return getLimit(field,U_CAL_LIMIT_GREATEST_MINIMUM);
|
||||
return getLimit(field,UCAL_LIMIT_GREATEST_MINIMUM);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
int32_t
|
||||
Calendar::getLeastMaximum(EDateFields field) const
|
||||
{
|
||||
return getLimit((UCalendarDateFields) field,U_CAL_LIMIT_LEAST_MAXIMUM);
|
||||
return getLimit((UCalendarDateFields) field,UCAL_LIMIT_LEAST_MAXIMUM);
|
||||
}
|
||||
|
||||
int32_t
|
||||
Calendar::getLeastMaximum(UCalendarDateFields field) const
|
||||
{
|
||||
return getLimit( field,U_CAL_LIMIT_LEAST_MAXIMUM);
|
||||
return getLimit( field,UCAL_LIMIT_LEAST_MAXIMUM);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -2088,55 +2114,53 @@ UCalendarDateFields Calendar::resolveFields(const UFieldResolutionTable* precede
|
||||
return (UCalendarDateFields)( (bestField>=kResolveRemap)?(bestField&(kResolveRemap-1)):bestField );
|
||||
}
|
||||
|
||||
const int32_t Calendar::kResolveRemap = 32;
|
||||
|
||||
const UFieldResolutionTable Calendar::kDatePrecedence[] =
|
||||
{
|
||||
{
|
||||
{ UCAL_DAY_OF_MONTH, -1 },
|
||||
{ UCAL_WEEK_OF_YEAR, UCAL_DAY_OF_WEEK, -1 },
|
||||
{ UCAL_WEEK_OF_MONTH, UCAL_DAY_OF_WEEK, -1 },
|
||||
{ UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, -1 },
|
||||
{ UCAL_WEEK_OF_YEAR, UCAL_DOW_LOCAL, -1 },
|
||||
{ UCAL_WEEK_OF_MONTH, UCAL_DOW_LOCAL, -1 },
|
||||
{ UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, -1 },
|
||||
{ UCAL_DAY_OF_YEAR, -1 },
|
||||
{ kResolveRemap | UCAL_DAY_OF_MONTH, UCAL_YEAR, -1 }, // if YEAR is set over YEAR_WOY use DAY_OF_MONTH
|
||||
{ kResolveRemap | UCAL_WEEK_OF_YEAR, UCAL_YEAR_WOY, -1 }, // if YEAR_WOY is set, calc based on WEEK_OF_YEAR
|
||||
{ -1 }
|
||||
{ UCAL_DAY_OF_MONTH, kResolveSTOP },
|
||||
{ UCAL_WEEK_OF_YEAR, UCAL_DAY_OF_WEEK, kResolveSTOP },
|
||||
{ UCAL_WEEK_OF_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
|
||||
{ UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
|
||||
{ UCAL_WEEK_OF_YEAR, UCAL_DOW_LOCAL, kResolveSTOP },
|
||||
{ UCAL_WEEK_OF_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
|
||||
{ UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
|
||||
{ UCAL_DAY_OF_YEAR, kResolveSTOP },
|
||||
{ kResolveRemap | UCAL_DAY_OF_MONTH, UCAL_YEAR, kResolveSTOP }, // if YEAR is set over YEAR_WOY use DAY_OF_MONTH
|
||||
{ kResolveRemap | UCAL_WEEK_OF_YEAR, UCAL_YEAR_WOY, kResolveSTOP }, // if YEAR_WOY is set, calc based on WEEK_OF_YEAR
|
||||
{ kResolveSTOP }
|
||||
},
|
||||
{
|
||||
{ UCAL_WEEK_OF_YEAR, -1 },
|
||||
{ UCAL_WEEK_OF_MONTH, -1 },
|
||||
{ UCAL_DAY_OF_WEEK_IN_MONTH, -1 },
|
||||
{ kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, -1 },
|
||||
{ kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, -1 },
|
||||
{ -1 }
|
||||
{ UCAL_WEEK_OF_YEAR, kResolveSTOP },
|
||||
{ UCAL_WEEK_OF_MONTH, kResolveSTOP },
|
||||
{ UCAL_DAY_OF_WEEK_IN_MONTH, kResolveSTOP },
|
||||
{ kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP },
|
||||
{ kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP },
|
||||
{ kResolveSTOP }
|
||||
},
|
||||
{{-1}}
|
||||
{{kResolveSTOP}}
|
||||
};
|
||||
|
||||
|
||||
const UFieldResolutionTable Calendar::kDOWPrecedence[] =
|
||||
{
|
||||
{
|
||||
{ UCAL_DAY_OF_WEEK,-1, -1 },
|
||||
{ UCAL_DOW_LOCAL,-1, -1 },
|
||||
{-1}
|
||||
{ UCAL_DAY_OF_WEEK,kResolveSTOP, kResolveSTOP },
|
||||
{ UCAL_DOW_LOCAL,kResolveSTOP, kResolveSTOP },
|
||||
{kResolveSTOP}
|
||||
},
|
||||
{{-1}}
|
||||
{{kResolveSTOP}}
|
||||
};
|
||||
|
||||
// precedence for calculating a year
|
||||
const UFieldResolutionTable Calendar::kYearPrecedence[] =
|
||||
{
|
||||
{
|
||||
{ UCAL_YEAR, -1 },
|
||||
{ UCAL_EXTENDED_YEAR, -1 },
|
||||
{ UCAL_YEAR_WOY, UCAL_WEEK_OF_YEAR, -1 }, // YEAR_WOY is useless without WEEK_OF_YEAR
|
||||
{ -1 }
|
||||
{ UCAL_YEAR, kResolveSTOP },
|
||||
{ UCAL_EXTENDED_YEAR, kResolveSTOP },
|
||||
{ UCAL_YEAR_WOY, UCAL_WEEK_OF_YEAR, kResolveSTOP }, // YEAR_WOY is useless without WEEK_OF_YEAR
|
||||
{ kResolveSTOP }
|
||||
},
|
||||
{{-1}}
|
||||
{{kResolveSTOP}}
|
||||
};
|
||||
|
||||
|
||||
@ -2169,7 +2193,7 @@ void Calendar::computeTime(UErrorCode& status) {
|
||||
// time and call clear(MONTH) to reset the MONTH to January. This
|
||||
// is legacy behavior. Without this, clear(MONTH) has no effect,
|
||||
// since the internally set JULIAN_DAY is used.
|
||||
if (fStamp[UCAL_MILLISECONDS_IN_DAY] >= kMinimumUserStamp &&
|
||||
if (fStamp[UCAL_MILLISECONDS_IN_DAY] >= ((int32_t)kMinimumUserStamp) &&
|
||||
newestStamp(UCAL_AM_PM, UCAL_MILLISECOND, kUnset) <= fStamp[UCAL_MILLISECONDS_IN_DAY]) {
|
||||
millisInDay = internalGet(UCAL_MILLISECONDS_IN_DAY);
|
||||
} else {
|
||||
@ -2189,8 +2213,8 @@ void Calendar::computeTime(UErrorCode& status) {
|
||||
// Again, we assume standard time.
|
||||
// We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
|
||||
// or DST_OFFSET fields; then we use those fields.
|
||||
if (fStamp[UCAL_ZONE_OFFSET] >= kMinimumUserStamp ||
|
||||
fStamp[UCAL_DST_OFFSET] >= kMinimumUserStamp) {
|
||||
if (fStamp[UCAL_ZONE_OFFSET] >= ((int32_t)kMinimumUserStamp) ||
|
||||
fStamp[UCAL_DST_OFFSET] >= ((int32_t)kMinimumUserStamp)) {
|
||||
millisInDay -= internalGet(UCAL_ZONE_OFFSET) + internalGet(UCAL_DST_OFFSET);
|
||||
} else {
|
||||
millisInDay -= computeZoneOffset(millis, millisInDay,status);
|
||||
@ -2271,7 +2295,7 @@ int32_t Calendar::computeJulianDay()
|
||||
// to January. This is legacy behavior. Without this,
|
||||
// clear(MONTH) has no effect, since the internally set JULIAN_DAY
|
||||
// is used.
|
||||
if (fStamp[UCAL_JULIAN_DAY] >= kMinimumUserStamp) {
|
||||
if (fStamp[UCAL_JULIAN_DAY] >= (int32_t)kMinimumUserStamp) {
|
||||
int32_t bestStamp = newestStamp(UCAL_ERA, UCAL_DAY_OF_WEEK_IN_MONTH, kUnset);
|
||||
bestStamp = newestStamp(UCAL_YEAR_WOY, UCAL_EXTENDED_YEAR, bestStamp);
|
||||
if (bestStamp <= fStamp[UCAL_JULIAN_DAY]) {
|
||||
|
@ -93,17 +93,6 @@ static const int32_t kGregorianCalendarLimits[UCAL_FIELD_COUNT][4] = {
|
||||
{/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1} // MILLISECONDS_IN_DAY
|
||||
};
|
||||
|
||||
// These numbers are 2^52 - 1, the largest allowable mantissa in a 64-bit double
|
||||
// with a 0 exponent. These are the absolute largest numbers for millis that
|
||||
// this calendar will handle reliably. It will work for larger values, however.
|
||||
// The problem is that, once the exponent is not 0, the calendar will jump.
|
||||
// When translated into a year, LATEST_SUPPORTED_MILLIS corresponds to 144,683 AD
|
||||
// and EARLIEST_SUPPORTED_MILLIS corresponds to 140,742 BC
|
||||
static const UDate EARLIEST_SUPPORTED_MILLIS = - 4503599627370495.0;
|
||||
static const UDate LATEST_SUPPORTED_MILLIS = 4503599627370495.0;
|
||||
|
||||
static const int32_t kGregorianShift = 10;// days (TODO: make this handle non-1582 cutover)
|
||||
static const int32_t kGregorianWeekShift = 2;// weeks
|
||||
/*
|
||||
* <pre>
|
||||
* Greatest Least
|
||||
@ -333,7 +322,7 @@ GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status)
|
||||
// normalized cutover is in pure date milliseconds; it contains no time
|
||||
// of day or timezone component, and it used to compare against other
|
||||
// pure date values.
|
||||
int32_t cutoverDay = (int32_t)Math::floorDivide(fGregorianCutover, kOneDay);
|
||||
int32_t cutoverDay = (int32_t)Math::floorDivide(fGregorianCutover, (double)kOneDay);
|
||||
fNormalizedGregorianCutover = cutoverDay * kOneDay;
|
||||
|
||||
// Handle the rare case of numeric overflow. If the user specifies a
|
||||
@ -427,8 +416,7 @@ void GregorianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& statu
|
||||
// [j81] if we are after the cutover in its year, shift the day of the year
|
||||
if((eyear == fGregorianCutoverYear) && (julianDay >= fCutoverJulianDay)) {
|
||||
//from handleComputeMonthStart
|
||||
int32_t y = eyear-1;
|
||||
int32_t gregShift = Math::floorDivide(y, 400) - Math::floorDivide(y, 100) + 2;
|
||||
int32_t gregShift = Grego::gregorianShift(eyear);
|
||||
#if defined (U_DEBUG_CAL)
|
||||
fprintf(stderr, "%s:%d: gregorian shift %d ::: doy%d => %d [cut=%d]\n",
|
||||
__FILE__, __LINE__,gregShift, dayOfYear, dayOfYear+gregShift, fCutoverJulianDay);
|
||||
@ -510,8 +498,7 @@ int32_t GregorianCalendar::handleComputeJulianDay(UCalendarDateFields bestField)
|
||||
}
|
||||
|
||||
if(fIsGregorian && (internalGet(UCAL_EXTENDED_YEAR) == fGregorianCutoverYear)) {
|
||||
int32_t y = internalGet(UCAL_EXTENDED_YEAR)-1;
|
||||
int32_t gregShift = Math::floorDivide(y, 400) - Math::floorDivide(y, 100) + 2;
|
||||
int32_t gregShift = Grego::gregorianShift(internalGet(UCAL_EXTENDED_YEAR));
|
||||
if (bestField == UCAL_DAY_OF_YEAR) {
|
||||
#if defined (U_DEBUG_CAL)
|
||||
fprintf(stderr, "%s:%d: [DOY%d] gregorian shift of JD %d += %d\n",
|
||||
@ -544,7 +531,7 @@ int32_t GregorianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month,
|
||||
}
|
||||
|
||||
UBool isLeap = eyear%4 == 0;
|
||||
int32_t y = eyear - 1;
|
||||
int32_t y = eyear-1;
|
||||
int32_t julianDay = 365*y + Math::floorDivide(y, 4) + (kJan1_1JulianDay - 3);
|
||||
|
||||
nonConstThis->fIsGregorian = (eyear >= fGregorianCutoverYear);
|
||||
@ -559,7 +546,7 @@ int32_t GregorianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month,
|
||||
isLeap = isLeap && ((eyear%100 != 0) || (eyear%400 == 0));
|
||||
// Add 2 because Gregorian calendar starts 2 days after
|
||||
// Julian calendar
|
||||
int32_t gregShift = Math::floorDivide(y, 400) - Math::floorDivide(y, 100) + 2;
|
||||
int32_t gregShift = Grego::gregorianShift(eyear);
|
||||
#if defined (U_DEBUG_CAL)
|
||||
fprintf(stderr, "%s:%d: (hcms%d/%d) gregorian shift of %d += %d\n",
|
||||
__FILE__, __LINE__, eyear, month, julianDay, gregShift);
|
||||
@ -719,7 +706,7 @@ double GregorianCalendar::computeJulianDayOfYear(UBool isGregorian,
|
||||
if (isGregorian) {
|
||||
isLeap = isLeap && ((year%100 != 0) || (year%400 == 0));
|
||||
// Add 2 because Gregorian calendar starts 2 days after Julian calendar
|
||||
julianDay += Math::floorDivide(y, 400) - Math::floorDivide(y, 100) + 2;
|
||||
julianDay += Grego::gregorianShift(year);
|
||||
}
|
||||
|
||||
return julianDay;
|
||||
@ -783,7 +770,7 @@ double GregorianCalendar::computeJulianDayOfYear(UBool isGregorian,
|
||||
double
|
||||
GregorianCalendar::millisToJulianDay(UDate millis)
|
||||
{
|
||||
return (double)kEpochStartAsJulianDay + Math::floorDivide(millis, kOneDay);
|
||||
return (double)kEpochStartAsJulianDay + Math::floorDivide(millis, (double)kOneDay);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -1066,15 +1053,13 @@ int32_t GregorianCalendar::getActualMinimum(UCalendarDateFields field) const
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Old year limits were least max 292269054, max 292278994.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
int32_t GregorianCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const {
|
||||
return kGregorianCalendarLimits[field][limitType];
|
||||
}
|
||||
|
@ -63,6 +63,28 @@ class U_I18N_API Math {
|
||||
int32_t& remainder);
|
||||
};
|
||||
|
||||
// Useful millisecond constants
|
||||
#define kOneDay (1.0 * U_MILLIS_PER_DAY) // 86,400,000
|
||||
#define kOneHour (60*60*1000)
|
||||
#define kOneMinute 60000
|
||||
#define kOneSecond 1000
|
||||
#define kOneMillisecond 1
|
||||
#define kOneWeek (7.0 * kOneDay) // 604,800,000
|
||||
|
||||
// Epoch constants
|
||||
#define kJan1_1JulianDay 1721426 // January 1, year 1 (Gregorian)
|
||||
|
||||
#define kEpochStartAsJulianDay 2440588 // January 1, 1970 (Gregorian)
|
||||
|
||||
#define kEpochYear 1970
|
||||
|
||||
|
||||
#define kEarliestViableMillis -185331720384000000.0 // minimum representable by julian day -1e17
|
||||
|
||||
#define kLatestViableMillis 185753453990400000.0 // max representable by julian day +1e17
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A utility class providing proleptic Gregorian calendar functions
|
||||
* used by time zone and calendar code. Do not instantiate.
|
||||
@ -146,6 +168,13 @@ class U_I18N_API Grego {
|
||||
*/
|
||||
static inline int32_t millisToJulianDay(double millis);
|
||||
|
||||
/**
|
||||
* Calculates the Gregorian day shift value for an extended year.
|
||||
* @param eyear Extended year
|
||||
* @returns number of days to ADD to Julian in order to convert from J->G
|
||||
*/
|
||||
static inline int32_t gregorianShift(int32_t eyear);
|
||||
|
||||
private:
|
||||
static const int16_t DAYS_BEFORE[24];
|
||||
static const int8_t MONTH_LENGTH[24];
|
||||
@ -176,32 +205,20 @@ inline void Grego::dayToFields(double day, int32_t& year, int32_t& month,
|
||||
dayToFields(day,year,month,dom,dow,doy_unused);
|
||||
}
|
||||
|
||||
// Useful millisecond constants
|
||||
static const double kOneDay = U_MILLIS_PER_DAY; // 86,400,000
|
||||
static const int32_t kOneHour = 60*60*1000;
|
||||
#define kOneMinute 60000
|
||||
#define kOneSecond 1000
|
||||
#define kOneMillisecond 1
|
||||
static const double kOneWeek = 7.0 * U_MILLIS_PER_DAY; // 604,800,000
|
||||
|
||||
static const int32_t kJan1_1JulianDay = 1721426; // January 1, year 1 (Gregorian)
|
||||
|
||||
static const int32_t kEpochStartAsJulianDay = 2440588; // January 1, 1970 (Gregorian)
|
||||
|
||||
static const int32_t kEpochYear = 1970;
|
||||
|
||||
inline double Grego::julianDayToMillis(int32_t julian)
|
||||
{
|
||||
return (julian - kEpochStartAsJulianDay) * kOneDay;
|
||||
}
|
||||
|
||||
inline int32_t Grego::millisToJulianDay(double millis) {
|
||||
return (int32_t) (kEpochStartAsJulianDay + Math::floorDivide(millis, kOneDay));
|
||||
return (int32_t) (kEpochStartAsJulianDay + Math::floorDivide(millis, (double)kOneDay));
|
||||
}
|
||||
|
||||
static const double kEarliestViableMillis = -185331720384000000.0; // minimum representable by julian day -1e17
|
||||
|
||||
static const double kLatestViableMillis = 185753453990400000.0; // max representable by julian day +1e17
|
||||
inline int32_t Grego::gregorianShift(int32_t eyear) {
|
||||
int32_t y = eyear-1;
|
||||
int32_t gregShift = Math::floorDivide(y, 400) - Math::floorDivide(y, 100) + 2;
|
||||
return gregShift;
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -192,7 +192,7 @@ public:
|
||||
YEAR_WOY, // 'Y' Example: 1..big number - Year of Week of Year
|
||||
DOW_LOCAL, // 'e' Example: 1..7 - Day of Week / Localized
|
||||
|
||||
FIELD_COUNT = UCAL_FIELD_COUNT
|
||||
FIELD_COUNT = UCAL_FIELD_COUNT // See ucal.h for other fields.
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1320,15 +1320,15 @@ protected:
|
||||
virtual void prepareGetActual(UCalendarDateFields field, UBool isMinimum, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Limit enums. Not in sync with UCalendarLimitTypes
|
||||
* Limit enums. Not in sync with UCalendarLimitTypes (refers to internal fields).
|
||||
* @internal
|
||||
*/
|
||||
enum ELimitType {
|
||||
U_CAL_LIMIT_MINIMUM = 0,
|
||||
U_CAL_LIMIT_GREATEST_MINIMUM,
|
||||
U_CAL_LIMIT_LEAST_MAXIMUM,
|
||||
U_CAL_LIMIT_MAXIMUM,
|
||||
U_CAL_LIMIT_COUNT
|
||||
UCAL_LIMIT_MINIMUM = 0,
|
||||
UCAL_LIMIT_GREATEST_MINIMUM,
|
||||
UCAL_LIMIT_LEAST_MAXIMUM,
|
||||
UCAL_LIMIT_MAXIMUM,
|
||||
UCAL_LIMIT_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1361,7 +1361,7 @@ protected:
|
||||
* @see #ELimitType
|
||||
* @internal
|
||||
*/
|
||||
int32_t getLimit(UCalendarDateFields field, ELimitType limitType) const;
|
||||
virtual int32_t getLimit(UCalendarDateFields field, ELimitType limitType) const;
|
||||
|
||||
|
||||
/**
|
||||
@ -1467,11 +1467,16 @@ protected:
|
||||
int32_t newestStamp(UCalendarDateFields start, UCalendarDateFields end, int32_t bestSoFar) const;
|
||||
|
||||
/**
|
||||
* Value to be bitwised "ORed" against resolve table field values for remapping.
|
||||
* Values for field resolution tables
|
||||
* @see #resolveFields
|
||||
* @internal
|
||||
*/
|
||||
static const int32_t kResolveRemap;
|
||||
enum {
|
||||
/** Marker for end of resolve set (row or group). */
|
||||
kResolveSTOP = -1,
|
||||
/** Value to be bitwised "ORed" against resolve table field values for remapping. Example: (UCAL_DATE | kResolveRemap) in 1st column will cause 'UCAL_DATE' to be returned, but will not examine the value of UCAL_DATE. */
|
||||
kResolveRemap = 32
|
||||
};
|
||||
|
||||
/**
|
||||
* Precedence table for Dates
|
||||
@ -1496,7 +1501,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Given a precedence table, return the newest field combination in
|
||||
* the table, or -1 if none is found.
|
||||
* the table, or -1 (kResolveSTOP) if none is found.
|
||||
*
|
||||
* <p>The precedence table is a 3-dimensional array of integers. It
|
||||
* may be thought of as an array of groups. Each group is an array of
|
||||
@ -1510,7 +1515,7 @@ protected:
|
||||
* <p>In some cases, it may be desirable to map a line to field that
|
||||
* whose stamp is NOT examined. For example, if the best field is
|
||||
* DAY_OF_WEEK then the DAY_OF_WEEK_IN_MONTH algorithm may be used. In
|
||||
* order to do this, insert the value <code>REMAP_RESOLVE | F</code> at
|
||||
* order to do this, insert the value <code>kResolveRemap | F</code> at
|
||||
* the start of the line, where <code>F</code> is the desired return
|
||||
* field value. This field will NOT be examined; it only determines
|
||||
* the return value if the other fields in the line are the newest.
|
||||
|
@ -256,7 +256,7 @@ enum UCalendarDateFields {
|
||||
*/
|
||||
UCAL_DOW_LOCAL,
|
||||
/**
|
||||
* Year of this calendar system, encompassing all supra-year fields. For example, in Gregorian/Julian calendars, positive Extended Year values indicate years AD, 1 BC = -1 extended, 2 BC = -2 extended, and so on.
|
||||
* Year of this calendar system, encompassing all supra-year fields. For example, in Gregorian/Julian calendars, positive Extended Year values indicate years AD, 1 BC = 0 extended, 2 BC = -1 extended, and so on.
|
||||
* @draft ICU 2.8
|
||||
*/
|
||||
UCAL_EXTENDED_YEAR,
|
||||
@ -277,7 +277,7 @@ enum UCalendarDateFields {
|
||||
UCAL_FIELD_COUNT,
|
||||
|
||||
/**
|
||||
* Synonym for UCAL_DATE -
|
||||
* Synonym for UCAL_DATE
|
||||
* @draft ICU 2.8
|
||||
**/
|
||||
UCAL_DAY_OF_MONTH=UCAL_DATE
|
||||
|
Loading…
Reference in New Issue
Block a user