16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2007-2013, 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 "unicode/utypes.h" 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/basictz.h" 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "gregoimp.h" 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uvector.h" 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MILLIS_PER_YEAR (365*24*60*60*1000.0) 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::BasicTimeZone() 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZone() { 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::BasicTimeZone(const UnicodeString &id) 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZone(id) { 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::BasicTimeZone(const BasicTimeZone& source) 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: TimeZone(source) { 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::~BasicTimeZone() { 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::hasEquivalentTransitions(const BasicTimeZone& tz, UDate start, UDate end, 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool ignoreDstAmount, UErrorCode& status) const { 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (hasSameRules(tz)) { 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check the offsets at the start time 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t raw1, raw2, dst1, dst2; 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org getOffset(start, FALSE, raw1, dst1, status); 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tz.getOffset(start, FALSE, raw2, dst2, status); 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ignoreDstAmount) { 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((raw1 + dst1 != raw2 + dst2) 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (dst1 != 0 && dst2 == 0) 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (dst1 == 0 && dst2 != 0)) { 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (raw1 != raw2 || dst1 != dst2) { 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check transitions in the range 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate time = start; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneTransition tr1, tr2; 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (TRUE) { 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool avail1 = getNextTransition(time, FALSE, tr1); 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool avail2 = tz.getNextTransition(time, FALSE, tr2); 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ignoreDstAmount) { 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Skip a transition which only differ the amount of DST savings 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (TRUE) { 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (avail1 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && tr1.getTime() <= end 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && (tr1.getFrom()->getRawOffset() + tr1.getFrom()->getDSTSavings() 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org == tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings()) 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && (tr1.getFrom()->getDSTSavings() != 0 && tr1.getTo()->getDSTSavings() != 0)) { 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org getNextTransition(tr1.getTime(), FALSE, tr1); 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (TRUE) { 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (avail2 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && tr2.getTime() <= end 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && (tr2.getFrom()->getRawOffset() + tr2.getFrom()->getDSTSavings() 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org == tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings()) 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && (tr2.getFrom()->getDSTSavings() != 0 && tr2.getTo()->getDSTSavings() != 0)) { 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tz.getNextTransition(tr2.getTime(), FALSE, tr2); 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool inRange1 = (avail1 && tr1.getTime() <= end); 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool inRange2 = (avail2 && tr2.getTime() <= end); 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!inRange1 && !inRange2) { 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No more transition in the range 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!inRange1 || !inRange2) { 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tr1.getTime() != tr2.getTime()) { 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ignoreDstAmount) { 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings() 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org != tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings() 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (tr1.getTo()->getDSTSavings() != 0 && tr2.getTo()->getDSTSavings() == 0) 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (tr1.getTo()->getDSTSavings() == 0 && tr2.getTo()->getDSTSavings() != 0)) { 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tr1.getTo()->getRawOffset() != tr2.getTo()->getRawOffset() || 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tr1.getTo()->getDSTSavings() != tr2.getTo()->getDSTSavings()) { 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org time = tr1.getTime(); 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial, 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AnnualTimeZoneRule*& std, AnnualTimeZoneRule*& dst, UErrorCode& status) const { 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initial = NULL; 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org std = NULL; 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dst = NULL; 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t initialRaw, initialDst; 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString initialName; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AnnualTimeZoneRule *ar1 = NULL; 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AnnualTimeZoneRule *ar2 = NULL; 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString name; 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool avail; 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneTransition tr; 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Get the next transition 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = getNextTransition(date, FALSE, tr); 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (avail) { 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tr.getFrom()->getName(initialName); 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initialRaw = tr.getFrom()->getRawOffset(); 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initialDst = tr.getFrom()->getDSTSavings(); 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if the next transition is either DST->STD or STD->DST and 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // within roughly 1 year from the specified date 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate nextTransitionTime = tr.getTime(); 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0) 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0)) 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && (date + MILLIS_PER_YEAR > nextTransitionTime)) { 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t year, month, dom, dow, doy, mid; 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate d; 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Get local wall time for the next transition time 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Grego::timeToFields(nextTransitionTime + initialRaw + initialDst, 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year, month, dom, dow, doy, mid); 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t weekInMonth = Grego::dayOfWeekInMonth(year, month, dom); 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Create DOW rule 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DateTimeRule *dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME); 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tr.getTo()->getName(name); 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Note: SimpleTimeZone does not support raw offset change. 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // So we always use raw offset of the given time for the rule, 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // even raw offset is changed. This will result that the result 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // zone to return wrong offset after the transition. 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // When we encounter such case, we do not inspect next next 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // transition for another rule. 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar1 = new AnnualTimeZoneRule(name, initialRaw, tr.getTo()->getDSTSavings(), 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dtr, year, AnnualTimeZoneRule::MAX_YEAR); 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tr.getTo()->getRawOffset() == initialRaw) { 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Get the next next transition 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = getNextTransition(nextTransitionTime, FALSE, tr); 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (avail) { 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if the next next transition is either DST->STD or STD->DST 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // and within roughly 1 year from the next transition 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0) 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0)) 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org && nextTransitionTime + MILLIS_PER_YEAR > tr.getTime()) { 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Get local wall time for the next transition time 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Grego::timeToFields(tr.getTime() + tr.getFrom()->getRawOffset() + tr.getFrom()->getDSTSavings(), 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year, month, dom, dow, doy, mid); 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org weekInMonth = Grego::dayOfWeekInMonth(year, month, dom); 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Generate another DOW rule 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME); 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tr.getTo()->getName(name); 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar2 = new AnnualTimeZoneRule(name, tr.getTo()->getRawOffset(), tr.getTo()->getDSTSavings(), 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dtr, year - 1, AnnualTimeZoneRule::MAX_YEAR); 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Make sure this rule can be applied to the specified date 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = ar2->getPreviousStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), TRUE, d); 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!avail || d > date 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || initialRaw != tr.getTo()->getRawOffset() 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || initialDst != tr.getTo()->getDSTSavings()) { 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We cannot use this rule as the second transition rule 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete ar2; 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar2 = NULL; 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ar2 == NULL) { 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Try previous transition 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = getPreviousTransition(date, TRUE, tr); 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (avail) { 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if the previous transition is either DST->STD or STD->DST. 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The actual transition time does not matter here. 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((tr.getFrom()->getDSTSavings() == 0 && tr.getTo()->getDSTSavings() != 0) 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || (tr.getFrom()->getDSTSavings() != 0 && tr.getTo()->getDSTSavings() == 0)) { 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Generate another DOW rule 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Grego::timeToFields(tr.getTime() + tr.getFrom()->getRawOffset() + tr.getFrom()->getDSTSavings(), 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year, month, dom, dow, doy, mid); 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org weekInMonth = Grego::dayOfWeekInMonth(year, month, dom); 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME); 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tr.getTo()->getName(name); 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // second rule raw/dst offsets should match raw/dst offsets 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // at the given time 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar2 = new AnnualTimeZoneRule(name, initialRaw, initialDst, 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dtr, ar1->getStartYear() - 1, AnnualTimeZoneRule::MAX_YEAR); 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if this rule start after the first rule after the specified date 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = ar2->getNextStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), FALSE, d); 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!avail || d <= nextTransitionTime) { 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We cannot use this rule as the second transition rule 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete ar2; 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar2 = NULL; 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ar2 == NULL) { 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Cannot find a good pair of AnnualTimeZoneRule 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete ar1; 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar1 = NULL; 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The initial rule should represent the rule before the previous transition 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar1->getName(initialName); 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initialRaw = ar1->getRawOffset(); 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initialDst = ar1->getDSTSavings(); 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Try the previous one 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = getPreviousTransition(date, TRUE, tr); 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (avail) { 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tr.getTo()->getName(initialName); 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initialRaw = tr.getTo()->getRawOffset(); 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initialDst = tr.getTo()->getDSTSavings(); 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No transitions in the past. Just use the current offsets 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org getOffset(date, FALSE, initialRaw, initialDst, status); 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Set the initial rule 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initial = new InitialTimeZoneRule(initialName, initialRaw, initialDst); 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Set the standard and daylight saving rules 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ar1 != NULL && ar2 != NULL) { 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ar1->getDSTSavings() != 0) { 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dst = ar1; 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org std = ar2; 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org std = ar1; 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dst = ar2; 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial, 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector*& transitionRules, UErrorCode& status) const { 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const InitialTimeZoneRule *orgini; 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const TimeZoneRule **orgtrs = NULL; 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneTransition tzt; 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool avail; 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector *orgRules = NULL; 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t ruleCount; 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneRule *r = NULL; 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool *done = NULL; 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org InitialTimeZoneRule *res_initial = NULL; 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector *filteredRules = NULL; 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString name; 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate time, t; 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate *newTimes = NULL; 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate firstStart; 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool bFinalStd = FALSE, bFinalDst = FALSE; 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Original transition rules 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ruleCount = countTransitionRules(status); 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org orgRules = new UVector(ruleCount, status); 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org orgtrs = (const TimeZoneRule**)uprv_malloc(sizeof(TimeZoneRule*)*ruleCount); 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (orgtrs == NULL) { 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org getTimeZoneRules(orgini, orgtrs, ruleCount, status); 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (i = 0; i < ruleCount; i++) { 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org orgRules->addElement(orgtrs[i]->clone(), status); 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(orgtrs); 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org orgtrs = NULL; 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = getPreviousTransition(start, TRUE, tzt); 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!avail) { 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No need to filter out rules only applicable to time before the start 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initial = orgini->clone(); 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org transitionRules = orgRules; 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org done = (UBool*)uprv_malloc(sizeof(UBool)*ruleCount); 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (done == NULL) { 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredRules = new UVector(status); 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Create initial rule 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzt.getTo()->getName(name); 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_initial = new InitialTimeZoneRule(name, tzt.getTo()->getRawOffset(), 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tzt.getTo()->getDSTSavings()); 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Mark rules which does not need to be processed 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (i = 0; i < ruleCount; i++) { 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r = (TimeZoneRule*)orgRules->elementAt(i); 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = r->getNextStart(start, res_initial->getRawOffset(), res_initial->getDSTSavings(), FALSE, time); 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org done[i] = !avail; 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org time = start; 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (!bFinalStd || !bFinalDst) { 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = getNextTransition(time, FALSE, tzt); 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!avail) { 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate updatedTime = tzt.getTime(); 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (updatedTime == time) { 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Can get here if rules for start & end of daylight time have exactly 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the same time. 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO: fix getNextTransition() to prevent it? 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_STATE_ERROR; 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org time = updatedTime; 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const TimeZoneRule *toRule = tzt.getTo(); 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (i = 0; i < ruleCount; i++) { 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r = (TimeZoneRule*)orgRules->elementAt(i); 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*r == *toRule) { 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (i >= ruleCount) { 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This case should never happen 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_STATE_ERROR; 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (done[i]) { 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const TimeArrayTimeZoneRule *tar = dynamic_cast<const TimeArrayTimeZoneRule *>(toRule); 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const AnnualTimeZoneRule *ar; 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tar != NULL) { 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Get the previous raw offset and DST savings before the very first start time 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeZoneTransition tzt0; 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = start; 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (TRUE) { 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org avail = getNextTransition(t, FALSE, tzt0); 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!avail) { 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*(tzt0.getTo()) == *tar) { 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = tzt0.getTime(); 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (avail) { 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if the entire start times to be added 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart); 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (firstStart > start) { 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Just add the rule as is 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredRules->addElement(tar->clone(), status); 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Colllect transitions after the start time 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t startTimes; 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DateTimeRule::TimeRuleType timeType; 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t idx; 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org startTimes = tar->countStartTimes(); 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org timeType = tar->getTimeType(); 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 0; idx < startTimes; idx++) { 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tar->getStartTimeAt(idx, t); 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (timeType == DateTimeRule::STANDARD_TIME) { 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t -= tzt.getFrom()->getRawOffset(); 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (timeType == DateTimeRule::WALL_TIME) { 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t -= tzt.getFrom()->getDSTSavings(); 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (t > start) { 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t asize = startTimes - idx; 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (asize > 0) { 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newTimes = (UDate*)uprv_malloc(sizeof(UDate) * asize); 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newTimes == NULL) { 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t newidx = 0; newidx < asize; newidx++) { 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tar->getStartTimeAt(idx + newidx, newTimes[newidx]); 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(newTimes); 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newTimes = NULL; 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tar->getName(name); 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TimeArrayTimeZoneRule *newTar = new TimeArrayTimeZoneRule(name, 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tar->getRawOffset(), tar->getDSTSavings(), newTimes, asize, timeType); 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(newTimes); 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredRules->addElement(newTar, status); 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if ((ar = dynamic_cast<const AnnualTimeZoneRule *>(toRule)) != NULL) { 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar->getFirstStart(tzt.getFrom()->getRawOffset(), tzt.getFrom()->getDSTSavings(), firstStart); 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (firstStart == tzt.getTime()) { 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Just add the rule as is 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredRules->addElement(ar->clone(), status); 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Calculate the transition year 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t year, month, dom, dow, doy, mid; 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Grego::timeToFields(tzt.getTime(), year, month, dom, dow, doy, mid); 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Re-create the rule 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ar->getName(name); 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AnnualTimeZoneRule *newAr = new AnnualTimeZoneRule(name, ar->getRawOffset(), ar->getDSTSavings(), 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *(ar->getRule()), year, ar->getEndYear()); 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredRules->addElement(newAr, status); 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto error; 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // check if this is a final rule 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ar->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) { 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // After bot final standard and dst rules are processed, 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // exit this while loop. 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ar->getDSTSavings() == 0) { 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bFinalStd = TRUE; 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bFinalDst = TRUE; 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org done[i] = TRUE; 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Set the results 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (orgRules != NULL) { 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (!orgRules->isEmpty()) { 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r = (TimeZoneRule*)orgRules->orphanElementAt(0); 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete r; 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete orgRules; 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (done != NULL) { 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(done); 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initial = res_initial; 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org transitionRules = filteredRules; 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgerror: 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (orgtrs != NULL) { 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(orgtrs); 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (orgRules != NULL) { 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (!orgRules->isEmpty()) { 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r = (TimeZoneRule*)orgRules->orphanElementAt(0); 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete r; 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete orgRules; 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (done != NULL) { 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filteredRules != NULL) { 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (!filteredRules->isEmpty()) { 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r = (TimeZoneRule*)filteredRules->orphanElementAt(0); 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete r; 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete filteredRules; 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete res_initial; 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(done); 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org initial = NULL; 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org transitionRules = NULL; 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgBasicTimeZone::getOffsetFromLocal(UDate /*date*/, int32_t /*nonExistingTimeOpt*/, int32_t /*duplicatedTimeOpt*/, 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t& /*rawOffset*/, int32_t& /*dstOffset*/, UErrorCode& status) const { 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_UNSUPPORTED_ERROR; 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */ 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof 561