michael@0: /* michael@0: ******************************************************************************* michael@0: * Copyright (C) 2007-2012, International Business Machines Corporation and michael@0: * others. All Rights Reserved. michael@0: ******************************************************************************* michael@0: */ michael@0: michael@0: #include "utypeinfo.h" // for 'typeid' to work michael@0: michael@0: #include "unicode/utypes.h" michael@0: michael@0: #if !UCONFIG_NO_FORMATTING michael@0: michael@0: #include "unicode/tzrule.h" michael@0: #include "unicode/ucal.h" michael@0: #include "gregoimp.h" michael@0: #include "cmemory.h" michael@0: #include "uarrsort.h" michael@0: michael@0: U_CDECL_BEGIN michael@0: // UComparator function for sorting start times michael@0: static int32_t U_CALLCONV michael@0: compareDates(const void * /*context*/, const void *left, const void *right) { michael@0: UDate l = *((UDate*)left); michael@0: UDate r = *((UDate*)right); michael@0: int32_t res = l < r ? -1 : (l == r ? 0 : 1); michael@0: return res; michael@0: } michael@0: U_CDECL_END michael@0: michael@0: U_NAMESPACE_BEGIN michael@0: michael@0: TimeZoneRule::TimeZoneRule(const UnicodeString& name, int32_t rawOffset, int32_t dstSavings) michael@0: : UObject(), fName(name), fRawOffset(rawOffset), fDSTSavings(dstSavings) { michael@0: } michael@0: michael@0: TimeZoneRule::TimeZoneRule(const TimeZoneRule& source) michael@0: : UObject(source), fName(source.fName), fRawOffset(source.fRawOffset), fDSTSavings(source.fDSTSavings) { michael@0: } michael@0: michael@0: TimeZoneRule::~TimeZoneRule() { michael@0: } michael@0: michael@0: TimeZoneRule& michael@0: TimeZoneRule::operator=(const TimeZoneRule& right) { michael@0: if (this != &right) { michael@0: fName = right.fName; michael@0: fRawOffset = right.fRawOffset; michael@0: fDSTSavings = right.fDSTSavings; michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: UBool michael@0: TimeZoneRule::operator==(const TimeZoneRule& that) const { michael@0: return ((this == &that) || michael@0: (typeid(*this) == typeid(that) && michael@0: fName == that.fName && michael@0: fRawOffset == that.fRawOffset && michael@0: fDSTSavings == that.fDSTSavings)); michael@0: } michael@0: michael@0: UBool michael@0: TimeZoneRule::operator!=(const TimeZoneRule& that) const { michael@0: return !operator==(that); michael@0: } michael@0: michael@0: UnicodeString& michael@0: TimeZoneRule::getName(UnicodeString& name) const { michael@0: name = fName; michael@0: return name; michael@0: } michael@0: michael@0: int32_t michael@0: TimeZoneRule::getRawOffset(void) const { michael@0: return fRawOffset; michael@0: } michael@0: michael@0: int32_t michael@0: TimeZoneRule::getDSTSavings(void) const { michael@0: return fDSTSavings; michael@0: } michael@0: michael@0: UBool michael@0: TimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const { michael@0: return ((this == &other) || michael@0: (typeid(*this) == typeid(other) && michael@0: fRawOffset == other.fRawOffset && michael@0: fDSTSavings == other.fDSTSavings)); michael@0: } michael@0: michael@0: michael@0: UOBJECT_DEFINE_RTTI_IMPLEMENTATION(InitialTimeZoneRule) michael@0: michael@0: InitialTimeZoneRule::InitialTimeZoneRule(const UnicodeString& name, michael@0: int32_t rawOffset, michael@0: int32_t dstSavings) michael@0: : TimeZoneRule(name, rawOffset, dstSavings) { michael@0: } michael@0: michael@0: InitialTimeZoneRule::InitialTimeZoneRule(const InitialTimeZoneRule& source) michael@0: : TimeZoneRule(source) { michael@0: } michael@0: michael@0: InitialTimeZoneRule::~InitialTimeZoneRule() { michael@0: } michael@0: michael@0: InitialTimeZoneRule* michael@0: InitialTimeZoneRule::clone(void) const { michael@0: return new InitialTimeZoneRule(*this); michael@0: } michael@0: michael@0: InitialTimeZoneRule& michael@0: InitialTimeZoneRule::operator=(const InitialTimeZoneRule& right) { michael@0: if (this != &right) { michael@0: TimeZoneRule::operator=(right); michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: UBool michael@0: InitialTimeZoneRule::operator==(const TimeZoneRule& that) const { michael@0: return ((this == &that) || michael@0: (typeid(*this) == typeid(that) && michael@0: TimeZoneRule::operator==(that))); michael@0: } michael@0: michael@0: UBool michael@0: InitialTimeZoneRule::operator!=(const TimeZoneRule& that) const { michael@0: return !operator==(that); michael@0: } michael@0: michael@0: UBool michael@0: InitialTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const { michael@0: if (this == &other) { michael@0: return TRUE; michael@0: } michael@0: if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) { michael@0: return FALSE; michael@0: } michael@0: return TRUE; michael@0: } michael@0: michael@0: UBool michael@0: InitialTimeZoneRule::getFirstStart(int32_t /*prevRawOffset*/, michael@0: int32_t /*prevDSTSavings*/, michael@0: UDate& /*result*/) const { michael@0: return FALSE; michael@0: } michael@0: michael@0: UBool michael@0: InitialTimeZoneRule::getFinalStart(int32_t /*prevRawOffset*/, michael@0: int32_t /*prevDSTSavings*/, michael@0: UDate& /*result*/) const { michael@0: return FALSE; michael@0: } michael@0: michael@0: UBool michael@0: InitialTimeZoneRule::getNextStart(UDate /*base*/, michael@0: int32_t /*prevRawOffset*/, michael@0: int32_t /*prevDSTSavings*/, michael@0: UBool /*inclusive*/, michael@0: UDate& /*result*/) const { michael@0: return FALSE; michael@0: } michael@0: michael@0: UBool michael@0: InitialTimeZoneRule::getPreviousStart(UDate /*base*/, michael@0: int32_t /*prevRawOffset*/, michael@0: int32_t /*prevDSTSavings*/, michael@0: UBool /*inclusive*/, michael@0: UDate& /*result*/) const { michael@0: return FALSE; michael@0: } michael@0: michael@0: michael@0: UOBJECT_DEFINE_RTTI_IMPLEMENTATION(AnnualTimeZoneRule) michael@0: michael@0: const int32_t AnnualTimeZoneRule::MAX_YEAR = 0x7FFFFFFF; /* max signed int32 */ michael@0: michael@0: AnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name, michael@0: int32_t rawOffset, michael@0: int32_t dstSavings, michael@0: const DateTimeRule& dateTimeRule, michael@0: int32_t startYear, michael@0: int32_t endYear) michael@0: : TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(new DateTimeRule(dateTimeRule)), michael@0: fStartYear(startYear), fEndYear(endYear) { michael@0: } michael@0: michael@0: AnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name, michael@0: int32_t rawOffset, michael@0: int32_t dstSavings, michael@0: DateTimeRule* dateTimeRule, michael@0: int32_t startYear, michael@0: int32_t endYear) michael@0: : TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(dateTimeRule), michael@0: fStartYear(startYear), fEndYear(endYear) { michael@0: } michael@0: michael@0: AnnualTimeZoneRule::AnnualTimeZoneRule(const AnnualTimeZoneRule& source) michael@0: : TimeZoneRule(source), fDateTimeRule(new DateTimeRule(*(source.fDateTimeRule))), michael@0: fStartYear(source.fStartYear), fEndYear(source.fEndYear) { michael@0: } michael@0: michael@0: AnnualTimeZoneRule::~AnnualTimeZoneRule() { michael@0: delete fDateTimeRule; michael@0: } michael@0: michael@0: AnnualTimeZoneRule* michael@0: AnnualTimeZoneRule::clone(void) const { michael@0: return new AnnualTimeZoneRule(*this); michael@0: } michael@0: michael@0: AnnualTimeZoneRule& michael@0: AnnualTimeZoneRule::operator=(const AnnualTimeZoneRule& right) { michael@0: if (this != &right) { michael@0: TimeZoneRule::operator=(right); michael@0: delete fDateTimeRule; michael@0: fDateTimeRule = right.fDateTimeRule->clone(); michael@0: fStartYear = right.fStartYear; michael@0: fEndYear = right.fEndYear; michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::operator==(const TimeZoneRule& that) const { michael@0: if (this == &that) { michael@0: return TRUE; michael@0: } michael@0: if (typeid(*this) != typeid(that)) { michael@0: return FALSE; michael@0: } michael@0: AnnualTimeZoneRule *atzr = (AnnualTimeZoneRule*)&that; michael@0: return (*fDateTimeRule == *(atzr->fDateTimeRule) && michael@0: fStartYear == atzr->fStartYear && michael@0: fEndYear == atzr->fEndYear); michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::operator!=(const TimeZoneRule& that) const { michael@0: return !operator==(that); michael@0: } michael@0: michael@0: const DateTimeRule* michael@0: AnnualTimeZoneRule::getRule() const { michael@0: return fDateTimeRule; michael@0: } michael@0: michael@0: int32_t michael@0: AnnualTimeZoneRule::getStartYear() const { michael@0: return fStartYear; michael@0: } michael@0: michael@0: int32_t michael@0: AnnualTimeZoneRule::getEndYear() const { michael@0: return fEndYear; michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::getStartInYear(int32_t year, michael@0: int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UDate &result) const { michael@0: if (year < fStartYear || year > fEndYear) { michael@0: return FALSE; michael@0: } michael@0: double ruleDay; michael@0: DateTimeRule::DateRuleType type = fDateTimeRule->getDateRuleType(); michael@0: if (type == DateTimeRule::DOM) { michael@0: ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), fDateTimeRule->getRuleDayOfMonth()); michael@0: } else { michael@0: UBool after = TRUE; michael@0: if (type == DateTimeRule::DOW) { michael@0: // Normalize DOW rule into DOW_GEQ_DOM or DOW_LEQ_DOM michael@0: int32_t weeks = fDateTimeRule->getRuleWeekInMonth(); michael@0: if (weeks > 0) { michael@0: ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), 1); michael@0: ruleDay += 7 * (weeks - 1); michael@0: } else { michael@0: after = FALSE; michael@0: ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), michael@0: Grego::monthLength(year, fDateTimeRule->getRuleMonth())); michael@0: ruleDay += 7 * (weeks + 1); michael@0: } michael@0: } else { michael@0: int32_t month = fDateTimeRule->getRuleMonth(); michael@0: int32_t dom = fDateTimeRule->getRuleDayOfMonth(); michael@0: if (type == DateTimeRule::DOW_LEQ_DOM) { michael@0: after = FALSE; michael@0: // Handle Feb <=29 michael@0: if (month == UCAL_FEBRUARY && dom == 29 && !Grego::isLeapYear(year)) { michael@0: dom--; michael@0: } michael@0: } michael@0: ruleDay = Grego::fieldsToDay(year, month, dom); michael@0: } michael@0: int32_t dow = Grego::dayOfWeek(ruleDay); michael@0: int32_t delta = fDateTimeRule->getRuleDayOfWeek() - dow; michael@0: if (after) { michael@0: delta = delta < 0 ? delta + 7 : delta; michael@0: } else { michael@0: delta = delta > 0 ? delta - 7 : delta; michael@0: } michael@0: ruleDay += delta; michael@0: } michael@0: michael@0: result = ruleDay*U_MILLIS_PER_DAY + fDateTimeRule->getRuleMillisInDay(); michael@0: if (fDateTimeRule->getTimeRuleType() != DateTimeRule::UTC_TIME) { michael@0: result -= prevRawOffset; michael@0: } michael@0: if (fDateTimeRule->getTimeRuleType() == DateTimeRule::WALL_TIME) { michael@0: result -= prevDSTSavings; michael@0: } michael@0: return TRUE; michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const { michael@0: if (this == &other) { michael@0: return TRUE; michael@0: } michael@0: if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) { michael@0: return FALSE; michael@0: } michael@0: AnnualTimeZoneRule* that = (AnnualTimeZoneRule*)&other; michael@0: return (*fDateTimeRule == *(that->fDateTimeRule) && michael@0: fStartYear == that->fStartYear && michael@0: fEndYear == that->fEndYear); michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::getFirstStart(int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UDate& result) const { michael@0: return getStartInYear(fStartYear, prevRawOffset, prevDSTSavings, result); michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::getFinalStart(int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UDate& result) const { michael@0: if (fEndYear == MAX_YEAR) { michael@0: return FALSE; michael@0: } michael@0: return getStartInYear(fEndYear, prevRawOffset, prevDSTSavings, result); michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::getNextStart(UDate base, michael@0: int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UBool inclusive, michael@0: UDate& result) const { michael@0: int32_t year, month, dom, dow, doy, mid; michael@0: Grego::timeToFields(base, year, month, dom, dow, doy, mid); michael@0: if (year < fStartYear) { michael@0: return getFirstStart(prevRawOffset, prevDSTSavings, result); michael@0: } michael@0: UDate tmp; michael@0: if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) { michael@0: if (tmp < base || (!inclusive && (tmp == base))) { michael@0: // Return the next one michael@0: return getStartInYear(year + 1, prevRawOffset, prevDSTSavings, result); michael@0: } else { michael@0: result = tmp; michael@0: return TRUE; michael@0: } michael@0: } michael@0: return FALSE; michael@0: } michael@0: michael@0: UBool michael@0: AnnualTimeZoneRule::getPreviousStart(UDate base, michael@0: int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UBool inclusive, michael@0: UDate& result) const { michael@0: int32_t year, month, dom, dow, doy, mid; michael@0: Grego::timeToFields(base, year, month, dom, dow, doy, mid); michael@0: if (year > fEndYear) { michael@0: return getFinalStart(prevRawOffset, prevDSTSavings, result); michael@0: } michael@0: UDate tmp; michael@0: if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) { michael@0: if (tmp > base || (!inclusive && (tmp == base))) { michael@0: // Return the previous one michael@0: return getStartInYear(year - 1, prevRawOffset, prevDSTSavings, result); michael@0: } else { michael@0: result = tmp; michael@0: return TRUE; michael@0: } michael@0: } michael@0: return FALSE; michael@0: } michael@0: michael@0: UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeArrayTimeZoneRule) michael@0: michael@0: TimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const UnicodeString& name, michael@0: int32_t rawOffset, michael@0: int32_t dstSavings, michael@0: const UDate* startTimes, michael@0: int32_t numStartTimes, michael@0: DateTimeRule::TimeRuleType timeRuleType) michael@0: : TimeZoneRule(name, rawOffset, dstSavings), fTimeRuleType(timeRuleType), michael@0: fStartTimes(NULL) { michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: initStartTimes(startTimes, numStartTimes, status); michael@0: //TODO - status? michael@0: } michael@0: michael@0: michael@0: TimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const TimeArrayTimeZoneRule& source) michael@0: : TimeZoneRule(source), fTimeRuleType(source.fTimeRuleType), fStartTimes(NULL) { michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: initStartTimes(source.fStartTimes, source.fNumStartTimes, status); michael@0: //TODO - status? michael@0: } michael@0: michael@0: michael@0: TimeArrayTimeZoneRule::~TimeArrayTimeZoneRule() { michael@0: if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) { michael@0: uprv_free(fStartTimes); michael@0: } michael@0: } michael@0: michael@0: TimeArrayTimeZoneRule* michael@0: TimeArrayTimeZoneRule::clone(void) const { michael@0: return new TimeArrayTimeZoneRule(*this); michael@0: } michael@0: michael@0: michael@0: TimeArrayTimeZoneRule& michael@0: TimeArrayTimeZoneRule::operator=(const TimeArrayTimeZoneRule& right) { michael@0: if (this != &right) { michael@0: TimeZoneRule::operator=(right); michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: initStartTimes(right.fStartTimes, right.fNumStartTimes, status); michael@0: //TODO - status? michael@0: fTimeRuleType = right.fTimeRuleType; michael@0: } michael@0: return *this; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::operator==(const TimeZoneRule& that) const { michael@0: if (this == &that) { michael@0: return TRUE; michael@0: } michael@0: if (typeid(*this) != typeid(that) || TimeZoneRule::operator==(that) == FALSE) { michael@0: return FALSE; michael@0: } michael@0: TimeArrayTimeZoneRule *tatzr = (TimeArrayTimeZoneRule*)&that; michael@0: if (fTimeRuleType != tatzr->fTimeRuleType || michael@0: fNumStartTimes != tatzr->fNumStartTimes) { michael@0: return FALSE; michael@0: } michael@0: // Compare start times michael@0: UBool res = TRUE; michael@0: for (int32_t i = 0; i < fNumStartTimes; i++) { michael@0: if (fStartTimes[i] != tatzr->fStartTimes[i]) { michael@0: res = FALSE; michael@0: break; michael@0: } michael@0: } michael@0: return res; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::operator!=(const TimeZoneRule& that) const { michael@0: return !operator==(that); michael@0: } michael@0: michael@0: DateTimeRule::TimeRuleType michael@0: TimeArrayTimeZoneRule::getTimeType(void) const { michael@0: return fTimeRuleType; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::getStartTimeAt(int32_t index, UDate& result) const { michael@0: if (index >= fNumStartTimes || index < 0) { michael@0: return FALSE; michael@0: } michael@0: result = fStartTimes[index]; michael@0: return TRUE; michael@0: } michael@0: michael@0: int32_t michael@0: TimeArrayTimeZoneRule::countStartTimes(void) const { michael@0: return fNumStartTimes; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const { michael@0: if (this == &other) { michael@0: return TRUE; michael@0: } michael@0: if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) { michael@0: return FALSE; michael@0: } michael@0: TimeArrayTimeZoneRule* that = (TimeArrayTimeZoneRule*)&other; michael@0: if (fTimeRuleType != that->fTimeRuleType || michael@0: fNumStartTimes != that->fNumStartTimes) { michael@0: return FALSE; michael@0: } michael@0: // Compare start times michael@0: UBool res = TRUE; michael@0: for (int32_t i = 0; i < fNumStartTimes; i++) { michael@0: if (fStartTimes[i] != that->fStartTimes[i]) { michael@0: res = FALSE; michael@0: break; michael@0: } michael@0: } michael@0: return res; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::getFirstStart(int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UDate& result) const { michael@0: if (fNumStartTimes <= 0 || fStartTimes == NULL) { michael@0: return FALSE; michael@0: } michael@0: result = getUTC(fStartTimes[0], prevRawOffset, prevDSTSavings); michael@0: return TRUE; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::getFinalStart(int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UDate& result) const { michael@0: if (fNumStartTimes <= 0 || fStartTimes == NULL) { michael@0: return FALSE; michael@0: } michael@0: result = getUTC(fStartTimes[fNumStartTimes - 1], prevRawOffset, prevDSTSavings); michael@0: return TRUE; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::getNextStart(UDate base, michael@0: int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UBool inclusive, michael@0: UDate& result) const { michael@0: int32_t i = fNumStartTimes - 1; michael@0: for (; i >= 0; i--) { michael@0: UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings); michael@0: if (time < base || (!inclusive && time == base)) { michael@0: break; michael@0: } michael@0: result = time; michael@0: } michael@0: if (i == fNumStartTimes - 1) { michael@0: return FALSE; michael@0: } michael@0: return TRUE; michael@0: } michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::getPreviousStart(UDate base, michael@0: int32_t prevRawOffset, michael@0: int32_t prevDSTSavings, michael@0: UBool inclusive, michael@0: UDate& result) const { michael@0: int32_t i = fNumStartTimes - 1; michael@0: for (; i >= 0; i--) { michael@0: UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings); michael@0: if (time < base || (inclusive && time == base)) { michael@0: result = time; michael@0: return TRUE; michael@0: } michael@0: } michael@0: return FALSE; michael@0: } michael@0: michael@0: michael@0: // ---- private methods ------ michael@0: michael@0: UBool michael@0: TimeArrayTimeZoneRule::initStartTimes(const UDate source[], int32_t size, UErrorCode& status) { michael@0: // Free old array michael@0: if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) { michael@0: uprv_free(fStartTimes); michael@0: } michael@0: // Allocate new one if needed michael@0: if (size > TIMEARRAY_STACK_BUFFER_SIZE) { michael@0: fStartTimes = (UDate*)uprv_malloc(sizeof(UDate)*size); michael@0: if (fStartTimes == NULL) { michael@0: status = U_MEMORY_ALLOCATION_ERROR; michael@0: fNumStartTimes = 0; michael@0: return FALSE; michael@0: } michael@0: } else { michael@0: fStartTimes = (UDate*)fLocalStartTimes; michael@0: } michael@0: uprv_memcpy(fStartTimes, source, sizeof(UDate)*size); michael@0: fNumStartTimes = size; michael@0: // Sort dates michael@0: uprv_sortArray(fStartTimes, fNumStartTimes, (int32_t)sizeof(UDate), compareDates, NULL, TRUE, &status); michael@0: if (U_FAILURE(status)) { michael@0: if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) { michael@0: uprv_free(fStartTimes); michael@0: } michael@0: fNumStartTimes = 0; michael@0: return FALSE; michael@0: } michael@0: return TRUE; michael@0: } michael@0: michael@0: UDate michael@0: TimeArrayTimeZoneRule::getUTC(UDate time, int32_t raw, int32_t dst) const { michael@0: if (fTimeRuleType != DateTimeRule::UTC_TIME) { michael@0: time -= raw; michael@0: } michael@0: if (fTimeRuleType == DateTimeRule::WALL_TIME) { michael@0: time -= dst; michael@0: } michael@0: return time; michael@0: } michael@0: michael@0: U_NAMESPACE_END michael@0: michael@0: #endif /* #if !UCONFIG_NO_FORMATTING */ michael@0: michael@0: //eof michael@0: