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