ICU-2966 cleanup and docs

X-SVN-Rev: 12850
This commit is contained in:
Alan Liu 2003-08-16 00:10:56 +00:00
parent cc19ae1c9d
commit 4ce8f701f9
2 changed files with 64 additions and 33 deletions

View File

@ -130,14 +130,18 @@ static void dayToFields(double day, int32_t& year, int32_t& month,
//---------------------------------------------------------------------- //----------------------------------------------------------------------
/** /**
* Default constructor * Default constructor. Creates a time zone with an empty ID and
* a fixed GMT offset of zero.
*/ */
OlsonTimeZone::OlsonTimeZone() : finalZone(0), finalYear(INT32_MAX) { OlsonTimeZone::OlsonTimeZone() : finalZone(0), finalYear(INT32_MAX) {
constructEmpty(); constructEmpty();
} }
/**
* Construct a GMT+0 zone with no transitions. This is done when a
* constructor fails so the resultant object is well-behaved.
*/
void OlsonTimeZone::constructEmpty() { void OlsonTimeZone::constructEmpty() {
// Construct a GMT+0 zone with no transitions
transitionCount = 0; transitionCount = 0;
typeCount = 1; typeCount = 1;
transitionTimes = typeOffsets = ZEROS; transitionTimes = typeOffsets = ZEROS;
@ -146,6 +150,10 @@ void OlsonTimeZone::constructEmpty() {
/** /**
* Construct from a resource bundle * Construct from a resource bundle
* @param top the top-level zoneinfo resource bundle. This is used
* to lookup the rule that `res' may refer to, if there is one.
* @param res the resource bundle of the zone to be constructed
* @param ec input-output error code
*/ */
OlsonTimeZone::OlsonTimeZone(const UResourceBundle* top, OlsonTimeZone::OlsonTimeZone(const UResourceBundle* top,
const UResourceBundle* res, const UResourceBundle* res,
@ -179,7 +187,7 @@ OlsonTimeZone::OlsonTimeZone(const UResourceBundle* top,
r = ures_getByIndex(res, 1, NULL, &ec); r = ures_getByIndex(res, 1, NULL, &ec);
typeOffsets = ures_getIntVector(r, &i, &ec); typeOffsets = ures_getIntVector(r, &i, &ec);
ures_close(r); ures_close(r);
if ((i<2 || i>0x7FFF || ((i&1)!=0)) && U_SUCCESS(ec)) { if ((i<2 || i>0x7FFE || ((i&1)!=0)) && U_SUCCESS(ec)) {
ec = U_INVALID_FORMAT_ERROR; ec = U_INVALID_FORMAT_ERROR;
} }
typeCount = (int16_t) i >> 1; typeCount = (int16_t) i >> 1;
@ -193,6 +201,7 @@ OlsonTimeZone::OlsonTimeZone(const UResourceBundle* top,
ec = U_INVALID_FORMAT_ERROR; ec = U_INVALID_FORMAT_ERROR;
} }
// Process final rule and data, if any
if (size == 5) { if (size == 5) {
UnicodeString ruleid = ures_getUnicodeStringByIndex(res, 3, &ec); UnicodeString ruleid = ures_getUnicodeStringByIndex(res, 3, &ec);
r = ures_getByIndex(res, 4, NULL, &ec); r = ures_getByIndex(res, 4, NULL, &ec);
@ -278,10 +287,10 @@ OlsonTimeZone::~OlsonTimeZone() {
UBool OlsonTimeZone::operator==(const TimeZone& other) const { UBool OlsonTimeZone::operator==(const TimeZone& other) const {
const OlsonTimeZone* z = (const OlsonTimeZone*) &other; const OlsonTimeZone* z = (const OlsonTimeZone*) &other;
// typeData points into memory-mapped or DLL space, so if two
// zones are the same, their pointers will be equal.
return TimeZone::operator==(other) && return TimeZone::operator==(other) &&
// [sic] pointer comparison: // [sic] pointer comparison: typeData points into
// memory-mapped or DLL space, so if two zones have the same
// pointer, they are equal.
(typeData == z->typeData || (typeData == z->typeData ||
// If the pointers are not equal, the zones may still // If the pointers are not equal, the zones may still
// be equal if their rules and transitions are equal // be equal if their rules and transitions are equal
@ -389,6 +398,9 @@ int32_t OlsonTimeZone::getRawOffset() const {
return raw; return raw;
} }
/**
* TimeZone API.
*/
void OlsonTimeZone::getOffset(UDate date, UBool local, int32_t& rawoff, void OlsonTimeZone::getOffset(UDate date, UBool local, int32_t& rawoff,
int32_t& dstoff, UErrorCode& ec) const { int32_t& dstoff, UErrorCode& ec) const {
if (U_FAILURE(ec)) { if (U_FAILURE(ec)) {
@ -396,23 +408,23 @@ void OlsonTimeZone::getOffset(UDate date, UBool local, int32_t& rawoff,
} }
int32_t year, month, dom, dow; int32_t year, month, dom, dow;
double t = uprv_floor(date / U_MILLIS_PER_SECOND); double secs = uprv_floor(date / U_MILLIS_PER_SECOND);
double d = uprv_floor(date / U_MILLIS_PER_DAY); double days = uprv_floor(date / U_MILLIS_PER_DAY);
dayToFields(d, year, month, dom, dow); dayToFields(days, year, month, dom, dow);
if (year > finalYear) { // [sic] >, not >=; see above if (year > finalYear) { // [sic] >, not >=; see above
U_ASSERT(finalZone != 0); U_ASSERT(finalZone != 0);
int32_t millis = (int32_t) (date - d * U_MILLIS_PER_DAY); int32_t millis = (int32_t) (date - days * U_MILLIS_PER_DAY);
rawoff = finalZone->getRawOffset(); rawoff = finalZone->getRawOffset();
if (!local) { if (!local) {
// Adjust from GMT to local // Adjust from GMT to local
date += rawoff; date += rawoff;
double d2 = uprv_floor(date / U_MILLIS_PER_DAY); double days2 = uprv_floor(date / U_MILLIS_PER_DAY);
millis = (int32_t) (date - d2 * U_MILLIS_PER_DAY); millis = (int32_t) (date - days2 * U_MILLIS_PER_DAY);
if (d2 != d) { if (days2 != days) {
dayToFields(d2, year, month, dom, dow); dayToFields(days2, year, month, dom, dow);
} }
} }
@ -422,7 +434,7 @@ void OlsonTimeZone::getOffset(UDate date, UBool local, int32_t& rawoff,
return; return;
} }
int16_t i = findTransition(t, local); int16_t i = findTransition(secs, local);
rawoff = rawOffset(i) * U_MILLIS_PER_SECOND; rawoff = rawOffset(i) * U_MILLIS_PER_SECOND;
dstoff = dstOffset(i) * U_MILLIS_PER_SECOND; dstoff = dstOffset(i) * U_MILLIS_PER_SECOND;
} }
@ -473,17 +485,17 @@ int16_t OlsonTimeZone::findTransition(double time, UBool local) const {
* TimeZone API. * TimeZone API.
*/ */
UBool OlsonTimeZone::useDaylightTime() const { UBool OlsonTimeZone::useDaylightTime() const {
// For most clients, if DST was observed in 1942 (for example) but // If DST was observed in 1942 (for example) but has never been
// has never been observed from 1943 to the present, most clients // observed from 1943 to the present, most clients will expect
// expect this method to return FALSE. This method determines // this method to return FALSE. This method determines whether
// whether DST is in use in the current year (at any point in the // DST is in use in the current year (at any point in the year)
// year) and returns TRUE if so. // and returns TRUE if so.
int32_t d = floorDivide(uprv_getUTCtime(), SECONDS_PER_DAY); // epoch days int32_t days = floorDivide(uprv_getUTCtime(), SECONDS_PER_DAY); // epoch days
int32_t year, month, dom, dow; int32_t year, month, dom, dow;
dayToFields(d, year, month, dom, dow); dayToFields(days, year, month, dom, dow);
if (year > finalYear) { // [sic] >, not >=; see above if (year > finalYear) { // [sic] >, not >=; see above
U_ASSERT(finalZone != 0 && finalZone->useDaylightTime()); U_ASSERT(finalZone != 0 && finalZone->useDaylightTime());

View File

@ -98,11 +98,23 @@ UBool timeZone_cleanup()
U_NAMESPACE_BEGIN U_NAMESPACE_BEGIN
// TODO cleanup /**
static int32_t OLSON_ZONE_START = -1; * The Olson data is stored the "zoneinfo" resource bundle.
static int32_t OLSON_ZONE_COUNT = 0; * Sub-resources are organized into three ranges of data: Zones, final
* rules, and country tables. There is also a meta-data resource
* which has six integers: The start and count values for the three
* ranges. E.g., 10, 15, 3, 7, 0, 3 means that sub resources at index
* 0..2 are country maps, 3..9 are final rules, and 10..24 are zones.
*
* We currently only need to know the zone range.
*/
static int32_t OLSON_ZONE_START = -1; // starting index of zones
static int32_t OLSON_ZONE_COUNT = 0; // count of zones
// TODO docs, cleanup /**
* Given a pointer to an open "zoneinfo" resource, load up the Olson
* meta-data. Return TRUE if successful.
*/
static UBool getOlsonMeta(const UResourceBundle* top) { static UBool getOlsonMeta(const UResourceBundle* top) {
if (OLSON_ZONE_START < 0) { if (OLSON_ZONE_START < 0) {
UErrorCode ec = U_ZERO_ERROR; UErrorCode ec = U_ZERO_ERROR;
@ -122,6 +134,9 @@ static UBool getOlsonMeta(const UResourceBundle* top) {
return (OLSON_ZONE_START >= 0); return (OLSON_ZONE_START >= 0);
} }
/**
* Load up the Olson meta-data. Return TRUE if successful.
*/
static UBool getOlsonMeta() { static UBool getOlsonMeta() {
if (OLSON_ZONE_START < 0) { if (OLSON_ZONE_START < 0) {
UErrorCode ec = U_ZERO_ERROR; UErrorCode ec = U_ZERO_ERROR;
@ -134,7 +149,14 @@ static UBool getOlsonMeta() {
return (OLSON_ZONE_START >= 0); return (OLSON_ZONE_START >= 0);
} }
// TODO docs, cleanup // TODO: #ifdef out this code after 8-Nov-2003
// #ifdef ICU_TIMEZONE_USE_DEPRECATES
/**
* Load all the ids from the "zoneinfo" resource bundle into a static
* array that we hang onto. This is _only_ used to implement the
* deprecated createAvailableIDs() API.
*/
static UBool loadOlsonIDs() { static UBool loadOlsonIDs() {
if (OLSON_IDS != 0) { if (OLSON_IDS != 0) {
return TRUE; return TRUE;
@ -188,6 +210,8 @@ static UBool loadOlsonIDs() {
return TRUE; return TRUE;
} }
// #endif //ICU_TIMEZONE_USE_DEPRECATES
// ------------------------------------- // -------------------------------------
const TimeZone* const TimeZone*
@ -804,9 +828,6 @@ TimeZone::createEnumeration(const char* country) {
// TODO: #ifdef out this code after 8-Nov-2003 // TODO: #ifdef out this code after 8-Nov-2003
// #ifdef ICU_TIMEZONE_USE_DEPRECATES // #ifdef ICU_TIMEZONE_USE_DEPRECATES
// This stuff is just here so the deprecated createAvailableIDs() API
// continues to work with the new 2.8 time zones.
const UnicodeString** const UnicodeString**
TimeZone::createAvailableIDs(int32_t rawOffset, int32_t& numIDs) TimeZone::createAvailableIDs(int32_t rawOffset, int32_t& numIDs)
{ {
@ -831,9 +852,7 @@ TimeZone::createAvailableIDs(int32_t rawOffset, int32_t& numIDs)
UnicodeString s; UnicodeString s;
for (int32_t i=0; i<OLSON_ZONE_COUNT; ++i) { for (int32_t i=0; i<OLSON_ZONE_COUNT; ++i) {
// This is VERY inefficient -- but this code is going away // This is VERY inefficient.
// soon so it doesn't matter. This is just for backward
// compatibility...
TimeZone* z = TimeZone::createTimeZone(OLSON_IDS[i]); TimeZone* z = TimeZone::createTimeZone(OLSON_IDS[i]);
// Make sure we get back the ID we wanted (if the ID is // Make sure we get back the ID we wanted (if the ID is
// invalid we get back GMT). // invalid we get back GMT).