LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - tzrule.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 307 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 67 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : *******************************************************************************
       5             : * Copyright (C) 2007-2012, International Business Machines Corporation and
       6             : * others. All Rights Reserved.
       7             : *******************************************************************************
       8             : */
       9             : 
      10             : #include "utypeinfo.h"  // for 'typeid' to work
      11             : 
      12             : #include "unicode/utypes.h"
      13             : 
      14             : #if !UCONFIG_NO_FORMATTING
      15             : 
      16             : #include "unicode/tzrule.h"
      17             : #include "unicode/ucal.h"
      18             : #include "gregoimp.h"
      19             : #include "cmemory.h"
      20             : #include "uarrsort.h"
      21             : 
      22             : U_CDECL_BEGIN
      23             : // UComparator function for sorting start times
      24             : static int32_t U_CALLCONV
      25           0 : compareDates(const void * /*context*/, const void *left, const void *right) {
      26           0 :     UDate l = *((UDate*)left);
      27           0 :     UDate r = *((UDate*)right);
      28           0 :     int32_t res = l < r ? -1 : (l == r ? 0 : 1);
      29           0 :     return res;
      30             : }
      31             : U_CDECL_END
      32             : 
      33             : U_NAMESPACE_BEGIN
      34             : 
      35           0 : TimeZoneRule::TimeZoneRule(const UnicodeString& name, int32_t rawOffset, int32_t dstSavings)
      36           0 : : UObject(), fName(name), fRawOffset(rawOffset), fDSTSavings(dstSavings) {
      37           0 : }
      38             : 
      39           0 : TimeZoneRule::TimeZoneRule(const TimeZoneRule& source)
      40           0 : : UObject(source), fName(source.fName), fRawOffset(source.fRawOffset), fDSTSavings(source.fDSTSavings) {
      41           0 : }
      42             : 
      43           0 : TimeZoneRule::~TimeZoneRule() {
      44           0 : }
      45             : 
      46             : TimeZoneRule&
      47           0 : TimeZoneRule::operator=(const TimeZoneRule& right) {
      48           0 :     if (this != &right) {
      49           0 :         fName = right.fName;
      50           0 :         fRawOffset = right.fRawOffset;
      51           0 :         fDSTSavings = right.fDSTSavings;
      52             :     }
      53           0 :     return *this;
      54             : }
      55             : 
      56             : UBool
      57           0 : TimeZoneRule::operator==(const TimeZoneRule& that) const {
      58           0 :     return ((this == &that) ||
      59           0 :             (typeid(*this) == typeid(that) &&
      60           0 :             fName == that.fName &&
      61           0 :             fRawOffset == that.fRawOffset &&
      62           0 :             fDSTSavings == that.fDSTSavings));
      63             : }
      64             : 
      65             : UBool
      66           0 : TimeZoneRule::operator!=(const TimeZoneRule& that) const {
      67           0 :     return !operator==(that);
      68             : }
      69             : 
      70             : UnicodeString&
      71           0 : TimeZoneRule::getName(UnicodeString& name) const {
      72           0 :     name = fName;
      73           0 :     return name;
      74             : }
      75             : 
      76             : int32_t
      77           0 : TimeZoneRule::getRawOffset(void) const {
      78           0 :     return fRawOffset;
      79             : }
      80             : 
      81             : int32_t
      82           0 : TimeZoneRule::getDSTSavings(void) const {
      83           0 :     return fDSTSavings;
      84             : }
      85             : 
      86             : UBool
      87           0 : TimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
      88           0 :     return ((this == &other) ||
      89           0 :             (typeid(*this) == typeid(other) &&
      90           0 :             fRawOffset == other.fRawOffset &&
      91           0 :             fDSTSavings == other.fDSTSavings));
      92             : }
      93             : 
      94             : 
      95           0 : UOBJECT_DEFINE_RTTI_IMPLEMENTATION(InitialTimeZoneRule)
      96             : 
      97           0 : InitialTimeZoneRule::InitialTimeZoneRule(const UnicodeString& name,
      98             :                                          int32_t rawOffset,
      99           0 :                                          int32_t dstSavings)
     100           0 : : TimeZoneRule(name, rawOffset, dstSavings) {
     101           0 : }
     102             : 
     103           0 : InitialTimeZoneRule::InitialTimeZoneRule(const InitialTimeZoneRule& source)
     104           0 : : TimeZoneRule(source) {
     105           0 : }
     106             : 
     107           0 : InitialTimeZoneRule::~InitialTimeZoneRule() {
     108           0 : }
     109             : 
     110             : InitialTimeZoneRule*
     111           0 : InitialTimeZoneRule::clone(void) const {
     112           0 :     return new InitialTimeZoneRule(*this);
     113             : }
     114             : 
     115             : InitialTimeZoneRule&
     116           0 : InitialTimeZoneRule::operator=(const InitialTimeZoneRule& right) {
     117           0 :     if (this != &right) {
     118           0 :         TimeZoneRule::operator=(right);
     119             :     }
     120           0 :     return *this;
     121             : }
     122             : 
     123             : UBool
     124           0 : InitialTimeZoneRule::operator==(const TimeZoneRule& that) const {
     125           0 :     return ((this == &that) ||
     126           0 :             (typeid(*this) == typeid(that) &&
     127           0 :             TimeZoneRule::operator==(that)));
     128             : }
     129             : 
     130             : UBool
     131           0 : InitialTimeZoneRule::operator!=(const TimeZoneRule& that) const {
     132           0 :     return !operator==(that);
     133             : }
     134             : 
     135             : UBool
     136           0 : InitialTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
     137           0 :     if (this == &other) {
     138           0 :         return TRUE;
     139             :     }
     140           0 :     if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
     141           0 :         return FALSE;
     142             :     }
     143           0 :     return TRUE;
     144             : }
     145             : 
     146             : UBool
     147           0 : InitialTimeZoneRule::getFirstStart(int32_t /*prevRawOffset*/,
     148             :                                   int32_t /*prevDSTSavings*/,
     149             :                                   UDate& /*result*/) const {
     150           0 :     return FALSE;
     151             : }
     152             : 
     153             : UBool
     154           0 : InitialTimeZoneRule::getFinalStart(int32_t /*prevRawOffset*/,
     155             :                                   int32_t /*prevDSTSavings*/,
     156             :                                   UDate& /*result*/) const {
     157           0 :     return FALSE;
     158             : }
     159             : 
     160             : UBool
     161           0 : InitialTimeZoneRule::getNextStart(UDate /*base*/,
     162             :                                  int32_t /*prevRawOffset*/,
     163             :                                  int32_t /*prevDSTSavings*/,
     164             :                                  UBool /*inclusive*/,
     165             :                                  UDate& /*result*/) const {
     166           0 :     return FALSE;
     167             : }
     168             : 
     169             : UBool
     170           0 : InitialTimeZoneRule::getPreviousStart(UDate /*base*/,
     171             :                                      int32_t /*prevRawOffset*/,
     172             :                                      int32_t /*prevDSTSavings*/,
     173             :                                      UBool /*inclusive*/,
     174             :                                      UDate& /*result*/) const {
     175           0 :     return FALSE;
     176             : }
     177             : 
     178             : 
     179           0 : UOBJECT_DEFINE_RTTI_IMPLEMENTATION(AnnualTimeZoneRule)
     180             : 
     181             : const int32_t AnnualTimeZoneRule::MAX_YEAR = 0x7FFFFFFF; /* max signed int32 */
     182             : 
     183           0 : AnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name,
     184             :                                        int32_t rawOffset,
     185             :                                        int32_t dstSavings, 
     186             :                                        const DateTimeRule& dateTimeRule,
     187             :                                        int32_t startYear,
     188           0 :                                        int32_t endYear)
     189           0 : : TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(new DateTimeRule(dateTimeRule)),
     190           0 :   fStartYear(startYear), fEndYear(endYear) {
     191           0 : }
     192             : 
     193           0 : AnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name,
     194             :                                        int32_t rawOffset,
     195             :                                        int32_t dstSavings, 
     196             :                                        DateTimeRule* dateTimeRule,
     197             :                                        int32_t startYear,
     198           0 :                                        int32_t endYear)
     199             : : TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(dateTimeRule),
     200           0 :   fStartYear(startYear), fEndYear(endYear) {
     201           0 : }
     202             : 
     203           0 : AnnualTimeZoneRule::AnnualTimeZoneRule(const AnnualTimeZoneRule& source)
     204           0 : : TimeZoneRule(source), fDateTimeRule(new DateTimeRule(*(source.fDateTimeRule))),
     205           0 :   fStartYear(source.fStartYear), fEndYear(source.fEndYear) {
     206           0 : }
     207             : 
     208           0 : AnnualTimeZoneRule::~AnnualTimeZoneRule() {
     209           0 :     delete fDateTimeRule;
     210           0 : }
     211             : 
     212             : AnnualTimeZoneRule*
     213           0 : AnnualTimeZoneRule::clone(void) const {
     214           0 :     return new AnnualTimeZoneRule(*this);
     215             : }
     216             : 
     217             : AnnualTimeZoneRule&
     218           0 : AnnualTimeZoneRule::operator=(const AnnualTimeZoneRule& right) {
     219           0 :     if (this != &right) {
     220           0 :         TimeZoneRule::operator=(right);
     221           0 :         delete fDateTimeRule;
     222           0 :         fDateTimeRule = right.fDateTimeRule->clone();
     223           0 :         fStartYear = right.fStartYear;
     224           0 :         fEndYear = right.fEndYear;
     225             :     }
     226           0 :     return *this;
     227             : }
     228             : 
     229             : UBool
     230           0 : AnnualTimeZoneRule::operator==(const TimeZoneRule& that) const {
     231           0 :     if (this == &that) {
     232           0 :         return TRUE;
     233             :     }
     234           0 :     if (typeid(*this) != typeid(that)) {
     235           0 :         return FALSE;
     236             :     }
     237           0 :     AnnualTimeZoneRule *atzr = (AnnualTimeZoneRule*)&that;
     238           0 :     return (*fDateTimeRule == *(atzr->fDateTimeRule) &&
     239           0 :             fStartYear == atzr->fStartYear &&
     240           0 :             fEndYear == atzr->fEndYear);
     241             : }
     242             : 
     243             : UBool
     244           0 : AnnualTimeZoneRule::operator!=(const TimeZoneRule& that) const {
     245           0 :     return !operator==(that);
     246             : }
     247             : 
     248             : const DateTimeRule*
     249           0 : AnnualTimeZoneRule::getRule() const {
     250           0 :     return fDateTimeRule;
     251             : }
     252             : 
     253             : int32_t
     254           0 : AnnualTimeZoneRule::getStartYear() const {
     255           0 :     return fStartYear;
     256             : }
     257             : 
     258             : int32_t
     259           0 : AnnualTimeZoneRule::getEndYear() const {
     260           0 :     return fEndYear;
     261             : }
     262             : 
     263             : UBool
     264           0 : AnnualTimeZoneRule::getStartInYear(int32_t year,
     265             :                                    int32_t prevRawOffset,
     266             :                                    int32_t prevDSTSavings,
     267             :                                    UDate &result) const {
     268           0 :     if (year < fStartYear || year > fEndYear) {
     269           0 :         return FALSE;
     270             :     }
     271             :     double ruleDay;
     272           0 :     DateTimeRule::DateRuleType type = fDateTimeRule->getDateRuleType();
     273           0 :     if (type == DateTimeRule::DOM) {
     274           0 :         ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), fDateTimeRule->getRuleDayOfMonth());
     275             :     } else {
     276           0 :         UBool after = TRUE;
     277           0 :         if (type == DateTimeRule::DOW) {
     278             :             // Normalize DOW rule into DOW_GEQ_DOM or DOW_LEQ_DOM
     279           0 :             int32_t weeks = fDateTimeRule->getRuleWeekInMonth();
     280           0 :             if (weeks > 0) {
     281           0 :                 ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), 1);
     282           0 :                 ruleDay += 7 * (weeks - 1);
     283             :             } else {
     284           0 :                 after = FALSE;
     285           0 :                 ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(),
     286           0 :                     Grego::monthLength(year, fDateTimeRule->getRuleMonth()));
     287           0 :                 ruleDay += 7 * (weeks + 1);
     288             :            }
     289             :         } else {
     290           0 :             int32_t month = fDateTimeRule->getRuleMonth();
     291           0 :             int32_t dom = fDateTimeRule->getRuleDayOfMonth();
     292           0 :             if (type == DateTimeRule::DOW_LEQ_DOM) {
     293           0 :                 after = FALSE;
     294             :                 // Handle Feb <=29
     295           0 :                 if (month == UCAL_FEBRUARY && dom == 29 && !Grego::isLeapYear(year)) {
     296           0 :                     dom--;
     297             :                 }
     298             :             }
     299           0 :             ruleDay = Grego::fieldsToDay(year, month, dom);
     300             :         }
     301           0 :         int32_t dow = Grego::dayOfWeek(ruleDay);
     302           0 :         int32_t delta = fDateTimeRule->getRuleDayOfWeek() - dow;
     303           0 :         if (after) {
     304           0 :             delta = delta < 0 ? delta + 7 : delta;
     305             :         } else {
     306           0 :             delta = delta > 0 ? delta - 7 : delta;
     307             :         }
     308           0 :         ruleDay += delta;
     309             :     }
     310             : 
     311           0 :     result = ruleDay*U_MILLIS_PER_DAY + fDateTimeRule->getRuleMillisInDay();
     312           0 :     if (fDateTimeRule->getTimeRuleType() != DateTimeRule::UTC_TIME) {
     313           0 :         result -= prevRawOffset;
     314             :     }
     315           0 :     if (fDateTimeRule->getTimeRuleType() == DateTimeRule::WALL_TIME) {
     316           0 :         result -= prevDSTSavings;
     317             :     }
     318           0 :     return TRUE;
     319             : }
     320             : 
     321             : UBool
     322           0 : AnnualTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
     323           0 :     if (this == &other) {
     324           0 :         return TRUE;
     325             :     }
     326           0 :     if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
     327           0 :         return FALSE;
     328             :     }
     329           0 :     AnnualTimeZoneRule* that = (AnnualTimeZoneRule*)&other;
     330           0 :     return (*fDateTimeRule == *(that->fDateTimeRule) &&
     331           0 :             fStartYear == that->fStartYear &&
     332           0 :             fEndYear == that->fEndYear);
     333             : }
     334             : 
     335             : UBool
     336           0 : AnnualTimeZoneRule::getFirstStart(int32_t prevRawOffset,
     337             :                                   int32_t prevDSTSavings,
     338             :                                   UDate& result) const {
     339           0 :     return getStartInYear(fStartYear, prevRawOffset, prevDSTSavings, result);
     340             : }
     341             : 
     342             : UBool
     343           0 : AnnualTimeZoneRule::getFinalStart(int32_t prevRawOffset,
     344             :                                   int32_t prevDSTSavings,
     345             :                                   UDate& result) const {
     346           0 :     if (fEndYear == MAX_YEAR) {
     347           0 :         return FALSE;
     348             :     }
     349           0 :     return getStartInYear(fEndYear, prevRawOffset, prevDSTSavings, result);
     350             : }
     351             : 
     352             : UBool
     353           0 : AnnualTimeZoneRule::getNextStart(UDate base,
     354             :                                  int32_t prevRawOffset,
     355             :                                  int32_t prevDSTSavings,
     356             :                                  UBool inclusive,
     357             :                                  UDate& result) const {
     358             :     int32_t year, month, dom, dow, doy, mid;
     359           0 :     Grego::timeToFields(base, year, month, dom, dow, doy, mid);
     360           0 :     if (year < fStartYear) {
     361           0 :         return getFirstStart(prevRawOffset, prevDSTSavings, result);
     362             :     }
     363             :     UDate tmp;
     364           0 :     if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) {
     365           0 :         if (tmp < base || (!inclusive && (tmp == base))) {
     366             :             // Return the next one
     367           0 :             return getStartInYear(year + 1, prevRawOffset, prevDSTSavings, result);
     368             :         } else {
     369           0 :             result = tmp;
     370           0 :             return TRUE;
     371             :         }
     372             :     }
     373           0 :     return FALSE;
     374             : }
     375             : 
     376             : UBool
     377           0 : AnnualTimeZoneRule::getPreviousStart(UDate base,
     378             :                                      int32_t prevRawOffset,
     379             :                                      int32_t prevDSTSavings,
     380             :                                      UBool inclusive,
     381             :                                      UDate& result) const {
     382             :     int32_t year, month, dom, dow, doy, mid;
     383           0 :     Grego::timeToFields(base, year, month, dom, dow, doy, mid);
     384           0 :     if (year > fEndYear) {
     385           0 :         return getFinalStart(prevRawOffset, prevDSTSavings, result);
     386             :     }
     387             :     UDate tmp;
     388           0 :     if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) {
     389           0 :         if (tmp > base || (!inclusive && (tmp == base))) {
     390             :             // Return the previous one
     391           0 :             return getStartInYear(year - 1, prevRawOffset, prevDSTSavings, result);
     392             :         } else {
     393           0 :             result = tmp;
     394           0 :             return TRUE;
     395             :         }
     396             :     }
     397           0 :     return FALSE;
     398             : }
     399             : 
     400           0 : UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeArrayTimeZoneRule)
     401             : 
     402           0 : TimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const UnicodeString& name,
     403             :                                              int32_t rawOffset,
     404             :                                              int32_t dstSavings,
     405             :                                              const UDate* startTimes,
     406             :                                              int32_t numStartTimes,
     407           0 :                                              DateTimeRule::TimeRuleType timeRuleType)
     408             : : TimeZoneRule(name, rawOffset, dstSavings), fTimeRuleType(timeRuleType),
     409           0 :   fStartTimes(NULL) {
     410           0 :     UErrorCode status = U_ZERO_ERROR;
     411           0 :     initStartTimes(startTimes, numStartTimes, status);
     412             :     //TODO - status?
     413           0 : }
     414             : 
     415             : 
     416           0 : TimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const TimeArrayTimeZoneRule& source)
     417           0 : : TimeZoneRule(source), fTimeRuleType(source.fTimeRuleType), fStartTimes(NULL) {
     418           0 :     UErrorCode status = U_ZERO_ERROR;
     419           0 :     initStartTimes(source.fStartTimes, source.fNumStartTimes, status);
     420             :     //TODO - status?
     421           0 : }
     422             : 
     423             : 
     424           0 : TimeArrayTimeZoneRule::~TimeArrayTimeZoneRule() {
     425           0 :     if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
     426           0 :         uprv_free(fStartTimes);
     427             :     }
     428           0 : }
     429             : 
     430             : TimeArrayTimeZoneRule*
     431           0 : TimeArrayTimeZoneRule::clone(void) const {
     432           0 :     return new TimeArrayTimeZoneRule(*this);
     433             : }
     434             : 
     435             : 
     436             : TimeArrayTimeZoneRule&
     437           0 : TimeArrayTimeZoneRule::operator=(const TimeArrayTimeZoneRule& right) {
     438           0 :     if (this != &right) {
     439           0 :         TimeZoneRule::operator=(right);
     440           0 :         UErrorCode status = U_ZERO_ERROR;
     441           0 :         initStartTimes(right.fStartTimes, right.fNumStartTimes, status);
     442             :         //TODO - status?
     443           0 :         fTimeRuleType = right.fTimeRuleType;        
     444             :     }
     445           0 :     return *this;
     446             : }
     447             : 
     448             : UBool
     449           0 : TimeArrayTimeZoneRule::operator==(const TimeZoneRule& that) const {
     450           0 :     if (this == &that) {
     451           0 :         return TRUE;
     452             :     }
     453           0 :     if (typeid(*this) != typeid(that) || TimeZoneRule::operator==(that) == FALSE) {
     454           0 :         return FALSE;
     455             :     }
     456           0 :     TimeArrayTimeZoneRule *tatzr = (TimeArrayTimeZoneRule*)&that;
     457           0 :     if (fTimeRuleType != tatzr->fTimeRuleType ||
     458           0 :         fNumStartTimes != tatzr->fNumStartTimes) {
     459           0 :         return FALSE;
     460             :     }
     461             :     // Compare start times
     462           0 :     UBool res = TRUE;
     463           0 :     for (int32_t i = 0; i < fNumStartTimes; i++) {
     464           0 :         if (fStartTimes[i] != tatzr->fStartTimes[i]) {
     465           0 :             res = FALSE;
     466           0 :             break;
     467             :         }
     468             :     }
     469           0 :     return res;
     470             : }
     471             : 
     472             : UBool
     473           0 : TimeArrayTimeZoneRule::operator!=(const TimeZoneRule& that) const {
     474           0 :     return !operator==(that);
     475             : }
     476             : 
     477             : DateTimeRule::TimeRuleType
     478           0 : TimeArrayTimeZoneRule::getTimeType(void) const {
     479           0 :     return fTimeRuleType;
     480             : }
     481             : 
     482             : UBool
     483           0 : TimeArrayTimeZoneRule::getStartTimeAt(int32_t index, UDate& result) const {
     484           0 :     if (index >= fNumStartTimes || index < 0) {
     485           0 :         return FALSE;
     486             :     }
     487           0 :     result = fStartTimes[index];
     488           0 :     return TRUE;
     489             : }
     490             : 
     491             : int32_t
     492           0 : TimeArrayTimeZoneRule::countStartTimes(void) const {
     493           0 :     return fNumStartTimes;
     494             : }
     495             : 
     496             : UBool
     497           0 : TimeArrayTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
     498           0 :     if (this == &other) {
     499           0 :         return TRUE;
     500             :     }
     501           0 :     if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
     502           0 :         return FALSE;
     503             :     }
     504           0 :     TimeArrayTimeZoneRule* that = (TimeArrayTimeZoneRule*)&other;
     505           0 :     if (fTimeRuleType != that->fTimeRuleType ||
     506           0 :         fNumStartTimes != that->fNumStartTimes) {
     507           0 :         return FALSE;
     508             :     }
     509             :     // Compare start times
     510           0 :     UBool res = TRUE;
     511           0 :     for (int32_t i = 0; i < fNumStartTimes; i++) {
     512           0 :         if (fStartTimes[i] != that->fStartTimes[i]) {
     513           0 :             res = FALSE;
     514           0 :             break;
     515             :         }
     516             :     }
     517           0 :     return res;
     518             : }
     519             : 
     520             : UBool
     521           0 : TimeArrayTimeZoneRule::getFirstStart(int32_t prevRawOffset,
     522             :                                              int32_t prevDSTSavings,
     523             :                                              UDate& result) const {
     524           0 :     if (fNumStartTimes <= 0 || fStartTimes == NULL) {
     525           0 :         return FALSE;
     526             :     }
     527           0 :     result = getUTC(fStartTimes[0], prevRawOffset, prevDSTSavings);
     528           0 :     return TRUE;
     529             : }
     530             : 
     531             : UBool
     532           0 : TimeArrayTimeZoneRule::getFinalStart(int32_t prevRawOffset,
     533             :                                      int32_t prevDSTSavings,
     534             :                                      UDate& result) const {
     535           0 :     if (fNumStartTimes <= 0 || fStartTimes == NULL) {
     536           0 :         return FALSE;
     537             :     }
     538           0 :     result = getUTC(fStartTimes[fNumStartTimes - 1], prevRawOffset, prevDSTSavings);
     539           0 :     return TRUE;
     540             : }
     541             : 
     542             : UBool
     543           0 : TimeArrayTimeZoneRule::getNextStart(UDate base,
     544             :                                     int32_t prevRawOffset,
     545             :                                     int32_t prevDSTSavings,
     546             :                                     UBool inclusive,
     547             :                                     UDate& result) const {
     548           0 :     int32_t i = fNumStartTimes - 1;
     549           0 :     for (; i >= 0; i--) {
     550           0 :         UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings);
     551           0 :         if (time < base || (!inclusive && time == base)) {
     552             :             break;
     553             :         }
     554           0 :         result = time;
     555             :     }
     556           0 :     if (i == fNumStartTimes - 1) {
     557           0 :         return FALSE;
     558             :     }
     559           0 :     return TRUE;
     560             : }
     561             : 
     562             : UBool
     563           0 : TimeArrayTimeZoneRule::getPreviousStart(UDate base,
     564             :                                         int32_t prevRawOffset,
     565             :                                         int32_t prevDSTSavings,
     566             :                                         UBool inclusive,
     567             :                                         UDate& result) const {
     568           0 :     int32_t i = fNumStartTimes - 1;
     569           0 :     for (; i >= 0; i--) {
     570           0 :         UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings);
     571           0 :         if (time < base || (inclusive && time == base)) {
     572           0 :             result = time;
     573           0 :             return TRUE;
     574             :         }
     575             :     }
     576           0 :     return FALSE;
     577             : }
     578             : 
     579             : 
     580             : // ---- private methods ------
     581             : 
     582             : UBool
     583           0 : TimeArrayTimeZoneRule::initStartTimes(const UDate source[], int32_t size, UErrorCode& status) {
     584             :     // Free old array
     585           0 :     if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
     586           0 :         uprv_free(fStartTimes);
     587             :     }
     588             :     // Allocate new one if needed
     589           0 :     if (size > TIMEARRAY_STACK_BUFFER_SIZE) {
     590           0 :         fStartTimes = (UDate*)uprv_malloc(sizeof(UDate)*size);
     591           0 :         if (fStartTimes == NULL) {
     592           0 :             status = U_MEMORY_ALLOCATION_ERROR;
     593           0 :             fNumStartTimes = 0;
     594           0 :             return FALSE;
     595             :         }
     596             :     } else {
     597           0 :         fStartTimes = (UDate*)fLocalStartTimes;
     598             :     }
     599           0 :     uprv_memcpy(fStartTimes, source, sizeof(UDate)*size);
     600           0 :     fNumStartTimes = size;
     601             :     // Sort dates
     602           0 :     uprv_sortArray(fStartTimes, fNumStartTimes, (int32_t)sizeof(UDate), compareDates, NULL, TRUE, &status);
     603           0 :     if (U_FAILURE(status)) {
     604           0 :         if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
     605           0 :             uprv_free(fStartTimes);
     606             :         }
     607           0 :         fNumStartTimes = 0;
     608           0 :         return FALSE;
     609             :     }
     610           0 :     return TRUE;
     611             : }
     612             : 
     613             : UDate
     614           0 : TimeArrayTimeZoneRule::getUTC(UDate time, int32_t raw, int32_t dst) const {
     615           0 :     if (fTimeRuleType != DateTimeRule::UTC_TIME) {
     616           0 :         time -= raw;
     617             :     }
     618           0 :     if (fTimeRuleType == DateTimeRule::WALL_TIME) {
     619           0 :         time -= dst;
     620             :     }
     621           0 :     return time;
     622             : }
     623             : 
     624             : U_NAMESPACE_END
     625             : 
     626             : #endif /* #if !UCONFIG_NO_FORMATTING */
     627             : 
     628             : //eof
     629             : 

Generated by: LCOV version 1.13