summaryrefslogtreecommitdiff
path: root/deps/node/deps/icu-small/source/i18n/rbtz.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/node/deps/icu-small/source/i18n/rbtz.cpp')
-rw-r--r--deps/node/deps/icu-small/source/i18n/rbtz.cpp958
1 files changed, 0 insertions, 958 deletions
diff --git a/deps/node/deps/icu-small/source/i18n/rbtz.cpp b/deps/node/deps/icu-small/source/i18n/rbtz.cpp
deleted file mode 100644
index 951073ab..00000000
--- a/deps/node/deps/icu-small/source/i18n/rbtz.cpp
+++ /dev/null
@@ -1,958 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-*******************************************************************************
-* Copyright (C) 2007-2013, International Business Machines Corporation and
-* others. All Rights Reserved.
-*******************************************************************************
-*/
-
-#include "utypeinfo.h" // for 'typeid' to work
-
-#include "unicode/utypes.h"
-
-#if !UCONFIG_NO_FORMATTING
-
-#include "unicode/rbtz.h"
-#include "unicode/gregocal.h"
-#include "uvector.h"
-#include "gregoimp.h"
-#include "cmemory.h"
-#include "umutex.h"
-
-U_NAMESPACE_BEGIN
-
-/**
- * A struct representing a time zone transition
- */
-struct Transition {
- UDate time;
- TimeZoneRule* from;
- TimeZoneRule* to;
-};
-
-static UBool compareRules(UVector* rules1, UVector* rules2) {
- if (rules1 == NULL && rules2 == NULL) {
- return TRUE;
- } else if (rules1 == NULL || rules2 == NULL) {
- return FALSE;
- }
- int32_t size = rules1->size();
- if (size != rules2->size()) {
- return FALSE;
- }
- for (int32_t i = 0; i < size; i++) {
- TimeZoneRule *r1 = (TimeZoneRule*)rules1->elementAt(i);
- TimeZoneRule *r2 = (TimeZoneRule*)rules2->elementAt(i);
- if (*r1 != *r2) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedTimeZone)
-
-RuleBasedTimeZone::RuleBasedTimeZone(const UnicodeString& id, InitialTimeZoneRule* initialRule)
-: BasicTimeZone(id), fInitialRule(initialRule), fHistoricRules(NULL), fFinalRules(NULL),
- fHistoricTransitions(NULL), fUpToDate(FALSE) {
-}
-
-RuleBasedTimeZone::RuleBasedTimeZone(const RuleBasedTimeZone& source)
-: BasicTimeZone(source), fInitialRule(source.fInitialRule->clone()),
- fHistoricTransitions(NULL), fUpToDate(FALSE) {
- fHistoricRules = copyRules(source.fHistoricRules);
- fFinalRules = copyRules(source.fFinalRules);
- if (source.fUpToDate) {
- UErrorCode status = U_ZERO_ERROR;
- complete(status);
- }
-}
-
-RuleBasedTimeZone::~RuleBasedTimeZone() {
- deleteTransitions();
- deleteRules();
-}
-
-RuleBasedTimeZone&
-RuleBasedTimeZone::operator=(const RuleBasedTimeZone& right) {
- if (*this != right) {
- BasicTimeZone::operator=(right);
- deleteRules();
- fInitialRule = right.fInitialRule->clone();
- fHistoricRules = copyRules(right.fHistoricRules);
- fFinalRules = copyRules(right.fFinalRules);
- deleteTransitions();
- fUpToDate = FALSE;
- }
- return *this;
-}
-
-UBool
-RuleBasedTimeZone::operator==(const TimeZone& that) const {
- if (this == &that) {
- return TRUE;
- }
- if (typeid(*this) != typeid(that)
- || BasicTimeZone::operator==(that) == FALSE) {
- return FALSE;
- }
- RuleBasedTimeZone *rbtz = (RuleBasedTimeZone*)&that;
- if (*fInitialRule != *(rbtz->fInitialRule)) {
- return FALSE;
- }
- if (compareRules(fHistoricRules, rbtz->fHistoricRules)
- && compareRules(fFinalRules, rbtz->fFinalRules)) {
- return TRUE;
- }
- return FALSE;
-}
-
-UBool
-RuleBasedTimeZone::operator!=(const TimeZone& that) const {
- return !operator==(that);
-}
-
-void
-RuleBasedTimeZone::addTransitionRule(TimeZoneRule* rule, UErrorCode& status) {
- if (U_FAILURE(status)) {
- return;
- }
- AnnualTimeZoneRule* atzrule = dynamic_cast<AnnualTimeZoneRule*>(rule);
- if (atzrule != NULL && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
- // A final rule
- if (fFinalRules == NULL) {
- fFinalRules = new UVector(status);
- if (U_FAILURE(status)) {
- return;
- }
- } else if (fFinalRules->size() >= 2) {
- // Cannot handle more than two final rules
- status = U_INVALID_STATE_ERROR;
- return;
- }
- fFinalRules->addElement((void*)rule, status);
- } else {
- // Non-final rule
- if (fHistoricRules == NULL) {
- fHistoricRules = new UVector(status);
- if (U_FAILURE(status)) {
- return;
- }
- }
- fHistoricRules->addElement((void*)rule, status);
- }
- // Mark dirty, so transitions are recalculated at next complete() call
- fUpToDate = FALSE;
-}
-
-static UMutex gLock = U_MUTEX_INITIALIZER;
-
-void
-RuleBasedTimeZone::completeConst(UErrorCode& status) const {
- if (U_FAILURE(status)) {
- return;
- }
- umtx_lock(&gLock);
- if (!fUpToDate) {
- RuleBasedTimeZone *ncThis = const_cast<RuleBasedTimeZone*>(this);
- ncThis->complete(status);
- }
- umtx_unlock(&gLock);
-}
-
-void
-RuleBasedTimeZone::complete(UErrorCode& status) {
- if (U_FAILURE(status)) {
- return;
- }
- if (fUpToDate) {
- return;
- }
- // Make sure either no final rules or a pair of AnnualTimeZoneRules
- // are available.
- if (fFinalRules != NULL && fFinalRules->size() != 2) {
- status = U_INVALID_STATE_ERROR;
- return;
- }
-
- UBool *done = NULL;
- // Create a TimezoneTransition and add to the list
- if (fHistoricRules != NULL || fFinalRules != NULL) {
- TimeZoneRule *curRule = fInitialRule;
- UDate lastTransitionTime = MIN_MILLIS;
-
- // Build the transition array which represents historical time zone
- // transitions.
- if (fHistoricRules != NULL && fHistoricRules->size() > 0) {
- int32_t i;
- int32_t historicCount = fHistoricRules->size();
- done = (UBool*)uprv_malloc(sizeof(UBool) * historicCount);
- if (done == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanup;
- }
- for (i = 0; i < historicCount; i++) {
- done[i] = FALSE;
- }
- while (TRUE) {
- int32_t curStdOffset = curRule->getRawOffset();
- int32_t curDstSavings = curRule->getDSTSavings();
- UDate nextTransitionTime = MAX_MILLIS;
- TimeZoneRule *nextRule = NULL;
- TimeZoneRule *r = NULL;
- UBool avail;
- UDate tt;
- UnicodeString curName, name;
- curRule->getName(curName);
-
- for (i = 0; i < historicCount; i++) {
- if (done[i]) {
- continue;
- }
- r = (TimeZoneRule*)fHistoricRules->elementAt(i);
- avail = r->getNextStart(lastTransitionTime, curStdOffset, curDstSavings, false, tt);
- if (!avail) {
- // No more transitions from this rule - skip this rule next time
- done[i] = TRUE;
- } else {
- r->getName(name);
- if (*r == *curRule ||
- (name == curName && r->getRawOffset() == curRule->getRawOffset()
- && r->getDSTSavings() == curRule->getDSTSavings())) {
- continue;
- }
- if (tt < nextTransitionTime) {
- nextTransitionTime = tt;
- nextRule = r;
- }
- }
- }
-
- if (nextRule == NULL) {
- // Check if all historic rules are done
- UBool bDoneAll = TRUE;
- for (int32_t j = 0; j < historicCount; j++) {
- if (!done[j]) {
- bDoneAll = FALSE;
- break;
- }
- }
- if (bDoneAll) {
- break;
- }
- }
-
- if (fFinalRules != NULL) {
- // Check if one of final rules has earlier transition date
- for (i = 0; i < 2 /* fFinalRules->size() */; i++) {
- TimeZoneRule *fr = (TimeZoneRule*)fFinalRules->elementAt(i);
- if (*fr == *curRule) {
- continue;
- }
- r = (TimeZoneRule*)fFinalRules->elementAt(i);
- avail = r->getNextStart(lastTransitionTime, curStdOffset, curDstSavings, false, tt);
- if (avail) {
- if (tt < nextTransitionTime) {
- nextTransitionTime = tt;
- nextRule = r;
- }
- }
- }
- }
-
- if (nextRule == NULL) {
- // Nothing more
- break;
- }
-
- if (fHistoricTransitions == NULL) {
- fHistoricTransitions = new UVector(status);
- if (U_FAILURE(status)) {
- goto cleanup;
- }
- }
- Transition *trst = (Transition*)uprv_malloc(sizeof(Transition));
- if (trst == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanup;
- }
- trst->time = nextTransitionTime;
- trst->from = curRule;
- trst->to = nextRule;
- fHistoricTransitions->addElement(trst, status);
- if (U_FAILURE(status)) {
- goto cleanup;
- }
- lastTransitionTime = nextTransitionTime;
- curRule = nextRule;
- }
- }
- if (fFinalRules != NULL) {
- if (fHistoricTransitions == NULL) {
- fHistoricTransitions = new UVector(status);
- if (U_FAILURE(status)) {
- goto cleanup;
- }
- }
- // Append the first transition for each
- TimeZoneRule *rule0 = (TimeZoneRule*)fFinalRules->elementAt(0);
- TimeZoneRule *rule1 = (TimeZoneRule*)fFinalRules->elementAt(1);
- UDate tt0, tt1;
- UBool avail0 = rule0->getNextStart(lastTransitionTime, curRule->getRawOffset(), curRule->getDSTSavings(), false, tt0);
- UBool avail1 = rule1->getNextStart(lastTransitionTime, curRule->getRawOffset(), curRule->getDSTSavings(), false, tt1);
- if (!avail0 || !avail1) {
- // Should not happen, because both rules are permanent
- status = U_INVALID_STATE_ERROR;
- goto cleanup;
- }
- Transition *final0 = (Transition*)uprv_malloc(sizeof(Transition));
- if (final0 == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanup;
- }
- Transition *final1 = (Transition*)uprv_malloc(sizeof(Transition));
- if (final1 == NULL) {
- uprv_free(final0);
- status = U_MEMORY_ALLOCATION_ERROR;
- goto cleanup;
- }
- if (tt0 < tt1) {
- final0->time = tt0;
- final0->from = curRule;
- final0->to = rule0;
- rule1->getNextStart(tt0, rule0->getRawOffset(), rule0->getDSTSavings(), false, final1->time);
- final1->from = rule0;
- final1->to = rule1;
- } else {
- final0->time = tt1;
- final0->from = curRule;
- final0->to = rule1;
- rule0->getNextStart(tt1, rule1->getRawOffset(), rule1->getDSTSavings(), false, final1->time);
- final1->from = rule1;
- final1->to = rule0;
- }
- fHistoricTransitions->addElement(final0, status);
- if (U_FAILURE(status)) {
- goto cleanup;
- }
- fHistoricTransitions->addElement(final1, status);
- if (U_FAILURE(status)) {
- goto cleanup;
- }
- }
- }
- fUpToDate = TRUE;
- if (done != NULL) {
- uprv_free(done);
- }
- return;
-
-cleanup:
- deleteTransitions();
- if (done != NULL) {
- uprv_free(done);
- }
- fUpToDate = FALSE;
-}
-
-TimeZone*
-RuleBasedTimeZone::clone(void) const {
- return new RuleBasedTimeZone(*this);
-}
-
-int32_t
-RuleBasedTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
- uint8_t dayOfWeek, int32_t millis, UErrorCode& status) const {
- if (U_FAILURE(status)) {
- return 0;
- }
- if (month < UCAL_JANUARY || month > UCAL_DECEMBER) {
- status = U_ILLEGAL_ARGUMENT_ERROR;
- return 0;
- } else {
- return getOffset(era, year, month, day, dayOfWeek, millis,
- Grego::monthLength(year, month), status);
- }
-}
-
-int32_t
-RuleBasedTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
- uint8_t /*dayOfWeek*/, int32_t millis,
- int32_t /*monthLength*/, UErrorCode& status) const {
- // dayOfWeek and monthLength are unused
- if (U_FAILURE(status)) {
- return 0;
- }
- if (era == GregorianCalendar::BC) {
- // Convert to extended year
- year = 1 - year;
- }
- int32_t rawOffset, dstOffset;
- UDate time = (UDate)Grego::fieldsToDay(year, month, day) * U_MILLIS_PER_DAY + millis;
- getOffsetInternal(time, TRUE, kDaylight, kStandard, rawOffset, dstOffset, status);
- if (U_FAILURE(status)) {
- return 0;
- }
- return (rawOffset + dstOffset);
-}
-
-void
-RuleBasedTimeZone::getOffset(UDate date, UBool local, int32_t& rawOffset,
- int32_t& dstOffset, UErrorCode& status) const {
- getOffsetInternal(date, local, kFormer, kLatter, rawOffset, dstOffset, status);
-}
-
-void
-RuleBasedTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
- int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) const {
- getOffsetInternal(date, TRUE, nonExistingTimeOpt, duplicatedTimeOpt, rawOffset, dstOffset, status);
-}
-
-
-/*
- * The internal getOffset implementation
- */
-void
-RuleBasedTimeZone::getOffsetInternal(UDate date, UBool local,
- int32_t NonExistingTimeOpt, int32_t DuplicatedTimeOpt,
- int32_t& rawOffset, int32_t& dstOffset,
- UErrorCode& status) const {
- rawOffset = 0;
- dstOffset = 0;
-
- if (U_FAILURE(status)) {
- return;
- }
- if (!fUpToDate) {
- // Transitions are not yet resolved. We cannot do it here
- // because this method is const. Thus, do nothing and return
- // error status.
- status = U_INVALID_STATE_ERROR;
- return;
- }
- const TimeZoneRule *rule = NULL;
- if (fHistoricTransitions == NULL) {
- rule = fInitialRule;
- } else {
- UDate tstart = getTransitionTime((Transition*)fHistoricTransitions->elementAt(0),
- local, NonExistingTimeOpt, DuplicatedTimeOpt);
- if (date < tstart) {
- rule = fInitialRule;
- } else {
- int32_t idx = fHistoricTransitions->size() - 1;
- UDate tend = getTransitionTime((Transition*)fHistoricTransitions->elementAt(idx),
- local, NonExistingTimeOpt, DuplicatedTimeOpt);
- if (date > tend) {
- if (fFinalRules != NULL) {
- rule = findRuleInFinal(date, local, NonExistingTimeOpt, DuplicatedTimeOpt);
- }
- if (rule == NULL) {
- // no final rules or the given time is before the first transition
- // specified by the final rules -> use the last rule
- rule = ((Transition*)fHistoricTransitions->elementAt(idx))->to;
- }
- } else {
- // Find a historical transition
- while (idx >= 0) {
- if (date >= getTransitionTime((Transition*)fHistoricTransitions->elementAt(idx),
- local, NonExistingTimeOpt, DuplicatedTimeOpt)) {
- break;
- }
- idx--;
- }
- rule = ((Transition*)fHistoricTransitions->elementAt(idx))->to;
- }
- }
- }
- if (rule != NULL) {
- rawOffset = rule->getRawOffset();
- dstOffset = rule->getDSTSavings();
- }
-}
-
-void
-RuleBasedTimeZone::setRawOffset(int32_t /*offsetMillis*/) {
- // We don't support this operation at this moment.
- // Nothing to do!
-}
-
-int32_t
-RuleBasedTimeZone::getRawOffset(void) const {
- // Note: This implementation returns standard GMT offset
- // as of current time.
- UErrorCode status = U_ZERO_ERROR;
- int32_t raw, dst;
- getOffset(uprv_getUTCtime() * U_MILLIS_PER_SECOND,
- FALSE, raw, dst, status);
- return raw;
-}
-
-UBool
-RuleBasedTimeZone::useDaylightTime(void) const {
- // Note: This implementation returns true when
- // daylight saving time is used as of now or
- // after the next transition.
- UErrorCode status = U_ZERO_ERROR;
- UDate now = uprv_getUTCtime() * U_MILLIS_PER_SECOND;
- int32_t raw, dst;
- getOffset(now, FALSE, raw, dst, status);
- if (dst != 0) {
- return TRUE;
- }
- // If DST is not used now, check if DST is used after the next transition
- UDate time;
- TimeZoneRule *from, *to;
- UBool avail = findNext(now, FALSE, time, from, to);
- if (avail && to->getDSTSavings() != 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-UBool
-RuleBasedTimeZone::inDaylightTime(UDate date, UErrorCode& status) const {
- if (U_FAILURE(status)) {
- return FALSE;
- }
- int32_t raw, dst;
- getOffset(date, FALSE, raw, dst, status);
- if (dst != 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-UBool
-RuleBasedTimeZone::hasSameRules(const TimeZone& other) const {
- if (this == &other) {
- return TRUE;
- }
- if (typeid(*this) != typeid(other)) {
- return FALSE;
- }
- const RuleBasedTimeZone& that = (const RuleBasedTimeZone&)other;
- if (*fInitialRule != *(that.fInitialRule)) {
- return FALSE;
- }
- if (compareRules(fHistoricRules, that.fHistoricRules)
- && compareRules(fFinalRules, that.fFinalRules)) {
- return TRUE;
- }
- return FALSE;
-}
-
-UBool
-RuleBasedTimeZone::getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const {
- UErrorCode status = U_ZERO_ERROR;
- completeConst(status);
- if (U_FAILURE(status)) {
- return FALSE;
- }
- UDate transitionTime;
- TimeZoneRule *fromRule, *toRule;
- UBool found = findNext(base, inclusive, transitionTime, fromRule, toRule);
- if (found) {
- result.setTime(transitionTime);
- result.setFrom((const TimeZoneRule&)*fromRule);
- result.setTo((const TimeZoneRule&)*toRule);
- return TRUE;
- }
- return FALSE;
-}
-
-UBool
-RuleBasedTimeZone::getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const {
- UErrorCode status = U_ZERO_ERROR;
- completeConst(status);
- if (U_FAILURE(status)) {
- return FALSE;
- }
- UDate transitionTime;
- TimeZoneRule *fromRule, *toRule;
- UBool found = findPrev(base, inclusive, transitionTime, fromRule, toRule);
- if (found) {
- result.setTime(transitionTime);
- result.setFrom((const TimeZoneRule&)*fromRule);
- result.setTo((const TimeZoneRule&)*toRule);
- return TRUE;
- }
- return FALSE;
-}
-
-int32_t
-RuleBasedTimeZone::countTransitionRules(UErrorCode& /*status*/) const {
- int32_t count = 0;
- if (fHistoricRules != NULL) {
- count += fHistoricRules->size();
- }
- if (fFinalRules != NULL) {
- count += fFinalRules->size();
- }
- return count;
-}
-
-void
-RuleBasedTimeZone::getTimeZoneRules(const InitialTimeZoneRule*& initial,
- const TimeZoneRule* trsrules[],
- int32_t& trscount,
- UErrorCode& status) const {
- if (U_FAILURE(status)) {
- return;
- }
- // Initial rule
- initial = fInitialRule;
-
- // Transition rules
- int32_t cnt = 0;
- int32_t idx;
- if (fHistoricRules != NULL && cnt < trscount) {
- int32_t historicCount = fHistoricRules->size();
- idx = 0;
- while (cnt < trscount && idx < historicCount) {
- trsrules[cnt++] = (const TimeZoneRule*)fHistoricRules->elementAt(idx++);
- }
- }
- if (fFinalRules != NULL && cnt < trscount) {
- int32_t finalCount = fFinalRules->size();
- idx = 0;
- while (cnt < trscount && idx < finalCount) {
- trsrules[cnt++] = (const TimeZoneRule*)fFinalRules->elementAt(idx++);
- }
- }
- // Set the result length
- trscount = cnt;
-}
-
-void
-RuleBasedTimeZone::deleteRules(void) {
- delete fInitialRule;
- fInitialRule = NULL;
- if (fHistoricRules != NULL) {
- while (!fHistoricRules->isEmpty()) {
- delete (TimeZoneRule*)(fHistoricRules->orphanElementAt(0));
- }
- delete fHistoricRules;
- fHistoricRules = NULL;
- }
- if (fFinalRules != NULL) {
- while (!fFinalRules->isEmpty()) {
- delete (AnnualTimeZoneRule*)(fFinalRules->orphanElementAt(0));
- }
- delete fFinalRules;
- fFinalRules = NULL;
- }
-}
-
-void
-RuleBasedTimeZone::deleteTransitions(void) {
- if (fHistoricTransitions != NULL) {
- while (!fHistoricTransitions->isEmpty()) {
- Transition *trs = (Transition*)fHistoricTransitions->orphanElementAt(0);
- uprv_free(trs);
- }
- delete fHistoricTransitions;
- }
- fHistoricTransitions = NULL;
-}
-
-UVector*
-RuleBasedTimeZone::copyRules(UVector* source) {
- if (source == NULL) {
- return NULL;
- }
- UErrorCode ec = U_ZERO_ERROR;
- int32_t size = source->size();
- UVector *rules = new UVector(size, ec);
- if (U_FAILURE(ec)) {
- return NULL;
- }
- int32_t i;
- for (i = 0; i < size; i++) {
- rules->addElement(((TimeZoneRule*)source->elementAt(i))->clone(), ec);
- if (U_FAILURE(ec)) {
- break;
- }
- }
- if (U_FAILURE(ec)) {
- // In case of error, clean up
- for (i = 0; i < rules->size(); i++) {
- TimeZoneRule *rule = (TimeZoneRule*)rules->orphanElementAt(i);
- delete rule;
- }
- delete rules;
- return NULL;
- }
- return rules;
-}
-
-TimeZoneRule*
-RuleBasedTimeZone::findRuleInFinal(UDate date, UBool local,
- int32_t NonExistingTimeOpt, int32_t DuplicatedTimeOpt) const {
- if (fFinalRules == NULL) {
- return NULL;
- }
-
- AnnualTimeZoneRule* fr0 = (AnnualTimeZoneRule*)fFinalRules->elementAt(0);
- AnnualTimeZoneRule* fr1 = (AnnualTimeZoneRule*)fFinalRules->elementAt(1);
- if (fr0 == NULL || fr1 == NULL) {
- return NULL;
- }
-
- UDate start0, start1;
- UDate base;
- int32_t localDelta;
-
- base = date;
- if (local) {
- localDelta = getLocalDelta(fr1->getRawOffset(), fr1->getDSTSavings(),
- fr0->getRawOffset(), fr0->getDSTSavings(),
- NonExistingTimeOpt, DuplicatedTimeOpt);
- base -= localDelta;
- }
- UBool avail0 = fr0->getPreviousStart(base, fr1->getRawOffset(), fr1->getDSTSavings(), TRUE, start0);
-
- base = date;
- if (local) {
- localDelta = getLocalDelta(fr0->getRawOffset(), fr0->getDSTSavings(),
- fr1->getRawOffset(), fr1->getDSTSavings(),
- NonExistingTimeOpt, DuplicatedTimeOpt);
- base -= localDelta;
- }
- UBool avail1 = fr1->getPreviousStart(base, fr0->getRawOffset(), fr0->getDSTSavings(), TRUE, start1);
-
- if (!avail0 || !avail1) {
- if (avail0) {
- return fr0;
- } else if (avail1) {
- return fr1;
- }
- // Both rules take effect after the given time
- return NULL;
- }
-
- return (start0 > start1) ? fr0 : fr1;
-}
-
-UBool
-RuleBasedTimeZone::findNext(UDate base, UBool inclusive, UDate& transitionTime,
- TimeZoneRule*& fromRule, TimeZoneRule*& toRule) const {
- if (fHistoricTransitions == NULL) {
- return FALSE;
- }
- UBool isFinal = FALSE;
- UBool found = FALSE;
- Transition result;
- Transition *tzt = (Transition*)fHistoricTransitions->elementAt(0);
- UDate tt = tzt->time;
- if (tt > base || (inclusive && tt == base)) {
- result = *tzt;
- found = TRUE;
- } else {
- int32_t idx = fHistoricTransitions->size() - 1;
- tzt = (Transition*)fHistoricTransitions->elementAt(idx);
- tt = tzt->time;
- if (inclusive && tt == base) {
- result = *tzt;
- found = TRUE;
- } else if (tt <= base) {
- if (fFinalRules != NULL) {
- // Find a transion time with finalRules
- TimeZoneRule *r0 = (TimeZoneRule*)fFinalRules->elementAt(0);
- TimeZoneRule *r1 = (TimeZoneRule*)fFinalRules->elementAt(1);
- UDate start0, start1;
- UBool avail0 = r0->getNextStart(base, r1->getRawOffset(), r1->getDSTSavings(), inclusive, start0);
- UBool avail1 = r1->getNextStart(base, r0->getRawOffset(), r0->getDSTSavings(), inclusive, start1);
- // avail0/avail1 should be always TRUE
- if (!avail0 && !avail1) {
- return FALSE;
- }
- if (!avail1 || start0 < start1) {
- result.time = start0;
- result.from = r1;
- result.to = r0;
- } else {
- result.time = start1;
- result.from = r0;
- result.to = r1;
- }
- isFinal = TRUE;
- found = TRUE;
- }
- } else {
- // Find a transition within the historic transitions
- idx--;
- Transition *prev = tzt;
- while (idx > 0) {
- tzt = (Transition*)fHistoricTransitions->elementAt(idx);
- tt = tzt->time;
- if (tt < base || (!inclusive && tt == base)) {
- break;
- }
- idx--;
- prev = tzt;
- }
- result.time = prev->time;
- result.from = prev->from;
- result.to = prev->to;
- found = TRUE;
- }
- }
- if (found) {
- // For now, this implementation ignore transitions with only zone name changes.
- if (result.from->getRawOffset() == result.to->getRawOffset()
- && result.from->getDSTSavings() == result.to->getDSTSavings()) {
- if (isFinal) {
- return FALSE;
- } else {
- // No offset changes. Try next one if not final
- return findNext(result.time, FALSE /* always exclusive */,
- transitionTime, fromRule, toRule);
- }
- }
- transitionTime = result.time;
- fromRule = result.from;
- toRule = result.to;
- return TRUE;
- }
- return FALSE;
-}
-
-UBool
-RuleBasedTimeZone::findPrev(UDate base, UBool inclusive, UDate& transitionTime,
- TimeZoneRule*& fromRule, TimeZoneRule*& toRule) const {
- if (fHistoricTransitions == NULL) {
- return FALSE;
- }
- UBool found = FALSE;
- Transition result;
- Transition *tzt = (Transition*)fHistoricTransitions->elementAt(0);
- UDate tt = tzt->time;
- if (inclusive && tt == base) {
- result = *tzt;
- found = TRUE;
- } else if (tt < base) {
- int32_t idx = fHistoricTransitions->size() - 1;
- tzt = (Transition*)fHistoricTransitions->elementAt(idx);
- tt = tzt->time;
- if (inclusive && tt == base) {
- result = *tzt;
- found = TRUE;
- } else if (tt < base) {
- if (fFinalRules != NULL) {
- // Find a transion time with finalRules
- TimeZoneRule *r0 = (TimeZoneRule*)fFinalRules->elementAt(0);
- TimeZoneRule *r1 = (TimeZoneRule*)fFinalRules->elementAt(1);
- UDate start0, start1;
- UBool avail0 = r0->getPreviousStart(base, r1->getRawOffset(), r1->getDSTSavings(), inclusive, start0);
- UBool avail1 = r1->getPreviousStart(base, r0->getRawOffset(), r0->getDSTSavings(), inclusive, start1);
- // avail0/avail1 should be always TRUE
- if (!avail0 && !avail1) {
- return FALSE;
- }
- if (!avail1 || start0 > start1) {
- result.time = start0;
- result.from = r1;
- result.to = r0;
- } else {
- result.time = start1;
- result.from = r0;
- result.to = r1;
- }
- } else {
- result = *tzt;
- }
- found = TRUE;
- } else {
- // Find a transition within the historic transitions
- idx--;
- while (idx >= 0) {
- tzt = (Transition*)fHistoricTransitions->elementAt(idx);
- tt = tzt->time;
- if (tt < base || (inclusive && tt == base)) {
- break;
- }
- idx--;
- }
- result = *tzt;
- found = TRUE;
- }
- }
- if (found) {
- // For now, this implementation ignore transitions with only zone name changes.
- if (result.from->getRawOffset() == result.to->getRawOffset()
- && result.from->getDSTSavings() == result.to->getDSTSavings()) {
- // No offset changes. Try next one if not final
- return findPrev(result.time, FALSE /* always exclusive */,
- transitionTime, fromRule, toRule);
- }
- transitionTime = result.time;
- fromRule = result.from;
- toRule = result.to;
- return TRUE;
- }
- return FALSE;
-}
-
-UDate
-RuleBasedTimeZone::getTransitionTime(Transition* transition, UBool local,
- int32_t NonExistingTimeOpt, int32_t DuplicatedTimeOpt) const {
- UDate time = transition->time;
- if (local) {
- time += getLocalDelta(transition->from->getRawOffset(), transition->from->getDSTSavings(),
- transition->to->getRawOffset(), transition->to->getDSTSavings(),
- NonExistingTimeOpt, DuplicatedTimeOpt);
- }
- return time;
-}
-
-int32_t
-RuleBasedTimeZone::getLocalDelta(int32_t rawBefore, int32_t dstBefore, int32_t rawAfter, int32_t dstAfter,
- int32_t NonExistingTimeOpt, int32_t DuplicatedTimeOpt) const {
- int32_t delta = 0;
-
- int32_t offsetBefore = rawBefore + dstBefore;
- int32_t offsetAfter = rawAfter + dstAfter;
-
- UBool dstToStd = (dstBefore != 0) && (dstAfter == 0);
- UBool stdToDst = (dstBefore == 0) && (dstAfter != 0);
-
- if (offsetAfter - offsetBefore >= 0) {
- // Positive transition, which makes a non-existing local time range
- if (((NonExistingTimeOpt & kStdDstMask) == kStandard && dstToStd)
- || ((NonExistingTimeOpt & kStdDstMask) == kDaylight && stdToDst)) {
- delta = offsetBefore;
- } else if (((NonExistingTimeOpt & kStdDstMask) == kStandard && stdToDst)
- || ((NonExistingTimeOpt & kStdDstMask) == kDaylight && dstToStd)) {
- delta = offsetAfter;
- } else if ((NonExistingTimeOpt & kFormerLatterMask) == kLatter) {
- delta = offsetBefore;
- } else {
- // Interprets the time with rule before the transition,
- // default for non-existing time range
- delta = offsetAfter;
- }
- } else {
- // Negative transition, which makes a duplicated local time range
- if (((DuplicatedTimeOpt & kStdDstMask) == kStandard && dstToStd)
- || ((DuplicatedTimeOpt & kStdDstMask) == kDaylight && stdToDst)) {
- delta = offsetAfter;
- } else if (((DuplicatedTimeOpt & kStdDstMask) == kStandard && stdToDst)
- || ((DuplicatedTimeOpt & kStdDstMask) == kDaylight && dstToStd)) {
- delta = offsetBefore;
- } else if ((DuplicatedTimeOpt & kFormerLatterMask) == kFormer) {
- delta = offsetBefore;
- } else {
- // Interprets the time with rule after the transition,
- // default for duplicated local time range
- delta = offsetAfter;
- }
- }
- return delta;
-}
-
-U_NAMESPACE_END
-
-#endif /* #if !UCONFIG_NO_FORMATTING */
-
-//eof