16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2007-2012, International Business Machines Corporation and
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* others. All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "utypeinfo.h"  // for 'typeid' to work
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/tzrule.h"
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucal.h"
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "gregoimp.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uarrsort.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UComparator function for sorting start times
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcompareDates(const void * /*context*/, const void *left, const void *right) {
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDate l = *((UDate*)left);
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDate r = *((UDate*)right);
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t res = l < r ? -1 : (l == r ? 0 : 1);
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return res;
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::TimeZoneRule(const UnicodeString& name, int32_t rawOffset, int32_t dstSavings)
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: UObject(), fName(name), fRawOffset(rawOffset), fDSTSavings(dstSavings) {
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::TimeZoneRule(const TimeZoneRule& source)
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: UObject(source), fName(source.fName), fRawOffset(source.fRawOffset), fDSTSavings(source.fDSTSavings) {
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::~TimeZoneRule() {
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule&
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::operator=(const TimeZoneRule& right) {
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this != &right) {
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fName = right.fName;
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fRawOffset = right.fRawOffset;
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fDSTSavings = right.fDSTSavings;
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *this;
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::operator==(const TimeZoneRule& that) const {
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((this == &that) ||
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (typeid(*this) == typeid(that) &&
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fName == that.fName &&
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fRawOffset == that.fRawOffset &&
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fDSTSavings == that.fDSTSavings));
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::operator!=(const TimeZoneRule& that) const {
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return !operator==(that);
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString&
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::getName(UnicodeString& name) const {
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    name = fName;
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return name;
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::getRawOffset(void) const {
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fRawOffset;
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::getDSTSavings(void) const {
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fDSTSavings;
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((this == &other) ||
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (typeid(*this) == typeid(other) &&
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fRawOffset == other.fRawOffset &&
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fDSTSavings == other.fDSTSavings));
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(InitialTimeZoneRule)
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::InitialTimeZoneRule(const UnicodeString& name,
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                         int32_t rawOffset,
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                         int32_t dstSavings)
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZoneRule(name, rawOffset, dstSavings) {
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::InitialTimeZoneRule(const InitialTimeZoneRule& source)
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZoneRule(source) {
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::~InitialTimeZoneRule() {
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule*
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::clone(void) const {
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return new InitialTimeZoneRule(*this);
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule&
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::operator=(const InitialTimeZoneRule& right) {
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this != &right) {
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        TimeZoneRule::operator=(right);
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *this;
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::operator==(const TimeZoneRule& that) const {
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((this == &that) ||
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (typeid(*this) == typeid(that) &&
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            TimeZoneRule::operator==(that)));
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::operator!=(const TimeZoneRule& that) const {
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return !operator==(that);
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this == &other) {
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return TRUE;
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::getFirstStart(int32_t /*prevRawOffset*/,
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  int32_t /*prevDSTSavings*/,
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UDate& /*result*/) const {
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::getFinalStart(int32_t /*prevRawOffset*/,
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  int32_t /*prevDSTSavings*/,
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UDate& /*result*/) const {
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::getNextStart(UDate /*base*/,
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 int32_t /*prevRawOffset*/,
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 int32_t /*prevDSTSavings*/,
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 UBool /*inclusive*/,
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 UDate& /*result*/) const {
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgInitialTimeZoneRule::getPreviousStart(UDate /*base*/,
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     int32_t /*prevRawOffset*/,
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     int32_t /*prevDSTSavings*/,
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     UBool /*inclusive*/,
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     UDate& /*result*/) const {
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(AnnualTimeZoneRule)
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t AnnualTimeZoneRule::MAX_YEAR = 0x7FFFFFFF; /* max signed int32 */
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name,
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t rawOffset,
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t dstSavings,
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       const DateTimeRule& dateTimeRule,
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t startYear,
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t endYear)
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(new DateTimeRule(dateTimeRule)),
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  fStartYear(startYear), fEndYear(endYear) {
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::AnnualTimeZoneRule(const UnicodeString& name,
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t rawOffset,
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t dstSavings,
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       DateTimeRule* dateTimeRule,
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t startYear,
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       int32_t endYear)
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZoneRule(name, rawOffset, dstSavings), fDateTimeRule(dateTimeRule),
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  fStartYear(startYear), fEndYear(endYear) {
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::AnnualTimeZoneRule(const AnnualTimeZoneRule& source)
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZoneRule(source), fDateTimeRule(new DateTimeRule(*(source.fDateTimeRule))),
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  fStartYear(source.fStartYear), fEndYear(source.fEndYear) {
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::~AnnualTimeZoneRule() {
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    delete fDateTimeRule;
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule*
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::clone(void) const {
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return new AnnualTimeZoneRule(*this);
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule&
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::operator=(const AnnualTimeZoneRule& right) {
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this != &right) {
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        TimeZoneRule::operator=(right);
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete fDateTimeRule;
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fDateTimeRule = right.fDateTimeRule->clone();
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fStartYear = right.fStartYear;
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fEndYear = right.fEndYear;
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *this;
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::operator==(const TimeZoneRule& that) const {
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this == &that) {
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return TRUE;
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (typeid(*this) != typeid(that)) {
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    AnnualTimeZoneRule *atzr = (AnnualTimeZoneRule*)&that;
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (*fDateTimeRule == *(atzr->fDateTimeRule) &&
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fStartYear == atzr->fStartYear &&
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fEndYear == atzr->fEndYear);
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::operator!=(const TimeZoneRule& that) const {
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return !operator==(that);
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst DateTimeRule*
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getRule() const {
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fDateTimeRule;
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getStartYear() const {
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fStartYear;
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getEndYear() const {
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fEndYear;
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getStartInYear(int32_t year,
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                   int32_t prevRawOffset,
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                   int32_t prevDSTSavings,
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                   UDate &result) const {
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (year < fStartYear || year > fEndYear) {
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    double ruleDay;
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    DateTimeRule::DateRuleType type = fDateTimeRule->getDateRuleType();
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (type == DateTimeRule::DOM) {
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), fDateTimeRule->getRuleDayOfMonth());
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UBool after = TRUE;
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (type == DateTimeRule::DOW) {
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Normalize DOW rule into DOW_GEQ_DOM or DOW_LEQ_DOM
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t weeks = fDateTimeRule->getRuleWeekInMonth();
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (weeks > 0) {
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(), 1);
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ruleDay += 7 * (weeks - 1);
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                after = FALSE;
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ruleDay = Grego::fieldsToDay(year, fDateTimeRule->getRuleMonth(),
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    Grego::monthLength(year, fDateTimeRule->getRuleMonth()));
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ruleDay += 7 * (weeks + 1);
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           }
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t month = fDateTimeRule->getRuleMonth();
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t dom = fDateTimeRule->getRuleDayOfMonth();
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (type == DateTimeRule::DOW_LEQ_DOM) {
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                after = FALSE;
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                // Handle Feb <=29
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if (month == UCAL_FEBRUARY && dom == 29 && !Grego::isLeapYear(year)) {
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    dom--;
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ruleDay = Grego::fieldsToDay(year, month, dom);
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t dow = Grego::dayOfWeek(ruleDay);
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t delta = fDateTimeRule->getRuleDayOfWeek() - dow;
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (after) {
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delta = delta < 0 ? delta + 7 : delta;
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delta = delta > 0 ? delta - 7 : delta;
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ruleDay += delta;
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result = ruleDay*U_MILLIS_PER_DAY + fDateTimeRule->getRuleMillisInDay();
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fDateTimeRule->getTimeRuleType() != DateTimeRule::UTC_TIME) {
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result -= prevRawOffset;
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fDateTimeRule->getTimeRuleType() == DateTimeRule::WALL_TIME) {
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result -= prevDSTSavings;
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this == &other) {
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return TRUE;
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    AnnualTimeZoneRule* that = (AnnualTimeZoneRule*)&other;
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (*fDateTimeRule == *(that->fDateTimeRule) &&
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fStartYear == that->fStartYear &&
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fEndYear == that->fEndYear);
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getFirstStart(int32_t prevRawOffset,
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  int32_t prevDSTSavings,
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UDate& result) const {
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getStartInYear(fStartYear, prevRawOffset, prevDSTSavings, result);
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getFinalStart(int32_t prevRawOffset,
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  int32_t prevDSTSavings,
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UDate& result) const {
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fEndYear == MAX_YEAR) {
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return getStartInYear(fEndYear, prevRawOffset, prevDSTSavings, result);
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getNextStart(UDate base,
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 int32_t prevRawOffset,
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 int32_t prevDSTSavings,
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 UBool inclusive,
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                 UDate& result) const {
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t year, month, dom, dow, doy, mid;
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Grego::timeToFields(base, year, month, dom, dow, doy, mid);
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (year < fStartYear) {
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return getFirstStart(prevRawOffset, prevDSTSavings, result);
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDate tmp;
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) {
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (tmp < base || (!inclusive && (tmp == base))) {
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Return the next one
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return getStartInYear(year + 1, prevRawOffset, prevDSTSavings, result);
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result = tmp;
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return TRUE;
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgAnnualTimeZoneRule::getPreviousStart(UDate base,
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     int32_t prevRawOffset,
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     int32_t prevDSTSavings,
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     UBool inclusive,
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     UDate& result) const {
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t year, month, dom, dow, doy, mid;
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Grego::timeToFields(base, year, month, dom, dow, doy, mid);
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (year > fEndYear) {
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return getFinalStart(prevRawOffset, prevDSTSavings, result);
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDate tmp;
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (getStartInYear(year, prevRawOffset, prevDSTSavings, tmp)) {
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (tmp > base || (!inclusive && (tmp == base))) {
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Return the previous one
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return getStartInYear(year - 1, prevRawOffset, prevDSTSavings, result);
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result = tmp;
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return TRUE;
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeArrayTimeZoneRule)
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const UnicodeString& name,
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             int32_t rawOffset,
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             int32_t dstSavings,
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             const UDate* startTimes,
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             int32_t numStartTimes,
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             DateTimeRule::TimeRuleType timeRuleType)
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZoneRule(name, rawOffset, dstSavings), fTimeRuleType(timeRuleType),
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  fStartTimes(NULL) {
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode status = U_ZERO_ERROR;
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    initStartTimes(startTimes, numStartTimes, status);
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    //TODO - status?
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::TimeArrayTimeZoneRule(const TimeArrayTimeZoneRule& source)
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZoneRule(source), fTimeRuleType(source.fTimeRuleType), fStartTimes(NULL) {
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode status = U_ZERO_ERROR;
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    initStartTimes(source.fStartTimes, source.fNumStartTimes, status);
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    //TODO - status?
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::~TimeArrayTimeZoneRule() {
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprv_free(fStartTimes);
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule*
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::clone(void) const {
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return new TimeArrayTimeZoneRule(*this);
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule&
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::operator=(const TimeArrayTimeZoneRule& right) {
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this != &right) {
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        TimeZoneRule::operator=(right);
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UErrorCode status = U_ZERO_ERROR;
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        initStartTimes(right.fStartTimes, right.fNumStartTimes, status);
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        //TODO - status?
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fTimeRuleType = right.fTimeRuleType;
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *this;
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::operator==(const TimeZoneRule& that) const {
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this == &that) {
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return TRUE;
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (typeid(*this) != typeid(that) || TimeZoneRule::operator==(that) == FALSE) {
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    TimeArrayTimeZoneRule *tatzr = (TimeArrayTimeZoneRule*)&that;
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fTimeRuleType != tatzr->fTimeRuleType ||
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fNumStartTimes != tatzr->fNumStartTimes) {
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Compare start times
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool res = TRUE;
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i = 0; i < fNumStartTimes; i++) {
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fStartTimes[i] != tatzr->fStartTimes[i]) {
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            res = FALSE;
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return res;
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::operator!=(const TimeZoneRule& that) const {
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return !operator==(that);
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgDateTimeRule::TimeRuleType
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::getTimeType(void) const {
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fTimeRuleType;
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::getStartTimeAt(int32_t index, UDate& result) const {
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (index >= fNumStartTimes || index < 0) {
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result = fStartTimes[index];
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::countStartTimes(void) const {
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return fNumStartTimes;
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::isEquivalentTo(const TimeZoneRule& other) const {
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (this == &other) {
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return TRUE;
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (typeid(*this) != typeid(other) || TimeZoneRule::isEquivalentTo(other) == FALSE) {
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    TimeArrayTimeZoneRule* that = (TimeArrayTimeZoneRule*)&other;
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fTimeRuleType != that->fTimeRuleType ||
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fNumStartTimes != that->fNumStartTimes) {
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Compare start times
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool res = TRUE;
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i = 0; i < fNumStartTimes; i++) {
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fStartTimes[i] != that->fStartTimes[i]) {
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            res = FALSE;
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return res;
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::getFirstStart(int32_t prevRawOffset,
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             int32_t prevDSTSavings,
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             UDate& result) const {
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fNumStartTimes <= 0 || fStartTimes == NULL) {
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result = getUTC(fStartTimes[0], prevRawOffset, prevDSTSavings);
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::getFinalStart(int32_t prevRawOffset,
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     int32_t prevDSTSavings,
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                     UDate& result) const {
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fNumStartTimes <= 0 || fStartTimes == NULL) {
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result = getUTC(fStartTimes[fNumStartTimes - 1], prevRawOffset, prevDSTSavings);
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::getNextStart(UDate base,
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                    int32_t prevRawOffset,
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                    int32_t prevDSTSavings,
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                    UBool inclusive,
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                    UDate& result) const {
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i = fNumStartTimes - 1;
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (; i >= 0; i--) {
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings);
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (time < base || (!inclusive && time == base)) {
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        result = time;
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (i == fNumStartTimes - 1) {
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::getPreviousStart(UDate base,
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                        int32_t prevRawOffset,
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                        int32_t prevDSTSavings,
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                        UBool inclusive,
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                        UDate& result) const {
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i = fNumStartTimes - 1;
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (; i >= 0; i--) {
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UDate time = getUTC(fStartTimes[i], prevRawOffset, prevDSTSavings);
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (time < base || (inclusive && time == base)) {
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            result = time;
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return TRUE;
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ---- private methods ------
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::initStartTimes(const UDate source[], int32_t size, UErrorCode& status) {
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Free old array
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprv_free(fStartTimes);
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Allocate new one if needed
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (size > TIMEARRAY_STACK_BUFFER_SIZE) {
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fStartTimes = (UDate*)uprv_malloc(sizeof(UDate)*size);
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fStartTimes == NULL) {
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            fNumStartTimes = 0;
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return FALSE;
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fStartTimes = (UDate*)fLocalStartTimes;
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uprv_memcpy(fStartTimes, source, sizeof(UDate)*size);
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    fNumStartTimes = size;
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Sort dates
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uprv_sortArray(fStartTimes, fNumStartTimes, (int32_t)sizeof(UDate), compareDates, NULL, TRUE, &status);
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (fStartTimes != NULL && fStartTimes != fLocalStartTimes) {
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_free(fStartTimes);
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fNumStartTimes = 0;
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return TRUE;
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUDate
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTimeArrayTimeZoneRule::getUTC(UDate time, int32_t raw, int32_t dst) const {
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fTimeRuleType != DateTimeRule::UTC_TIME) {
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        time -= raw;
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (fTimeRuleType == DateTimeRule::WALL_TIME) {
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        time -= dst;
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return time;
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
628