164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others.
264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html
3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
58de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert* Copyright (C) 2007-2016, International Business Machines Corporation and
68de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert* others. All Rights Reserved.
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/dtrule.h"
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/tzrule.h"
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/rbtz.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/simpletz.h"
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/tzrule.h"
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/calendar.h"
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/gregocal.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ucal.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/unistr.h"
2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ustring.h"
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/tztrans.h"
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/vtzone.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "tzrulets.h"
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "zrule.h"
2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ztrans.h"
2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "vzone.h"
3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define HOUR (60*60*1000)
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char *const TESTZIDS[] = {
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "AGT",
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "America/New_York",
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "America/Los_Angeles",
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "America/Indiana/Indianapolis",
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "America/Havana",
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Europe/Lisbon",
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Europe/Paris",
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Asia/Tokyo",
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Asia/Sakhalin",
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Africa/Cairo",
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Africa/Windhoek",
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Australia/Sydney",
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "Etc/GMT+8"
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
5127f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool hasEquivalentTransitions(/*const*/ BasicTimeZone& tz1, /*const*/BasicTimeZone& tz2,
5227f654740f2a26ad62a5c155af9199af9e69b889claireho                                        UDate start, UDate end,
5327f654740f2a26ad62a5c155af9199af9e69b889claireho                                        UBool ignoreDstAmount, int32_t maxTransitionTimeDelta,
5427f654740f2a26ad62a5c155af9199af9e69b889claireho                                        UErrorCode& status);
5527f654740f2a26ad62a5c155af9199af9e69b889claireho
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass TestZIDEnumeration : public StringEnumeration {
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestZIDEnumeration(UBool all = FALSE);
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ~TestZIDEnumeration();
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual int32_t count(UErrorCode& /*status*/) const {
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return len;
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual const UnicodeString *snext(UErrorCode& status);
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual void reset(UErrorCode& status);
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static inline UClassID getStaticClassID() {
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return (UClassID)&fgClassID;
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UClassID getDynamicClassID() const {
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return getStaticClassID();
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate:
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const char fgClassID;
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t idx;
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t len;
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    StringEnumeration   *tzenum;
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char TestZIDEnumeration::fgClassID = 0;
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTestZIDEnumeration::TestZIDEnumeration(UBool all)
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: idx(0) {
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (all) {
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tzenum = TimeZone::createEnumeration();
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        len = tzenum->count(status);
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tzenum = NULL;
898de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert        len = UPRV_LENGTHOF(TESTZIDS);
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTestZIDEnumeration::~TestZIDEnumeration() {
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tzenum != NULL) {
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tzenum;
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UnicodeString*
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTestZIDEnumeration::snext(UErrorCode& status) {
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tzenum != NULL) {
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return tzenum->snext(status);
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else if (U_SUCCESS(status) && idx < len) {
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        unistr = UnicodeString(TESTZIDS[idx++], "");
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return &unistr;
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return NULL;
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTestZIDEnumeration::reset(UErrorCode& status) {
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tzenum != NULL) {
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tzenum->reset(status);
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        idx = 0;
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid TimeZoneRuleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (exec) {
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("TestSuite TestTimeZoneRule");
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (index) {
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(0, TestSimpleRuleBasedTimeZone);
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(1, TestHistoricalRuleBasedTimeZone);
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(2, TestOlsonTransition);
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(3, TestRBTZTransition);
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(4, TestHasEquivalentTransitions);
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(5, TestVTimeZoneRoundTrip);
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(6, TestVTimeZoneRoundTripPartial);
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(7, TestVTimeZoneSimpleWrite);
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(8, TestVTimeZoneHeaderProps);
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(9, TestGetSimpleRules);
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(10, TestTimeZoneRuleCoverage);
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(11, TestSimpleTimeZoneCoverage);
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(12, TestVTimeZoneCoverage);
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        CASE(13, TestVTimeZoneParse);
14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        CASE(14, TestT6216);
14185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        CASE(15, TestT6669);
14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        CASE(16, TestVTimeZoneWrapper);
14383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        CASE(17, TestT8943);
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        default: name = ""; break;
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Compare SimpleTimeZone with equivalent RBTZ
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestSimpleRuleBasedTimeZone(void) {
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SimpleTimeZone stz(-1*HOUR, "TestSTZ",
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UCAL_SEPTEMBER, -30, -UCAL_SATURDAY, 1*HOUR, SimpleTimeZone::WALL_TIME,
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UCAL_FEBRUARY, 2, UCAL_SUNDAY, 1*HOUR, SimpleTimeZone::WALL_TIME,
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1*HOUR, status);
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Couldn't create SimpleTimezone.");
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr;
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *atzr;
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t STARTYEAR = 2000;
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *ir = new InitialTimeZoneRule(
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        "RBTZ_Initial", // Initial time Name
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -1*HOUR,        // Raw offset
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1*HOUR);        // DST saving amount
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Original rules
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone *rbtz1 = new RuleBasedTimeZone("RBTZ1", ir->clone());
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_SEPTEMBER, 30, UCAL_SATURDAY, FALSE,
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1*HOUR, DateTimeRule::WALL_TIME); // SUN<=30 in September, at 1AM wall time
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("RBTZ_DST1",
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -1*HOUR /*rawOffset*/, 1*HOUR /*dstSavings*/, dtr,
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz1->addTransitionRule(atzr, status);
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 1-1.");
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_FEBRUARY, 2, UCAL_SUNDAY,
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1*HOUR, DateTimeRule::WALL_TIME);  // 2nd Sunday in February, at 1AM wall time
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("RBTZ_STD1",
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -1*HOUR /*rawOffset*/, 0 /*dstSavings*/, dtr,
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz1->addTransitionRule(atzr, status);
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 1-2.");
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz1->complete(status);
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't complete RBTZ 1.");
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Equivalent, but different date rule type
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone *rbtz2 = new RuleBasedTimeZone("RBTZ2", ir->clone());
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_SEPTEMBER, -1, UCAL_SATURDAY,
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1*HOUR, DateTimeRule::WALL_TIME); // Last Sunday in September at 1AM wall time
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("RBTZ_DST2", -1*HOUR, 1*HOUR, dtr, STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz2->addTransitionRule(atzr, status);
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 2-1.");
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_FEBRUARY, 8, UCAL_SUNDAY, true,
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1*HOUR, DateTimeRule::WALL_TIME); // SUN>=8 in February, at 1AM wall time
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("RBTZ_STD2", -1*HOUR, 0, dtr, STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz2->addTransitionRule(atzr, status);
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 2-2.");
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz2->complete(status);
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't complete RBTZ 2");
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Equivalent, but different time rule type
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone *rbtz3 = new RuleBasedTimeZone("RBTZ3", ir->clone());
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_SEPTEMBER, 30, UCAL_SATURDAY, false,
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2*HOUR, DateTimeRule::UTC_TIME);
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("RBTZ_DST3", -1*HOUR, 1*HOUR, dtr, STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz3->addTransitionRule(atzr, status);
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 3-1.");
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_FEBRUARY, 2, UCAL_SUNDAY,
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0*HOUR, DateTimeRule::STANDARD_TIME);
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("RBTZ_STD3", -1*HOUR, 0, dtr, STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz3->addTransitionRule(atzr, status);
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 3-2.");
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz3->complete(status);
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't complete RBTZ 3");
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Check equivalency for 10 years
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate start = getUTCMillis(STARTYEAR, UCAL_JANUARY, 1);
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate until = getUTCMillis(STARTYEAR + 10, UCAL_JANUARY, 1);
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(stz.hasEquivalentTransitions(*rbtz1, start, until, TRUE, status))) {
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: rbtz1 must be equivalent to the SimpleTimeZone in the time range.");
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions");
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(stz.hasEquivalentTransitions(*rbtz2, start, until, TRUE, status))) {
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: rbtz2 must be equivalent to the SimpleTimeZone in the time range.");
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions");
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!(stz.hasEquivalentTransitions(*rbtz3, start, until, TRUE, status))) {
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: rbtz3 must be equivalent to the SimpleTimeZone in the time range.");
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions");
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // hasSameRules
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (rbtz1->hasSameRules(*rbtz2)) {
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: rbtz1 and rbtz2 have different rules, but returned true.");
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (rbtz1->hasSameRules(*rbtz3)) {
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: rbtz1 and rbtz3 have different rules, but returned true.");
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone *rbtz1c = (RuleBasedTimeZone*)rbtz1->clone();
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!rbtz1->hasSameRules(*rbtz1c)) {
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Cloned RuleBasedTimeZone must have the same rules with the original.");
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getOffset
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t era, year, month, dayOfMonth, dayOfWeek, millisInDay;
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time;
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t offset, dstSavings;
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool dst;
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    GregorianCalendar *cal = new GregorianCalendar(status);
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: Could not create a Gregorian calendar instance.: %s", u_errorName(status));
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete rbtz1;
28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete rbtz2;
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete rbtz3;
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete rbtz1c;
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return;
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->setTimeZone(*rbtz1);
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->clear();
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Jan 1, 1000 BC
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->set(UCAL_ERA, GregorianCalendar::BC);
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->set(1000, UCAL_JANUARY, 1);
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    era = cal->get(UCAL_ERA, status);
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    year = cal->get(UCAL_YEAR, status);
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    month = cal->get(UCAL_MONTH, status);
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dayOfMonth = cal->get(UCAL_DAY_OF_MONTH, status);
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dayOfWeek = cal->get(UCAL_DAY_OF_WEEK, status);
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    millisInDay = cal->get(UCAL_MILLISECONDS_IN_DAY, status);
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time = cal->getTime(status);
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Could not get calendar field values.");
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    offset = rbtz1->getOffset(era, year, month, dayOfMonth, dayOfWeek, millisInDay, status);
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(7 args) failed.");
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset != 0) {
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln(UnicodeString("FAIL: Invalid time zone offset: ") + offset + " /expected: 0");
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dst = rbtz1->inDaylightTime(time, status);
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: inDaylightTime failed.");
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!dst) {
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Invalid daylight saving time");
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz1->getOffset(time, TRUE, offset, dstSavings, status);
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(5 args) failed.");
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset != -3600000) {
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln(UnicodeString("FAIL: Invalid time zone raw offset: ") + offset + " /expected: -3600000");
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dstSavings != 3600000) {
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln(UnicodeString("FAIL: Invalid DST amount: ") + dstSavings + " /expected: 3600000");
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // July 1, 2000, AD
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->set(UCAL_ERA, GregorianCalendar::AD);
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->set(2000, UCAL_JULY, 1);
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    era = cal->get(UCAL_ERA, status);
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    year = cal->get(UCAL_YEAR, status);
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    month = cal->get(UCAL_MONTH, status);
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dayOfMonth = cal->get(UCAL_DAY_OF_MONTH, status);
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dayOfWeek = cal->get(UCAL_DAY_OF_WEEK, status);
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    millisInDay = cal->get(UCAL_MILLISECONDS_IN_DAY, status);
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time = cal->getTime(status);
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Could not get calendar field values.");
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    offset = rbtz1->getOffset(era, year, month, dayOfMonth, dayOfWeek, millisInDay, status);
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(7 args) failed.");
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset != -3600000) {
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: Invalid time zone offset: " + offset + " /expected: -3600000");
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dst = rbtz1->inDaylightTime(time, status);
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: inDaylightTime failed.");
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dst) {
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Invalid daylight saving time");
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz1->getOffset(time, TRUE, offset, dstSavings, status);
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(5 args) failed.");
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset != -3600000) {
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: Invalid time zone raw offset: " + offset + " /expected: -3600000");
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dstSavings != 0) {
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: Invalid DST amount: " + dstSavings + " /expected: 0");
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getRawOffset
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    offset = rbtz1->getRawOffset();
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset != -1*HOUR) {
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: Invalid time zone raw offset returned by getRawOffset: "
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            + offset + " /expected: -3600000");
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // operator=/==/!=
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone rbtz0("RBTZ1", ir->clone());
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (rbtz0 == *rbtz1 || !(rbtz0 != *rbtz1)) {
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: RuleBasedTimeZone rbtz0 is not equal to rbtz1, but got wrong result");
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz0 = *rbtz1;
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (rbtz0 != *rbtz1 || !(rbtz0 == *rbtz1)) {
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: RuleBasedTimeZone rbtz0 is equal to rbtz1, but got wrong result");
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // setRawOffset
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t RAW = -10*HOUR;
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz0.setRawOffset(RAW);
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (rbtz0.getRawOffset() != RAW) {
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("setRawOffset is implemented in RuleBasedTimeZone");
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // useDaylightTime
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!rbtz1->useDaylightTime()) {
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: useDaylightTime returned FALSE");
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Try to add 3rd final rule
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_OCTOBER, 15, 1*HOUR, DateTimeRule::WALL_TIME);
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("3RD_ATZ", -1*HOUR, 2*HOUR, dtr, STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz1->addTransitionRule(atzr, status);
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: 3rd final rule must be rejected");
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete atzr;
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Try to add an initial rule
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *ir1 = new InitialTimeZoneRule("Test Initial", 2*HOUR, 0);
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz1->addTransitionRule(ir1, status);
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZoneRule must be rejected");
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete ir1;
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete ir;
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete rbtz1;
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete rbtz2;
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete rbtz3;
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete rbtz1c;
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete cal;
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Test equivalency between OlsonTimeZone and custom RBTZ representing the
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * equivalent rules in a certain time range
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestHistoricalRuleBasedTimeZone(void) {
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Compare to America/New_York with equivalent RBTZ
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *ny = (BasicTimeZone*)TimeZone::createTimeZone("America/New_York");
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //RBTZ
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *ir = new InitialTimeZoneRule("EST", -5*HOUR, 0);
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone *rbtz = new RuleBasedTimeZone("EST5EDT", ir);
439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr;
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *tzr;
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Standard time
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_OCTOBER, -1, UCAL_SUNDAY,
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2*HOUR, DateTimeRule::WALL_TIME); // Last Sunday in October, at 2AM wall time
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EST", -5*HOUR /*rawOffset*/, 0 /*dstSavings*/, dtr, 1967, 2006);
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 1.");
450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_NOVEMBER, 1, UCAL_SUNDAY,
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        true, 2*HOUR, DateTimeRule::WALL_TIME); // SUN>=1 in November, at 2AM wall time
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EST", -5*HOUR, 0, dtr, 2007, AnnualTimeZoneRule::MAX_YEAR);
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 2.");
458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Daylight saving time
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_APRIL, -1, UCAL_SUNDAY,
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2*HOUR, DateTimeRule::WALL_TIME); // Last Sunday in April, at 2AM wall time
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, dtr, 1967, 1973);
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 3.");
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_JANUARY, 6,
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2*HOUR, DateTimeRule::WALL_TIME); // January 6, at 2AM wall time
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, dtr, 1974, 1974);
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 4.");
475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_FEBRUARY, 23,
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2*HOUR, DateTimeRule::WALL_TIME); // February 23, at 2AM wall time
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, dtr, 1975, 1975);
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 5.");
483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_APRIL, -1, UCAL_SUNDAY,
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2*HOUR, DateTimeRule::WALL_TIME); // Last Sunday in April, at 2AM wall time
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, dtr, 1976, 1986);
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 6.");
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_APRIL, 1, UCAL_SUNDAY,
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        true, 2*HOUR, DateTimeRule::WALL_TIME); // SUN>=1 in April, at 2AM wall time
495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, dtr, 1987, 2006);
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 7.");
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_MARCH, 8, UCAL_SUNDAY,
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        true, 2*HOUR, DateTimeRule::WALL_TIME); // SUN>=8 in March, at 2AM wall time
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tzr = new AnnualTimeZoneRule("EDT", -5*HOUR, 1*HOUR, dtr, 2007, AnnualTimeZoneRule::MAX_YEAR);
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->addTransitionRule(tzr, status);
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't add AnnualTimeZoneRule 7.");
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbtz->complete(status);
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: couldn't complete RBTZ.");
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // hasEquivalentTransitions
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_1950 = getUTCMillis(1950, UCAL_JANUARY, 1);
516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_1967 = getUTCMillis(1971, UCAL_JANUARY, 1);
517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_2010 = getUTCMillis(2010, UCAL_JANUARY, 1);
518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!ny->hasEquivalentTransitions(*rbtz, jan1_1967, jan1_2010, TRUE, status)) {
52085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("FAIL: The RBTZ must be equivalent to America/New_York between 1967 and 2010");
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions for ny/rbtz 1967-2010");
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (ny->hasEquivalentTransitions(*rbtz, jan1_1950, jan1_2010, TRUE, status)) {
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: The RBTZ must not be equivalent to America/New_York between 1950 and 2010");
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions for ny/rbtz 1950-2010");
530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Same with above, but calling RBTZ#hasEquivalentTransitions against OlsonTimeZone
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!rbtz->hasEquivalentTransitions(*ny, jan1_1967, jan1_2010, TRUE, status)) {
53485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("FAIL: The RBTZ must be equivalent to America/New_York between 1967 and 2010 ");
535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions for rbtz/ny 1967-2010");
538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (rbtz->hasEquivalentTransitions(*ny, jan1_1950, jan1_2010, TRUE, status)) {
540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: The RBTZ must not be equivalent to America/New_York between 1950 and 2010");
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions for rbtz/ny 1950-2010");
544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeZone APIs
547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (ny->hasSameRules(*rbtz) || rbtz->hasSameRules(*ny)) {
548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: hasSameRules must return false");
549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone *rbtzc = (RuleBasedTimeZone*)rbtz->clone();
551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!rbtz->hasSameRules(*rbtzc) || !rbtz->hasEquivalentTransitions(*rbtzc, jan1_1950, jan1_2010, TRUE, status)) {
552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: hasSameRules/hasEquivalentTransitions must return true for cloned RBTZs");
553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned from hasEquivalentTransitions for rbtz/rbtzc 1950-2010");
556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate times[] = {
559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2006, UCAL_MARCH, 15),
560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2006, UCAL_NOVEMBER, 1),
561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2007, UCAL_MARCH, 15),
562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2007, UCAL_NOVEMBER, 1),
563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2008, UCAL_MARCH, 15),
564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2008, UCAL_NOVEMBER, 1),
565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0
566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t offset1, dst1;
568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t offset2, dst2;
569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int i = 0; times[i] != 0; i++) {
571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Check getOffset - must return the same results for these time data
572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        rbtz->getOffset(times[i], FALSE, offset1, dst1, status);
573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: rbtz->getOffset failed");
575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ny->getOffset(times[i], FALSE, offset2, dst2, status);
577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: ny->getOffset failed");
579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (offset1 != offset2 || dst1 != dst2) {
58185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            dataerrln("FAIL: Incompatible time zone offset/dstSavings for ny and rbtz");
582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Check inDaylightTime
585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (rbtz->inDaylightTime(times[i], status) != ny->inDaylightTime(times[i], status)) {
58685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            dataerrln("FAIL: Incompatible daylight saving time for ny and rbtz");
587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: inDaylightTime failed");
590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete ny;
594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete rbtz;
595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete rbtzc;
596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Check if transitions returned by getNextTransition/getPreviousTransition
600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * are actual time transitions.
601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestOlsonTransition(void) {
604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t TESTYEARS[][2] = {
606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {1895, 1905}, // including int32 minimum second
607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {1965, 1975}, // including the epoch
608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {1995, 2015}, // practical year range
609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0,0}
610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestZIDEnumeration tzenum(!quick);
614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const UnicodeString *tzid = tzenum.snext(status);
616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzid == NULL) {
617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: error returned while enumerating timezone IDs.");
621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        BasicTimeZone *tz = (BasicTimeZone*)TimeZone::createTimeZone(*tzid);
624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t i = 0; TESTYEARS[i][0] != 0 || TESTYEARS[i][1] != 0; i++) {
625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate lo = getUTCMillis(TESTYEARS[i][0], UCAL_JANUARY, 1);
626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate hi = getUTCMillis(TESTYEARS[i][1], UCAL_JANUARY, 1);
627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            verifyTransitions(*tz, lo, hi);
628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tz;
630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Check if an OlsonTimeZone and its equivalent RBTZ have the exact same
635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * transitions.
636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestRBTZTransition(void) {
639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t STARTYEARS[] = {
640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1900,
641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1960,
642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1990,
643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2010,
644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0
645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestZIDEnumeration tzenum(!quick);
649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const UnicodeString *tzid = tzenum.snext(status);
651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzid == NULL) {
652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: error returned while enumerating timezone IDs.");
656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        BasicTimeZone *tz = (BasicTimeZone*)TimeZone::createTimeZone(*tzid);
659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t ruleCount = tz->countTransitionRules(status);
660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const InitialTimeZoneRule *initial;
662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const TimeZoneRule **trsrules = new const TimeZoneRule*[ruleCount];
663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tz->getTimeZoneRules(initial, trsrules, ruleCount, status);
664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: failed to get the TimeZoneRules from time zone " + *tzid);
666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        RuleBasedTimeZone *rbtz = new RuleBasedTimeZone(*tzid, initial->clone());
668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: failed to get the transition rule count from time zone " + *tzid);
670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t i = 0; i < ruleCount; i++) {
672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            rbtz->addTransitionRule(trsrules[i]->clone(), status);
673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"FAIL: failed to add a transition rule at index " + i + " to the RBTZ for " + *tzid);
675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        rbtz->complete(status);
678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: complete() failed for the RBTZ for " + *tzid);
680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t idx = 0; STARTYEARS[idx] != 0; idx++) {
683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate start = getUTCMillis(STARTYEARS[idx], UCAL_JANUARY, 1);
684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate until = getUTCMillis(STARTYEARS[idx] + 20, UCAL_JANUARY, 1);
685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Compare the original OlsonTimeZone with the RBTZ starting the startTime for 20 years
686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Ascending
688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            compareTransitionsAscending(*tz, *rbtz, start, until, FALSE);
689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Ascending/inclusive
690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            compareTransitionsAscending(*tz, *rbtz, start + 1, until, TRUE);
691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Descending
692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            compareTransitionsDescending(*tz, *rbtz, start, until, FALSE);
693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Descending/inclusive
694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            compareTransitionsDescending(*tz, *rbtz, start + 1, until, TRUE);
695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete [] trsrules;
697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete rbtz;
698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tz;
699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestHasEquivalentTransitions(void) {
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // America/New_York and America/Indiana/Indianapolis are equivalent
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // since 2006
706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *newyork = (BasicTimeZone*)TimeZone::createTimeZone("America/New_York");
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *indianapolis = (BasicTimeZone*)TimeZone::createTimeZone("America/Indiana/Indianapolis");
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *gmt_5 = (BasicTimeZone*)TimeZone::createTimeZone("Etc/GMT+5");
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_1971 = getUTCMillis(1971, UCAL_JANUARY, 1);
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_2005 = getUTCMillis(2005, UCAL_JANUARY, 1);
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_2006 = getUTCMillis(2006, UCAL_JANUARY, 1);
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_2007 = getUTCMillis(2007, UCAL_JANUARY, 1);
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate jan1_2011 = getUTCMillis(2010, UCAL_JANUARY, 1);
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (newyork->hasEquivalentTransitions(*indianapolis, jan1_2005, jan1_2011, TRUE, status)) {
71885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("FAIL: New_York is not equivalent to Indianapolis between 2005 and 2010");
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error status is returned from hasEquivalentTransition");
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!newyork->hasEquivalentTransitions(*indianapolis, jan1_2006, jan1_2011, TRUE, status)) {
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: New_York is equivalent to Indianapolis between 2006 and 2010");
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error status is returned from hasEquivalentTransition");
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!indianapolis->hasEquivalentTransitions(*gmt_5, jan1_1971, jan1_2006, TRUE, status)) {
731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Indianapolis is equivalent to GMT+5 between 1971 and 2005");
732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error status is returned from hasEquivalentTransition");
735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (indianapolis->hasEquivalentTransitions(*gmt_5, jan1_1971, jan1_2007, TRUE, status)) {
73785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("FAIL: Indianapolis is not equivalent to GMT+5 between 1971 and 2006");
738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error status is returned from hasEquivalentTransition");
741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Cloned TimeZone
744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *newyork2 = (BasicTimeZone*)newyork->clone();
745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!newyork->hasEquivalentTransitions(*newyork2, jan1_1971, jan1_2011, FALSE, status)) {
746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Cloned TimeZone must have the same transitions");
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error status is returned from hasEquivalentTransition for newyork/newyork2");
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!newyork->hasEquivalentTransitions(*newyork2, jan1_1971, jan1_2011, TRUE, status)) {
752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Cloned TimeZone must have the same transitions");
753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error status is returned from hasEquivalentTransition for newyork/newyork2");
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // America/New_York and America/Los_Angeles has same DST start rules, but
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // raw offsets are different
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *losangeles = (BasicTimeZone*)TimeZone::createTimeZone("America/Los_Angeles");
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (newyork->hasEquivalentTransitions(*losangeles, jan1_2006, jan1_2011, TRUE, status)) {
76285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("FAIL: New_York is not equivalent to Los Angeles, but returned true");
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error status is returned from hasEquivalentTransition for newyork/losangeles");
766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete newyork;
769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete newyork2;
770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete indianapolis;
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete gmt_5;
772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete losangeles;
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Write out time zone rules of OlsonTimeZone into VTIMEZONE format, create a new
777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * VTimeZone from the VTIMEZONE data, then compare transitions
778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestVTimeZoneRoundTrip(void) {
781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate startTime = getUTCMillis(1850, UCAL_JANUARY, 1);
782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate endTime = getUTCMillis(2050, UCAL_JANUARY, 1);
783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestZIDEnumeration tzenum(!quick);
786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const UnicodeString *tzid = tzenum.snext(status);
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzid == NULL) {
789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: error returned while enumerating timezone IDs.");
793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        BasicTimeZone *tz = (BasicTimeZone*)TimeZone::createTimeZone(*tzid);
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        VTimeZone *vtz_org = VTimeZone::createVTimeZoneByID(*tzid);
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        vtz_org->setTZURL("http://source.icu-project.org/timezone");
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        vtz_org->setLastModified(Calendar::getNow());
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        VTimeZone *vtz_new = NULL;
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString vtzdata;
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Write out VTIMEZONE data
802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        vtz_org->write(vtzdata, status);
803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: error returned while writing time zone rules for " +
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *tzid + " into VTIMEZONE format.");
806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Read VTIMEZONE data
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            vtz_new = VTimeZone::createVTimeZone(vtzdata, status);
809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"FAIL: error returned while reading VTIMEZONE data for " + *tzid);
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Write out VTIMEZONE one more time
813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                UnicodeString vtzdata1;
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz_new->write(vtzdata1, status);
815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (U_FAILURE(status)) {
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln((UnicodeString)"FAIL: error returned while writing time zone rules for " +
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        *tzid + "(vtz_new) into VTIMEZONE format.");
818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Make sure VTIMEZONE data is exactly same with the first one
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (vtzdata != vtzdata1) {
821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        errln((UnicodeString)"FAIL: different VTIMEZONE data after round trip for " + *tzid);
822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Check equivalency after the first transition.
825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // The DST information before the first transition might be lost
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // because there is no good way to represent the initial time with
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // VTIMEZONE.
828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                int32_t raw1, raw2, dst1, dst2;
829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                tz->getOffset(startTime, FALSE, raw1, dst1, status);
830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz_new->getOffset(startTime, FALSE, raw2, dst2, status);
831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (U_FAILURE(status)) {
832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: error status is returned from getOffset");
833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (raw1 + dst1 != raw2 + dst2) {
835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        errln("FAIL: VTimeZone for " + *tzid +
836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            " is not equivalent to its OlsonTimeZone corresponding at "
837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            + dateToString(startTime));
838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    TimeZoneTransition trans;
840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    UBool avail = tz->getNextTransition(startTime, FALSE, trans);
841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (avail) {
842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (!vtz_new->hasEquivalentTransitions(*tz, trans.getTime(),
843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                endTime, TRUE, status)) {
84427f654740f2a26ad62a5c155af9199af9e69b889claireho                            int32_t maxDelta = 1000;
84527f654740f2a26ad62a5c155af9199af9e69b889claireho                            if (!hasEquivalentTransitions(*vtz_new, *tz, trans.getTime() + maxDelta,
84627f654740f2a26ad62a5c155af9199af9e69b889claireho                                endTime, TRUE, maxDelta, status)) {
84727f654740f2a26ad62a5c155af9199af9e69b889claireho                                errln("FAIL: VTimeZone for " + *tzid +
84827f654740f2a26ad62a5c155af9199af9e69b889claireho                                    " is not equivalent to its OlsonTimeZone corresponding.");
84927f654740f2a26ad62a5c155af9199af9e69b889claireho                            } else {
85027f654740f2a26ad62a5c155af9199af9e69b889claireho                                logln("VTimeZone for " + *tzid +
85127f654740f2a26ad62a5c155af9199af9e69b889claireho                                    "  differs from its OlsonTimeZone corresponding with maximum transition time delta - " + maxDelta);
85227f654740f2a26ad62a5c155af9199af9e69b889claireho                            }
853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (U_FAILURE(status)) {
855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            errln("FAIL: error status is returned from hasEquivalentTransition");
856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (vtz_new != NULL) {
861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete vtz_new;
862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz_new = NULL;
863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tz;
866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete vtz_org;
867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Write out time zone rules of OlsonTimeZone after a cutover date into VTIMEZONE format,
872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * create a new VTimeZone from the VTIMEZONE data, then compare transitions
873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestVTimeZoneRoundTripPartial(void) {
876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t STARTYEARS[] = {
877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1900,
878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        1950,
879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        2020,
880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0
881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate endTime = getUTCMillis(2050, UCAL_JANUARY, 1);
883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestZIDEnumeration tzenum(!quick);
886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const UnicodeString *tzid = tzenum.snext(status);
888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzid == NULL) {
889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: error returned while enumerating timezone IDs.");
893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        BasicTimeZone *tz = (BasicTimeZone*)TimeZone::createTimeZone(*tzid);
896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        VTimeZone *vtz_org = VTimeZone::createVTimeZoneByID(*tzid);
897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        VTimeZone *vtz_new = NULL;
898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString vtzdata;
899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t i = 0; STARTYEARS[i] != 0; i++) {
901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Write out VTIMEZONE
902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate startTime = getUTCMillis(STARTYEARS[i], UCAL_JANUARY, 1);
903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            vtz_org->write(startTime, vtzdata, status);
904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"FAIL: error returned while writing time zone rules for " +
906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *tzid + " into VTIMEZONE format since " + dateToString(startTime));
907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Read VTIMEZONE data
909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz_new = VTimeZone::createVTimeZone(vtzdata, status);
910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (U_FAILURE(status)) {
911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln((UnicodeString)"FAIL: error returned while reading VTIMEZONE data for " + *tzid
912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + " since " + dateToString(startTime));
913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Check equivalency after the first transition.
915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // The DST information before the first transition might be lost
916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // because there is no good way to represent the initial time with
917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // VTIMEZONE.
918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    int32_t raw1, raw2, dst1, dst2;
919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    tz->getOffset(startTime, FALSE, raw1, dst1, status);
920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    vtz_new->getOffset(startTime, FALSE, raw2, dst2, status);
921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (U_FAILURE(status)) {
922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        errln("FAIL: error status is returned from getOffset");
923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (raw1 + dst1 != raw2 + dst2) {
925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            errln("FAIL: VTimeZone for " + *tzid +
926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                " is not equivalent to its OlsonTimeZone corresponding at "
927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                + dateToString(startTime));
928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        TimeZoneTransition trans;
930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UBool avail = tz->getNextTransition(startTime, FALSE, trans);
931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (avail) {
932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (!vtz_new->hasEquivalentTransitions(*tz, trans.getTime(),
933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                    endTime, TRUE, status)) {
93427f654740f2a26ad62a5c155af9199af9e69b889claireho                                int32_t maxDelta = 1000;
93527f654740f2a26ad62a5c155af9199af9e69b889claireho                                if (!hasEquivalentTransitions(*vtz_new, *tz, trans.getTime() + maxDelta,
93627f654740f2a26ad62a5c155af9199af9e69b889claireho                                    endTime, TRUE, maxDelta, status)) {
93727f654740f2a26ad62a5c155af9199af9e69b889claireho                                    errln("FAIL: VTimeZone for " + *tzid +
93827f654740f2a26ad62a5c155af9199af9e69b889claireho                                        " is not equivalent to its OlsonTimeZone corresponding.");
93927f654740f2a26ad62a5c155af9199af9e69b889claireho                                } else {
94027f654740f2a26ad62a5c155af9199af9e69b889claireho                                    logln("VTimeZone for " + *tzid +
94127f654740f2a26ad62a5c155af9199af9e69b889claireho                                        "  differs from its OlsonTimeZone corresponding with maximum transition time delta - " + maxDelta);
94227f654740f2a26ad62a5c155af9199af9e69b889claireho                                }
94327f654740f2a26ad62a5c155af9199af9e69b889claireho
944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (U_FAILURE(status)) {
946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                errln("FAIL: error status is returned from hasEquivalentTransition");
947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (vtz_new != NULL) {
953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete vtz_new;
954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz_new = NULL;
955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tz;
958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete vtz_org;
959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Write out simple time zone rules from an OlsonTimeZone at various time into VTIMEZONE
964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * format and create a new VTimeZone from the VTIMEZONE data, then make sure the raw offset
965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and DST savings are same in these two time zones.
966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestVTimeZoneSimpleWrite(void) {
969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t TESTDATES[][3] = {
970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006,  UCAL_JANUARY,   1},
971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006,  UCAL_MARCH,     15},
972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006,  UCAL_MARCH,     31},
973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006,  UCAL_OCTOBER,   25},
974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006,  UCAL_NOVEMBER,  1},
975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006,  UCAL_NOVEMBER,  5},
976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2007,  UCAL_JANUARY,   1},
977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {0,     0,              0}
978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestZIDEnumeration tzenum(!quick);
982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const UnicodeString *tzid = tzenum.snext(status);
984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzid == NULL) {
985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: error returned while enumerating timezone IDs.");
989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        VTimeZone *vtz_org = VTimeZone::createVTimeZoneByID(*tzid);
992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        VTimeZone *vtz_new = NULL;
993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString vtzdata;
994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t i = 0; TESTDATES[i][0] != 0; i++) {
996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Write out VTIMEZONE
997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate time = getUTCMillis(TESTDATES[i][0], TESTDATES[i][1], TESTDATES[i][2]);
998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            vtz_org->writeSimple(time, vtzdata, status);
999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"FAIL: error returned while writing simple time zone rules for " +
1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *tzid + " into VTIMEZONE format at " + dateToString(time));
1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Read VTIMEZONE data
1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz_new = VTimeZone::createVTimeZone(vtzdata, status);
1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (U_FAILURE(status)) {
1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln((UnicodeString)"FAIL: error returned while reading simple VTIMEZONE data for " + *tzid
1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + " at " + dateToString(time));
1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Check equivalency
1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    int32_t raw0, dst0;
1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    int32_t raw1, dst1;
1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    vtz_org->getOffset(time, FALSE, raw0, dst0, status);
1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    vtz_new->getOffset(time, FALSE, raw1, dst1, status);
1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (U_SUCCESS(status)) {
1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (raw0 != raw1 || dst0 != dst1) {
1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            errln("FAIL: VTimeZone writeSimple for " + *tzid + " at "
1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                + dateToString(time) + " failed to the round trip.");
1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        errln("FAIL: getOffset returns error status");
1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (vtz_new != NULL) {
1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete vtz_new;
1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz_new = NULL;
1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete vtz_org;
1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Write out time zone rules of OlsonTimeZone into VTIMEZONE format with RFC2445 header TZURL and
1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * LAST-MODIFIED, create a new VTimeZone from the VTIMEZONE data to see if the headers are preserved.
1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestVTimeZoneHeaderProps(void) {
1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString TESTURL1("http://source.icu-project.org");
1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UnicodeString TESTURL2("http://www.ibm.com");
1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString tzurl;
1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate lmod;
1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate lastmod = getUTCMillis(2007, UCAL_JUNE, 1);
1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *vtz = VTimeZone::createVTimeZoneByID("America/Chicago");
1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    vtz->setTZURL(TESTURL1);
1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    vtz->setLastModified(lastmod);
1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Roundtrip conversion
1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString vtzdata;
1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    vtz->write(vtzdata, status);
1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *newvtz1 = NULL;
1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned while writing VTIMEZONE data 1");
1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Create a new one
1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    newvtz1 = VTimeZone::createVTimeZone(vtzdata, status);
1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: error returned while loading VTIMEZONE data 1");
1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Check if TZURL and LAST-MODIFIED properties are preserved
1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newvtz1->getTZURL(tzurl);
1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzurl != TESTURL1) {
1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: TZURL 1 was not preserved");
1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        vtz->getLastModified(lmod);
1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (lastmod != lmod) {
1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: LAST-MODIFIED was not preserved");
1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Set different tzurl
1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newvtz1->setTZURL(TESTURL2);
1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Second roundtrip, with a cutover
1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newvtz1->write(vtzdata, status);
1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: error returned while writing VTIMEZONE data 2");
1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            VTimeZone *newvtz2 = VTimeZone::createVTimeZone(vtzdata, status);
1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: error returned while loading VTIMEZONE data 2");
1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // Check if TZURL and LAST-MODIFIED properties are preserved
1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                newvtz2->getTZURL(tzurl);
1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (tzurl != TESTURL2) {
1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: TZURL was not preserved in the second roundtrip");
1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vtz->getLastModified(lmod);
1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (lastmod != lmod) {
1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: LAST-MODIFIED was not preserved in the second roundtrip");
1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete newvtz2;
1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete newvtz1;
1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete vtz;
1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Extract simple rules from an OlsonTimeZone and make sure the rule format matches
1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the expected format.
1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestGetSimpleRules(void) {
1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate testTimes[] = {
1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(1970, UCAL_JANUARY, 1),
1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2000, UCAL_MARCH, 31),
1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2005, UCAL_JULY, 1),
1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getUTCMillis(2010, UCAL_NOVEMBER, 1),
1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
11168de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert    int32_t numTimes = UPRV_LENGTHOF(testTimes);
1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TestZIDEnumeration tzenum(!quick);
1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *initial;
1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *std, *dst;
1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < numTimes ; i++) {
1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        while (TRUE) {
1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const UnicodeString *tzid = tzenum.snext(status);
1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (tzid == NULL) {
1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: error returned while enumerating timezone IDs.");
1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            BasicTimeZone *tz = (BasicTimeZone*)TimeZone::createTimeZone(*tzid);
1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            initial = NULL;
1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            std = dst = NULL;
1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            tz->getSimpleRulesNear(testTimes[i], initial, std, dst, status);
1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: getSimpleRules failed.");
1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (initial == NULL) {
1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: initial rule must not be NULL");
1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
114227f654740f2a26ad62a5c155af9199af9e69b889claireho            } else if (!((std == NULL && dst == NULL) || (std != NULL && dst != NULL))) {
1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: invalid std/dst pair.");
1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (std != NULL) {
1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                const DateTimeRule *dtr = std->getRule();
1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dtr->getDateRuleType() != DateTimeRule::DOW) {
1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: simple std rull must use DateTimeRule::DOW as date rule.");
1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dtr->getTimeRuleType() != DateTimeRule::WALL_TIME) {
1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: simple std rull must use DateTimeRule::WALL_TIME as time rule.");
1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                dtr = dst->getRule();
1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dtr->getDateRuleType() != DateTimeRule::DOW) {
1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: simple dst rull must use DateTimeRule::DOW as date rule.");
1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dtr->getTimeRuleType() != DateTimeRule::WALL_TIME) {
1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: simple dst rull must use DateTimeRule::WALL_TIME as time rule.");
1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    break;
1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Create an RBTZ from the rules and compare the offsets at the date
1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            RuleBasedTimeZone *rbtz = new RuleBasedTimeZone(*tzid, initial);
1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (std != NULL) {
1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                rbtz->addTransitionRule(std, status);
1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (U_FAILURE(status)) {
1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: couldn't add std rule.");
1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                rbtz->addTransitionRule(dst, status);
1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (U_FAILURE(status)) {
1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    errln("FAIL: couldn't add dst rule.");
1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            rbtz->complete(status);
1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: couldn't complete rbtz for " + *tzid);
1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t raw0, dst0, raw1, dst1;
1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            tz->getOffset(testTimes[i], FALSE, raw0, dst0, status);
1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: couldn't get offsets from tz for " + *tzid);
1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            rbtz->getOffset(testTimes[i], FALSE, raw1, dst1, status);
1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: couldn't get offsets from rbtz for " + *tzid);
1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (raw0 != raw1 || dst0 != dst1) {
1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln("FAIL: rbtz created by simple rule does not match the original tz for tzid " + *tzid);
1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete rbtz;
1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete tz;
1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * API coverage tests for TimeZoneRule
1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestTimeZoneRuleCoverage(void) {
1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time1 = getUTCMillis(2005, UCAL_JULY, 4);
1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time2 = getUTCMillis(2015, UCAL_JULY, 4);
1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time3 = getUTCMillis(1950, UCAL_JULY, 4);
1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr1 = new DateTimeRule(UCAL_FEBRUARY, 29, UCAL_SUNDAY, FALSE,
1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            3*HOUR, DateTimeRule::WALL_TIME); // Last Sunday on or before Feb 29, at 3 AM, wall time
1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr2 = new DateTimeRule(UCAL_MARCH, 11, 2*HOUR,
1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            DateTimeRule::STANDARD_TIME); // Mar 11, at 2 AM, standard time
1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr3 = new DateTimeRule(UCAL_OCTOBER, -1, UCAL_SATURDAY,
1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            6*HOUR, DateTimeRule::UTC_TIME); //Last Saturday in Oct, at 6 AM, UTC
1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr4 = new DateTimeRule(UCAL_MARCH, 8, UCAL_SUNDAY, TRUE,
1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            2*HOUR, DateTimeRule::WALL_TIME); // First Sunday on or after Mar 8, at 2 AM, wall time
1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *a1 = new AnnualTimeZoneRule("a1", -3*HOUR, 1*HOUR, *dtr1,
1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            2000, AnnualTimeZoneRule::MAX_YEAR);
1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *a2 = new AnnualTimeZoneRule("a2", -3*HOUR, 1*HOUR, *dtr1,
1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            2000, AnnualTimeZoneRule::MAX_YEAR);
1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *a3 = new AnnualTimeZoneRule("a3", -3*HOUR, 1*HOUR, *dtr1,
1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            2000, 2010);
1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *i1 = new InitialTimeZoneRule("i1", -3*HOUR, 0);
1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *i2 = new InitialTimeZoneRule("i2", -3*HOUR, 0);
1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *i3 = new InitialTimeZoneRule("i3", -3*HOUR, 1*HOUR);
1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate trtimes1[] = {0.0};
1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate trtimes2[] = {0.0, 10000000.0};
1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeArrayTimeZoneRule *t1 = new TimeArrayTimeZoneRule("t1", -3*HOUR, 0, trtimes1, 1, DateTimeRule::UTC_TIME);
1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeArrayTimeZoneRule *t2 = new TimeArrayTimeZoneRule("t2", -3*HOUR, 0, trtimes1, 1, DateTimeRule::UTC_TIME);
1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeArrayTimeZoneRule *t3 = new TimeArrayTimeZoneRule("t3", -3*HOUR, 0, trtimes2, 2, DateTimeRule::UTC_TIME);
1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeArrayTimeZoneRule *t4 = new TimeArrayTimeZoneRule("t4", -3*HOUR, 0, trtimes1, 1, DateTimeRule::STANDARD_TIME);
1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeArrayTimeZoneRule *t5 = new TimeArrayTimeZoneRule("t5", -4*HOUR, 1*HOUR, trtimes1, 1, DateTimeRule::WALL_TIME);
1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // DateTimeRule::operator=/clone
1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule dtr0(UCAL_MAY, 31, 2*HOUR, DateTimeRule::WALL_TIME);
1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dtr0 == *dtr1 || !(dtr0 != *dtr1)) {
1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: DateTimeRule dtr0 is not equal to dtr1, but got wrong result");
1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr0 = *dtr1;
1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dtr0 != *dtr1 || !(dtr0 == *dtr1)) {
1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: DateTimeRule dtr0 is equal to dtr1, but got wrong result");
1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr0c = dtr0.clone();
1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*dtr0c != *dtr1 || !(*dtr0c == *dtr1)) {
1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: DateTimeRule dtr0c is equal to dtr1, but got wrong result");
1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete dtr0c;
1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZonerule::operator=/clone
1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule a0("a0", 5*HOUR, 1*HOUR, *dtr1, 1990, AnnualTimeZoneRule::MAX_YEAR);
1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (a0 == *a1 || !(a0 != *a1)) {
1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule a0 is not equal to a1, but got wrong result");
1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    a0 = *a1;
1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (a0 != *a1 || !(a0 == *a1)) {
1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule a0 is equal to a1, but got wrong result");
1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *a0c = a0.clone();
1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*a0c != *a1 || !(*a0c == *a1)) {
1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule a0c is equal to a1, but got wrong result");
1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete a0c;
1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZoneRule::getRule
1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*(a1->getRule()) != *(a2->getRule())) {
1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: The same DateTimeRule must be returned from AnnualTimeZoneRule a1 and a2");
1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZoneRule::getStartYear
1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t startYear = a1->getStartYear();
1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (startYear != 2000) {
1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: The start year of AnnualTimeZoneRule a1 must be 2000 - returned: " + startYear);
1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZoneRule::getEndYear
1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t endYear = a1->getEndYear();
1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (endYear != AnnualTimeZoneRule::MAX_YEAR) {
1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: The start year of AnnualTimeZoneRule a1 must be MAX_YEAR - returned: " + endYear);
1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    endYear = a3->getEndYear();
1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (endYear != 2010) {
1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: The start year of AnnualTimeZoneRule a3 must be 2010 - returned: " + endYear);
1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZone::getStartInYear
1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool b1, b2;
1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate d1, d2;
1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = a1->getStartInYear(2005, -3*HOUR, 0, d1);
1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b2 = a3->getStartInYear(2005, -3*HOUR, 0, d2);
1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || !b2 || d1 != d2) {
1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule::getStartInYear did not work as expected");
1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b2 = a3->getStartInYear(2015, -3*HOUR, 0, d2);
1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b2) {
1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule::getStartInYear returned TRUE for 2015 which is out of rule range");
1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZone::getFirstStart
1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = a1->getFirstStart(-3*HOUR, 0, d1);
1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b2 = a1->getFirstStart(-4*HOUR, 1*HOUR, d2);
1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || !b2 || d1 != d2) {
1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: The same start time should be returned by getFirstStart");
1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZone::getFinalStart
1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = a1->getFinalStart(-3*HOUR, 0, d1);
1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getFinalStart returned TRUE for a1");
1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = a1->getStartInYear(2010, -3*HOUR, 0, d1);
1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b2 = a3->getFinalStart(-3*HOUR, 0, d2);
1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || !b2 || d1 != d2) {
1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad date is returned by getFinalStart");
1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZone::getNextStart / getPreviousStart
1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = a1->getNextStart(time1, -3*HOUR, 0, FALSE, d1);
1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1) {
1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getNextStart returned FALSE for ai");
1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        b2 = a1->getPreviousStart(d1, -3*HOUR, 0, TRUE, d2);
1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!b2 || d1 != d2) {
1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: Bad Date is returned by getPreviousStart");
1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = a3->getNextStart(time2, -3*HOUR, 0, FALSE, d1);
1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
133350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: getNextStart must return FALSE when no start time is available after the base time");
1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = a3->getFinalStart(-3*HOUR, 0, d1);
1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b2 = a3->getPreviousStart(time2, -3*HOUR, 0, FALSE, d2);
1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || !b2 || d1 != d2) {
133850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: getPreviousStart does not match with getFinalStart after the end year");
1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // AnnualTimeZone::isEquavalentTo
1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!a1->isEquivalentTo(*a2)) {
1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule a1 is equivalent to a2, but returned FALSE");
1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (a1->isEquivalentTo(*a3)) {
1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule a1 is not equivalent to a3, but returned TRUE");
1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!a1->isEquivalentTo(*a1)) {
1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule a1 is equivalent to itself, but returned FALSE");
1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (a1->isEquivalentTo(*t1)) {
1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: AnnualTimeZoneRule is not equivalent to TimeArrayTimeZoneRule, but returned TRUE");
1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // InitialTimezoneRule::operator=/clone
1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule i0("i0", 10*HOUR, 0);
1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (i0 == *i1 || !(i0 != *i1)) {
1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZoneRule i0 is not equal to i1, but got wrong result");
1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    i0 = *i1;
1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (i0 != *i1 || !(i0 == *i1)) {
1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZoneRule i0 is equal to i1, but got wrong result");
1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *i0c = i0.clone();
1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*i0c != *i1 || !(*i0c == *i1)) {
1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZoneRule i0c is equal to i1, but got wrong result");
1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete i0c;
1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // InitialTimeZoneRule::isEquivalentRule
1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!i1->isEquivalentTo(*i2)) {
1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZoneRule i1 is equivalent to i2, but returned FALSE");
1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (i1->isEquivalentTo(*i3)) {
1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZoneRule i1 is not equivalent to i3, but returned TRUE");
1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (i1->isEquivalentTo(*a1)) {
1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: An InitialTimeZoneRule is not equivalent to an AnnualTimeZoneRule, but returned TRUE");
1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // InitialTimeZoneRule::getFirstStart/getFinalStart/getNextStart/getPreviousStart
1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = i1->getFirstStart(0, 0, d1);
1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZone::getFirstStart returned TRUE");
1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = i1->getFinalStart(0, 0, d1);
1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZone::getFinalStart returned TRUE");
1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = i1->getNextStart(time1, 0, 0, FALSE, d1);
1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZone::getNextStart returned TRUE");
1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = i1->getPreviousStart(time1, 0, 0, FALSE, d1);
1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: InitialTimeZone::getPreviousStart returned TRUE");
1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeArrayTimeZoneRule::operator=/clone
1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeArrayTimeZoneRule t0("t0", 4*HOUR, 0, trtimes1, 1, DateTimeRule::UTC_TIME);
1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t0 == *t1 || !(t0 != *t1)) {
1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t0 is not equal to t1, but got wrong result");
1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    t0 = *t1;
1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t0 != *t1 || !(t0 == *t1)) {
1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t0 is equal to t1, but got wrong result");
1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeArrayTimeZoneRule *t0c = t0.clone();
1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*t0c != *t1 || !(*t0c == *t1)) {
1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t0c is equal to t1, but got wrong result");
1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete t0c;
1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeArrayTimeZoneRule::countStartTimes
1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t1->countStartTimes() != 1) {
1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad start time count is returned by TimeArrayTimeZoneRule::countStartTimes");
1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeArrayTimeZoneRule::getStartTimeAt
1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t1->getStartTimeAt(-1, d1);
1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule::getStartTimeAt returned TRUE for index -1");
1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t1->getStartTimeAt(0, d1);
1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || d1 != trtimes1[0]) {
1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule::getStartTimeAt returned incorrect result for index 0");
1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t1->getStartTimeAt(1, d1);
1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule::getStartTimeAt returned TRUE for index 1");
1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeArrayTimeZoneRule::getTimeType
1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t1->getTimeType() != DateTimeRule::UTC_TIME) {
1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t1 uses UTC_TIME, but different type is returned");
1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t4->getTimeType() != DateTimeRule::STANDARD_TIME) {
1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t4 uses STANDARD_TIME, but different type is returned");
1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t5->getTimeType() != DateTimeRule::WALL_TIME) {
1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t5 uses WALL_TIME, but different type is returned");
1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeArrayTimeZoneRule::getFirstStart/getFinalStart
1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t1->getFirstStart(0, 0, d1);
1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || d1 != trtimes1[0]) {
1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad first start time returned from TimeArrayTimeZoneRule t1");
1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t1->getFinalStart(0, 0, d1);
1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || d1 != trtimes1[0]) {
1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad final start time returned from TimeArrayTimeZoneRule t1");
1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t4->getFirstStart(-4*HOUR, 1*HOUR, d1);
1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || d1 != (trtimes1[0] + 4*HOUR)) {
1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad first start time returned from TimeArrayTimeZoneRule t4");
1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t5->getFirstStart(-4*HOUR, 1*HOUR, d1);
1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || d1 != (trtimes1[0] + 3*HOUR)) {
1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad first start time returned from TimeArrayTimeZoneRule t5");
1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeArrayTimeZoneRule::getNextStart/getPreviousStart
1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t3->getNextStart(time1, -3*HOUR, 1*HOUR, FALSE, d1);
1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
146550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: getNextStart returned TRUE after the final transition for t3");
1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t3->getPreviousStart(time1, -3*HOUR, 1*HOUR, FALSE, d1);
1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!b1 || d1 != trtimes2[1]) {
146950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: Bad start time returned by getPreviousStart for t3");
1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        b2 = t3->getPreviousStart(d1, -3*HOUR, 1*HOUR, FALSE, d2);
1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!b2 || d2 != trtimes2[0]) {
1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: Bad start time returned by getPreviousStart for t3");
1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b1 = t3->getPreviousStart(time3, -3*HOUR, 1*HOUR, FALSE, d1); //time3 - year 1950, no result expected
1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (b1) {
1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getPreviousStart returned TRUE before the first transition for t3");
1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeArrayTimeZoneRule::isEquivalentTo
1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!t1->isEquivalentTo(*t2)) {
1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t1 is equivalent to t2, but returned FALSE");
1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t1->isEquivalentTo(*t3)) {
1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t1 is not equivalent to t3, but returned TRUE");
1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t1->isEquivalentTo(*t4)) {
1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule t1 is not equivalent to t4, but returned TRUE");
1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (t1->isEquivalentTo(*a1)) {
1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeArrayTimeZoneRule is not equivalent to AnnualTimeZoneRule, but returned TRUE");
1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete dtr1;
1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete dtr2;
1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete dtr3;
1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete dtr4;
1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete a1;
1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete a2;
1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete a3;
1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete i1;
1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete i2;
1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete i3;
1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete t1;
1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete t2;
1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete t3;
1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete t4;
1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete t5;
1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * API coverage test for BasicTimeZone APIs in SimpleTimeZone
1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestSimpleTimeZoneCoverage(void) {
1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time1 = getUTCMillis(1990, UCAL_JUNE, 1);
1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time2 = getUTCMillis(2000, UCAL_JUNE, 1);
1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZoneTransition tzt1, tzt2;
1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool avail1, avail2;
1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const TimeZoneRule *trrules[2];
1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const InitialTimeZoneRule *ir = NULL;
1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t numTzRules;
1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // BasicTimeZone API implementation in SimpleTimeZone
1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SimpleTimeZone *stz1 = new SimpleTimeZone(-5*HOUR, "GMT-5");
1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    avail1 = stz1->getNextTransition(time1, FALSE, tzt1);
1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (avail1) {
1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: No transition must be returned by getNextTranstion for SimpleTimeZone with no DST rule");
1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    avail1 = stz1->getPreviousTransition(time1, FALSE, tzt1);
1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (avail1) {
1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: No transition must be returned by getPreviousTransition  for SimpleTimeZone with no DST rule");
1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    numTzRules = stz1->countTransitionRules(status);
1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: countTransitionRules failed");
1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (numTzRules != 0) {
1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: countTransitionRules returned " + numTzRules);
1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    numTzRules = 2;
1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    stz1->getTimeZoneRules(ir, trrules, numTzRules, status);
1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getTimeZoneRules failed");
1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (numTzRules != 0) {
1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Incorrect transition rule count");
1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (ir == NULL || ir->getRawOffset() != stz1->getRawOffset()) {
1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad initial time zone rule");
1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Set DST rule
1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    stz1->setStartRule(UCAL_MARCH, 11, 2*HOUR, status); // March 11
1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    stz1->setEndRule(UCAL_NOVEMBER, 1, UCAL_SUNDAY, 2*HOUR, status); // First Sunday in November
1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Failed to set DST rules in a SimpleTimeZone");
1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    avail1 = stz1->getNextTransition(time1, FALSE, tzt1);
1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!avail1) {
1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Non-null transition must be returned by getNextTranstion for SimpleTimeZone with a DST rule");
1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    avail1 = stz1->getPreviousTransition(time1, FALSE, tzt1);
1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!avail1) {
1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Non-null transition must be returned by getPreviousTransition  for SimpleTimeZone with a DST rule");
1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    numTzRules = stz1->countTransitionRules(status);
1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: countTransitionRules failed");
1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (numTzRules != 2) {
1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln((UnicodeString)"FAIL: countTransitionRules returned " + numTzRules);
1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    numTzRules = 2;
1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    trrules[0] = NULL;
1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    trrules[1] = NULL;
1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    stz1->getTimeZoneRules(ir, trrules, numTzRules, status);
1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getTimeZoneRules failed");
1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (numTzRules != 2) {
1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Incorrect transition rule count");
1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (ir == NULL || ir->getRawOffset() != stz1->getRawOffset()) {
1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad initial time zone rule");
1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (trrules[0] == NULL || trrules[0]->getRawOffset() != stz1->getRawOffset()) {
1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad transition rule 0");
1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (trrules[1] == NULL || trrules[1]->getRawOffset() != stz1->getRawOffset()) {
1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad transition rule 1");
1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Set DST start year
1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    stz1->setStartYear(2007);
1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    avail1 = stz1->getPreviousTransition(time1, FALSE, tzt1);
1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (avail1) {
1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: No transition must be returned before 1990");
1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    avail1 = stz1->getNextTransition(time1, FALSE, tzt1); // transition after 1990-06-01
1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    avail2 = stz1->getNextTransition(time2, FALSE, tzt2); // transition after 2000-06-01
1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!avail1 || !avail2 || tzt1 != tzt2) {
1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Bad transition returned by SimpleTimeZone::getNextTransition");
1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete stz1;
1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * API coverage test for VTimeZone
1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestVTimeZoneCoverage(void) {
1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString TZID("Europe/Moscow");
1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *otz = (BasicTimeZone*)TimeZone::createTimeZone(TZID);
1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *vtz = VTimeZone::createVTimeZoneByID(TZID);
1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getOffset(era, year, month, day, dayOfWeek, milliseconds, ec)
1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t offset1 = otz->getOffset(GregorianCalendar::AD, 2007, UCAL_JULY, 1, UCAL_SUNDAY, 0, status);
1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(7 args) failed for otz");
1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t offset2 = vtz->getOffset(GregorianCalendar::AD, 2007, UCAL_JULY, 1, UCAL_SUNDAY, 0, status);
1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(7 args) failed for vtz");
1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset1 != offset2) {
1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(7 args) returned different results in VTimeZone and OlsonTimeZone");
1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getOffset(era, year, month, day, dayOfWeek, milliseconds, monthLength, ec)
1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    offset1 = otz->getOffset(GregorianCalendar::AD, 2007, UCAL_JULY, 1, UCAL_SUNDAY, 0, 31, status);
1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(8 args) failed for otz");
1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    offset2 = vtz->getOffset(GregorianCalendar::AD, 2007, UCAL_JULY, 1, UCAL_SUNDAY, 0, 31, status);
1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(8 args) failed for vtz");
1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset1 != offset2) {
1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(8 args) returned different results in VTimeZone and OlsonTimeZone");
1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getOffset(date, local, rawOffset, dstOffset, ec)
1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate t = Calendar::getNow();
1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t rawOffset1, dstSavings1;
1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t rawOffset2, dstSavings2;
1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    otz->getOffset(t, FALSE, rawOffset1, dstSavings1, status);
1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(5 args) failed for otz");
1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    vtz->getOffset(t, FALSE, rawOffset2, dstSavings2, status);
1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(5 args) failed for vtz");
1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (rawOffset1 != rawOffset2 || dstSavings1 != dstSavings2) {
1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getOffset(long,boolean,int[]) returned different results in VTimeZone and OlsonTimeZone");
1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getRawOffset
1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (otz->getRawOffset() != vtz->getRawOffset()) {
1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getRawOffset returned different results in VTimeZone and OlsonTimeZone");
1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // inDaylightTime
1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool inDst1, inDst2;
1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inDst1 = otz->inDaylightTime(t, status);
1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
168050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: inDaylightTime failed for otz: %s", u_errorName(status));
1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inDst2 = vtz->inDaylightTime(t, status);
1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
168450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: inDaylightTime failed for vtz: %s", u_errorName(status));
1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (inDst1 != inDst2) {
1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: inDaylightTime returned different results in VTimeZone and OlsonTimeZone");
1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // useDaylightTime
1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (otz->useDaylightTime() != vtz->useDaylightTime()) {
1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: useDaylightTime returned different results in VTimeZone and OlsonTimeZone");
1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // setRawOffset
1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t RAW = -10*HOUR;
1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *tmpvtz = (VTimeZone*)vtz->clone();
1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tmpvtz->setRawOffset(RAW);
1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tmpvtz->getRawOffset() != RAW) {
1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("setRawOffset is implemented in VTimeZone");
1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // hasSameRules
1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool bSame = otz->hasSameRules(*vtz);
1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln((UnicodeString)"OlsonTimeZone::hasSameRules(VTimeZone) should return FALSE always for now - actual: " + bSame);
1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getTZURL/setTZURL
1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString TZURL("http://icu-project.org/timezone");
1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString url;
1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (vtz->getTZURL(url)) {
1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getTZURL returned TRUE");
1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    vtz->setTZURL(TZURL);
1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!vtz->getTZURL(url) || url != TZURL) {
1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: URL returned by getTZURL does not match the one set by setTZURL");
1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getLastModified/setLastModified
1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate lastmod;
1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (vtz->getLastModified(lastmod)) {
1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: getLastModified returned TRUE");
1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    vtz->setLastModified(t);
1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!vtz->getLastModified(lastmod) || lastmod != t) {
1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Date returned by getLastModified does not match the one set by setLastModified");
1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // getNextTransition/getPreviousTransition
1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate base = getUTCMillis(2007, UCAL_JULY, 1);
1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZoneTransition tzt1, tzt2;
1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool btr1 = otz->getNextTransition(base, TRUE, tzt1);
1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool btr2 = vtz->getNextTransition(base, TRUE, tzt2);
1733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!btr1 || !btr2 || tzt1 != tzt2) {
173485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("FAIL: getNextTransition returned different results in VTimeZone and OlsonTimeZone");
1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    btr1 = otz->getPreviousTransition(base, FALSE, tzt1);
1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    btr2 = vtz->getPreviousTransition(base, FALSE, tzt2);
1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!btr1 || !btr2 || tzt1 != tzt2) {
173985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        dataerrln("FAIL: getPreviousTransition returned different results in VTimeZone and OlsonTimeZone");
1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TimeZoneTransition constructor/clone
1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZoneTransition *tzt1c = tzt1.clone();
1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*tzt1c != tzt1 || !(*tzt1c == tzt1)) {
1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeZoneTransition tzt1c is equal to tzt1, but got wrong result");
1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete tzt1c;
1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZoneTransition tzt3(tzt1);
1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tzt3 != tzt1 || !(tzt3 == tzt1)) {
1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: TimeZoneTransition tzt3 is equal to tzt1, but got wrong result");
1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // hasEquivalentTransitions
1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time1 = getUTCMillis(1950, UCAL_JANUARY, 1);
1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time2 = getUTCMillis(2020, UCAL_JANUARY, 1);
1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool equiv = vtz->hasEquivalentTransitions(*otz, time1, time2, FALSE, status);
1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
175850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: hasEquivalentTransitions failed for vtz/otz: %s", u_errorName(status));
1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!equiv) {
176150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: hasEquivalentTransitons returned false for the same time zone");
1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // operator=/operator==/operator!=
1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *vtz1 = VTimeZone::createVTimeZoneByID("America/Los_Angeles");
1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*vtz1 == *vtz || !(*vtz1 != *vtz)) {
1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: VTimeZone vtz1 is not equal to vtz, but got wrong result");
1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *vtz1 = *vtz;
1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (*vtz1 != *vtz || !(*vtz1 == *vtz)) {
1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: VTimeZone vtz1 is equal to vtz, but got wrong result");
1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
177427f654740f2a26ad62a5c155af9199af9e69b889claireho    // Creation from BasicTimeZone
177527f654740f2a26ad62a5c155af9199af9e69b889claireho    //
177627f654740f2a26ad62a5c155af9199af9e69b889claireho    status = U_ZERO_ERROR;
177727f654740f2a26ad62a5c155af9199af9e69b889claireho    VTimeZone *vtzFromBasic = NULL;
177827f654740f2a26ad62a5c155af9199af9e69b889claireho    SimpleTimeZone *simpleTZ = new SimpleTimeZone(28800000, "Asia/Singapore");
177927f654740f2a26ad62a5c155af9199af9e69b889claireho    simpleTZ->setStartYear(1970);
178027f654740f2a26ad62a5c155af9199af9e69b889claireho    simpleTZ->setStartRule(0,  // month
178127f654740f2a26ad62a5c155af9199af9e69b889claireho                          1,  // day of week
178227f654740f2a26ad62a5c155af9199af9e69b889claireho                          0,  // time
178327f654740f2a26ad62a5c155af9199af9e69b889claireho                          status);
178427f654740f2a26ad62a5c155af9199af9e69b889claireho    simpleTZ->setEndRule(1, 1, 0, status);
178527f654740f2a26ad62a5c155af9199af9e69b889claireho    if (U_FAILURE(status)) {
178627f654740f2a26ad62a5c155af9199af9e69b889claireho        errln("File %s, line %d, failed with status = %s", __FILE__, __LINE__, u_errorName(status));
178727f654740f2a26ad62a5c155af9199af9e69b889claireho        goto end_basic_tz_test;
178827f654740f2a26ad62a5c155af9199af9e69b889claireho    }
178927f654740f2a26ad62a5c155af9199af9e69b889claireho    vtzFromBasic = VTimeZone::createVTimeZoneFromBasicTimeZone(*simpleTZ, status);
179027f654740f2a26ad62a5c155af9199af9e69b889claireho    if (U_FAILURE(status) || vtzFromBasic == NULL) {
179127f654740f2a26ad62a5c155af9199af9e69b889claireho        dataerrln("File %s, line %d, failed with status = %s", __FILE__, __LINE__, u_errorName(status));
179227f654740f2a26ad62a5c155af9199af9e69b889claireho        goto end_basic_tz_test;
179327f654740f2a26ad62a5c155af9199af9e69b889claireho    }
179427f654740f2a26ad62a5c155af9199af9e69b889claireho
179527f654740f2a26ad62a5c155af9199af9e69b889claireho    // delete the source time zone, to make sure there are no dependencies on it.
179627f654740f2a26ad62a5c155af9199af9e69b889claireho    delete simpleTZ;
179727f654740f2a26ad62a5c155af9199af9e69b889claireho
179827f654740f2a26ad62a5c155af9199af9e69b889claireho    // Create another simple time zone w the same rules, and check that it is the
179927f654740f2a26ad62a5c155af9199af9e69b889claireho    // same as the test VTimeZone created above.
180027f654740f2a26ad62a5c155af9199af9e69b889claireho    {
180127f654740f2a26ad62a5c155af9199af9e69b889claireho        SimpleTimeZone simpleTZ2(28800000, "Asia/Singapore");
180227f654740f2a26ad62a5c155af9199af9e69b889claireho        simpleTZ2.setStartYear(1970);
180327f654740f2a26ad62a5c155af9199af9e69b889claireho        simpleTZ2.setStartRule(0,  // month
180427f654740f2a26ad62a5c155af9199af9e69b889claireho                              1,  // day of week
180527f654740f2a26ad62a5c155af9199af9e69b889claireho                              0,  // time
180627f654740f2a26ad62a5c155af9199af9e69b889claireho                              status);
180727f654740f2a26ad62a5c155af9199af9e69b889claireho        simpleTZ2.setEndRule(1, 1, 0, status);
180827f654740f2a26ad62a5c155af9199af9e69b889claireho        if (U_FAILURE(status)) {
180927f654740f2a26ad62a5c155af9199af9e69b889claireho            errln("File %s, line %d, failed with status = %s", __FILE__, __LINE__, u_errorName(status));
181027f654740f2a26ad62a5c155af9199af9e69b889claireho            goto end_basic_tz_test;
181127f654740f2a26ad62a5c155af9199af9e69b889claireho        }
181227f654740f2a26ad62a5c155af9199af9e69b889claireho        if (vtzFromBasic->hasSameRules(simpleTZ2) == FALSE) {
181327f654740f2a26ad62a5c155af9199af9e69b889claireho            errln("File %s, line %d, failed hasSameRules() ", __FILE__, __LINE__);
181427f654740f2a26ad62a5c155af9199af9e69b889claireho            goto end_basic_tz_test;
181527f654740f2a26ad62a5c155af9199af9e69b889claireho        }
181627f654740f2a26ad62a5c155af9199af9e69b889claireho    }
181727f654740f2a26ad62a5c155af9199af9e69b889clairehoend_basic_tz_test:
181827f654740f2a26ad62a5c155af9199af9e69b889claireho    delete vtzFromBasic;
181927f654740f2a26ad62a5c155af9199af9e69b889claireho
1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete otz;
1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete vtz;
1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete tmpvtz;
1823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete vtz1;
1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::TestVTimeZoneParse(void) {
1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Trying to create VTimeZone from empty data
1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString emptyData;
1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *empty = VTimeZone::createVTimeZone(emptyData, status);
1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status) || empty != NULL) {
1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete empty;
1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Non-null VTimeZone is returned for empty VTIMEZONE data");
1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    status = U_ZERO_ERROR;
1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Create VTimeZone for Asia/Tokyo
1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString asiaTokyoID("Asia/Tokyo");
1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const UChar asiaTokyo[] = {
1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "BEGIN:VTIMEZONE\x0D\x0A" */
1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x42,0x45,0x47,0x49,0x4E,0x3A,0x56,0x54,0x49,0x4D,0x45,0x5A,0x4F,0x4E,0x45,0x0D,0x0A,
1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZID:Asia\x0D\x0A" */
1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x49,0x44,0x3A,0x41,0x73,0x69,0x61,0x0D,0x0A,
1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "\x09/Tokyo\x0D\x0A" */
1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x09,0x2F,0x54,0x6F,0x6B,0x79,0x6F,0x0D,0x0A,
1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "BEGIN:STANDARD\x0D\x0A" */
1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x42,0x45,0x47,0x49,0x4E,0x3A,0x53,0x54,0x41,0x4E,0x44,0x41,0x52,0x44,0x0D,0x0A,
1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZOFFSETFROM:+0900\x0D\x0A" */
1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4F,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4F,0x4D,0x3A,0x2B,0x30,0x39,0x30,0x30,0x0D,0x0A,
1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZOFFSETTO:+0900\x0D\x0A" */
1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4F,0x46,0x46,0x53,0x45,0x54,0x54,0x4F,0x3A,0x2B,0x30,0x39,0x30,0x30,0x0D,0x0A,
1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZNAME:JST\x0D\x0A" */
1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4E,0x41,0x4D,0x45,0x3A,0x4A,0x53,0x54,0x0D,0x0A,
1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "DTSTART:19700101\x0D\x0A" */
1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3A,0x31,0x39,0x37,0x30,0x30,0x31,0x30,0x31,0x0D,0x0A,
1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* " T000000\x0D\x0A" */
1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x20,0x54,0x30,0x30,0x30,0x30,0x30,0x30,0x0D,0x0A,
1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "END:STANDARD\x0D\x0A" */
1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x45,0x4E,0x44,0x3A,0x53,0x54,0x41,0x4E,0x44,0x41,0x52,0x44,0x0D,0x0A,
1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "END:VTIMEZONE" */
1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x45,0x4E,0x44,0x3A,0x56,0x54,0x49,0x4D,0x45,0x5A,0x4F,0x4E,0x45,
1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0
1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *tokyo = VTimeZone::createVTimeZone(asiaTokyo, status);
1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status) || tokyo == NULL) {
1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Failed to create a VTimeZone tokyo");
1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Check ID
1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString tzid;
1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tokyo->getID(tzid);
1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzid != asiaTokyoID) {
1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: Invalid TZID: " + tzid);
1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Make sure offsets are correct
1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t rawOffset, dstSavings;
1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tokyo->getOffset(Calendar::getNow(), FALSE, rawOffset, dstSavings, status);
1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: getOffset failed for tokyo");
1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (rawOffset != 9*HOUR || dstSavings != 0) {
1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: Bad offsets returned by a VTimeZone created for Tokyo");
1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete tokyo;
1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Create VTimeZone from VTIMEZONE data
1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const UChar fooData[] = {
1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "BEGIN:VCALENDAR\x0D\x0A" */
1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x42,0x45,0x47,0x49,0x4E,0x3A,0x56,0x43,0x41,0x4C,0x45,0x4E,0x44,0x41,0x52,0x0D,0x0A,
1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "BEGIN:VTIMEZONE\x0D\x0A" */
1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x42,0x45,0x47,0x49,0x4E,0x3A,0x56,0x54,0x49,0x4D,0x45,0x5A,0x4F,0x4E,0x45,0x0D,0x0A,
1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZID:FOO\x0D\x0A" */
1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x49,0x44,0x3A,0x46,0x4F,0x4F,0x0D,0x0A,
1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "BEGIN:STANDARD\x0D\x0A" */
1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x42,0x45,0x47,0x49,0x4E,0x3A,0x53,0x54,0x41,0x4E,0x44,0x41,0x52,0x44,0x0D,0x0A,
1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZOFFSETFROM:-0700\x0D\x0A" */
1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4F,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4F,0x4D,0x3A,0x2D,0x30,0x37,0x30,0x30,0x0D,0x0A,
1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZOFFSETTO:-0800\x0D\x0A" */
1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4F,0x46,0x46,0x53,0x45,0x54,0x54,0x4F,0x3A,0x2D,0x30,0x38,0x30,0x30,0x0D,0x0A,
1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZNAME:FST\x0D\x0A" */
1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4E,0x41,0x4D,0x45,0x3A,0x46,0x53,0x54,0x0D,0x0A,
1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "DTSTART:20071010T010000\x0D\x0A" */
1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3A,0x32,0x30,0x30,0x37,0x31,0x30,0x31,0x30,0x54,0x30,0x31,0x30,0x30,0x30,0x30,0x0D,0x0A,
1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "RRULE:FREQ=YEARLY;BYDAY=WE;BYMONTHDAY=10,11,12,13,14,15,16;BYMONTH=10\x0D\x0A" */
1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x52,0x52,0x55,0x4C,0x45,0x3A,0x46,0x52,0x45,0x51,0x3D,0x59,0x45,0x41,0x52,0x4C,0x59,0x3B,0x42,0x59,0x44,0x41,0x59,0x3D,0x57,0x45,0x3B,0x42,0x59,0x4D,0x4F,0x4E,0x54,0x48,0x44,0x41,0x59,0x3D,0x31,0x30,0x2C,0x31,0x31,0x2C,0x31,0x32,0x2C,0x31,0x33,0x2C,0x31,0x34,0x2C,0x31,0x35,0x2C,0x31,0x36,0x3B,0x42,0x59,0x4D,0x4F,0x4E,0x54,0x48,0x3D,0x31,0x30,0x0D,0x0A,
1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "END:STANDARD\x0D\x0A" */
1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x45,0x4E,0x44,0x3A,0x53,0x54,0x41,0x4E,0x44,0x41,0x52,0x44,0x0D,0x0A,
1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "BEGIN:DAYLIGHT\x0D\x0A" */
1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x42,0x45,0x47,0x49,0x4E,0x3A,0x44,0x41,0x59,0x4C,0x49,0x47,0x48,0x54,0x0D,0x0A,
1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZOFFSETFROM:-0800\x0D\x0A" */
1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4F,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4F,0x4D,0x3A,0x2D,0x30,0x38,0x30,0x30,0x0D,0x0A,
1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZOFFSETTO:-0700\x0D\x0A" */
1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4F,0x46,0x46,0x53,0x45,0x54,0x54,0x4F,0x3A,0x2D,0x30,0x37,0x30,0x30,0x0D,0x0A,
1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "TZNAME:FDT\x0D\x0A" */
1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x54,0x5A,0x4E,0x41,0x4D,0x45,0x3A,0x46,0x44,0x54,0x0D,0x0A,
1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "DTSTART:20070415T010000\x0D\x0A" */
1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3A,0x32,0x30,0x30,0x37,0x30,0x34,0x31,0x35,0x54,0x30,0x31,0x30,0x30,0x30,0x30,0x0D,0x0A,
1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "RRULE:FREQ=YEARLY;BYMONTHDAY=15;BYMONTH=4\x0D\x0A" */
1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x52,0x52,0x55,0x4C,0x45,0x3A,0x46,0x52,0x45,0x51,0x3D,0x59,0x45,0x41,0x52,0x4C,0x59,0x3B,0x42,0x59,0x4D,0x4F,0x4E,0x54,0x48,0x44,0x41,0x59,0x3D,0x31,0x35,0x3B,0x42,0x59,0x4D,0x4F,0x4E,0x54,0x48,0x3D,0x34,0x0D,0x0A,
1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "END:DAYLIGHT\x0D\x0A" */
1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x45,0x4E,0x44,0x3A,0x44,0x41,0x59,0x4C,0x49,0x47,0x48,0x54,0x0D,0x0A,
1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "END:VTIMEZONE\x0D\x0A" */
1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x45,0x4E,0x44,0x3A,0x56,0x54,0x49,0x4D,0x45,0x5A,0x4F,0x4E,0x45,0x0D,0x0A,
1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* "END:VCALENDAR" */
1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0x45,0x4E,0x44,0x3A,0x56,0x43,0x41,0x4C,0x45,0x4E,0x44,0x41,0x52,
1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        0
1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    VTimeZone *foo = VTimeZone::createVTimeZone(fooData, status);
1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status) || foo == NULL) {
1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Failed to create a VTimeZone foo");
1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Write VTIMEZONE data
1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString fooData2;
1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        foo->write(getUTCMillis(2005, UCAL_JANUARY, 1), fooData2, status);
1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: Failed to write VTIMEZONE data for foo");
1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(fooData2);
1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete foo;
1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
194785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
194885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeZoneRuleTest::TestT6216(void) {
194985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Test case in #6216
195085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const UChar tokyoTZ[] = {
195185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:VCALENDAR\r\n" */
195285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
195385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "VERSION:2.0\r\n" */
195485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x3a,0x32,0x2e,0x30,0x0d,0x0a,
195585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "PRODID:-//PYVOBJECT//NONSGML Version 1//EN\r\n" */
195685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x50,0x52,0x4f,0x44,0x49,0x44,0x3a,0x2d,0x2f,0x2f,0x50,0x59,0x56,0x4f,0x42,0x4a,0x45,0x43,0x54,0x2f,0x2f,0x4e,0x4f,0x4e,0x53,0x47,0x4d,0x4c,0x20,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2f,0x2f,0x45,0x4e,0x0d,0x0a,
195785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:VTIMEZONE\r\n" */
195885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
195985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZID:Asia/Tokyo\r\n" */
196085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x49,0x44,0x3a,0x41,0x73,0x69,0x61,0x2f,0x54,0x6f,0x6b,0x79,0x6f,0x0d,0x0a,
196185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:STANDARD\r\n" */
196285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
196385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "DTSTART:20000101T000000\r\n" */
196485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x30,0x30,0x31,0x30,0x31,0x54,0x30,0x30,0x30,0x30,0x30,0x30,0x0d,0x0a,
196585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "RRULE:FREQ=YEARLY;BYMONTH=1\r\n" */
196685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x0d,0x0a,
196785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZNAME:Asia/Tokyo\r\n" */
196885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x41,0x73,0x69,0x61,0x2f,0x54,0x6f,0x6b,0x79,0x6f,0x0d,0x0a,
196985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETFROM:+0900\r\n" */
197085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2b,0x30,0x39,0x30,0x30,0x0d,0x0a,
197185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETTO:+0900\r\n" */
197285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2b,0x30,0x39,0x30,0x30,0x0d,0x0a,
197385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:STANDARD\r\n" */
197485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
197585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:VTIMEZONE\r\n" */
197685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
197785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:VCALENDAR" */
197885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
197985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0
198085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
198185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Single final rule, overlapping with another
198285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const UChar finalOverlap[] = {
198385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:VCALENDAR\r\n" */
198485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
198585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:VTIMEZONE\r\n" */
198685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
198785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZID:FinalOverlap\r\n" */
198885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x49,0x44,0x3a,0x46,0x69,0x6e,0x61,0x6c,0x4f,0x76,0x65,0x72,0x6c,0x61,0x70,0x0d,0x0a,
198985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:STANDARD\r\n" */
199085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
199185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETFROM:-0200\r\n" */
199285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
199385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETTO:-0300\r\n" */
199485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
199585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZNAME:STD\r\n" */
199685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x53,0x54,0x44,0x0d,0x0a,
199785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "DTSTART:20001029T020000\r\n" */
199885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x30,0x31,0x30,0x32,0x39,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
199985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10\r\n" */
200085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x2d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x30,0x0d,0x0a,
200185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:STANDARD\r\n" */
200285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
200385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:DAYLIGHT\r\n" */
200485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
200585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETFROM:-0300\r\n" */
200685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
200785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETTO:-0200\r\n" */
200885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
200985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZNAME:DST\r\n" */
201085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x44,0x53,0x54,0x0d,0x0a,
201185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "DTSTART:19990404T020000\r\n" */
201285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x31,0x39,0x39,0x39,0x30,0x34,0x30,0x34,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
201385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T040000Z\r\n" */
201485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x34,0x3b,0x55,0x4e,0x54,0x49,0x4c,0x3d,0x32,0x30,0x30,0x35,0x30,0x34,0x30,0x33,0x54,0x30,0x34,0x30,0x30,0x30,0x30,0x5a,0x0d,0x0a,
201585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:DAYLIGHT\r\n" */
201685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
201785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:VTIMEZONE\r\n" */
201885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
201985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:VCALENDAR" */
202085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
202185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0
202285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
202385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Single final rule, no overlapping with another
202485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const UChar finalNonOverlap[] = {
202585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:VCALENDAR\r\n" */
202685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
202785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:VTIMEZONE\r\n" */
202885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
202985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZID:FinalNonOverlap\r\n" */
203085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x49,0x44,0x3a,0x46,0x69,0x6e,0x61,0x6c,0x4e,0x6f,0x6e,0x4f,0x76,0x65,0x72,0x6c,0x61,0x70,0x0d,0x0a,
203185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:STANDARD\r\n" */
203285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
203385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETFROM:-0200\r\n" */
203485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
203585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETTO:-0300\r\n" */
203685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
203785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZNAME:STD\r\n" */
203885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x53,0x54,0x44,0x0d,0x0a,
203985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "DTSTART:20001029T020000\r\n" */
204085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x30,0x31,0x30,0x32,0x39,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
204185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10;UNTIL=20041031T040000Z\r\n" */
204285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x2d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x30,0x3b,0x55,0x4e,0x54,0x49,0x4c,0x3d,0x32,0x30,0x30,0x34,0x31,0x30,0x33,0x31,0x54,0x30,0x34,0x30,0x30,0x30,0x30,0x5a,0x0d,0x0a,
204385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:STANDARD\r\n" */
204485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
204585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:DAYLIGHT\r\n" */
204685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
204785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETFROM:-0300\r\n" */
204885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
204985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETTO:-0200\r\n" */
205085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
205185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZNAME:DST\r\n" */
205285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x44,0x53,0x54,0x0d,0x0a,
205385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "DTSTART:19990404T020000\r\n" */
205485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x31,0x39,0x39,0x39,0x30,0x34,0x30,0x34,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
205585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T040000Z\r\n" */
205685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x34,0x3b,0x55,0x4e,0x54,0x49,0x4c,0x3d,0x32,0x30,0x30,0x35,0x30,0x34,0x30,0x33,0x54,0x30,0x34,0x30,0x30,0x30,0x30,0x5a,0x0d,0x0a,
205785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:DAYLIGHT\r\n" */
205885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
205985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "BEGIN:STANDARD\r\n" */
206085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
206185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETFROM:-0200\r\n" */
206285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
206385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZOFFSETTO:-0300\r\n" */
206485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
206585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "TZNAME:STDFINAL\r\n" */
206685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x53,0x54,0x44,0x46,0x49,0x4e,0x41,0x4c,0x0d,0x0a,
206785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "DTSTART:20071028T020000\r\n" */
206885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x37,0x31,0x30,0x32,0x38,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
206985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10\r\n" */
207085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x2d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x30,0x0d,0x0a,
207185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:STANDARD\r\n" */
207285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
207385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:VTIMEZONE\r\n" */
207485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
207585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        /* "END:VCALENDAR" */
207685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0x45,0x4e,0x44,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
207785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        0
207885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
207985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
208085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    static const int32_t TestDates[][3] = {
208185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {1995, UCAL_JANUARY, 1},
208285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {1995, UCAL_JULY, 1},
208385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {2000, UCAL_JANUARY, 1},
208485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {2000, UCAL_JULY, 1},
208585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {2005, UCAL_JANUARY, 1},
208685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {2005, UCAL_JULY, 1},
208785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {2010, UCAL_JANUARY, 1},
208885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {2010, UCAL_JULY, 1},
208985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {0, 0, 0}
209085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
209185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
209250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /*static*/ const UnicodeString TestZones[] = {
209385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString(tokyoTZ),
209485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString(finalOverlap),
209585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString(finalNonOverlap),
209685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString()
209785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
209885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
209985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t Expected[][8] = {
210085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      //  JAN90      JUL90      JAN00      JUL00      JAN05      JUL05      JAN10      JUL10
210185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        { 32400000,  32400000,  32400000,  32400000,  32400000,  32400000,  32400000,  32400000},
210285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {-10800000, -10800000,  -7200000,  -7200000, -10800000,  -7200000, -10800000, -10800000},
210385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {-10800000, -10800000,  -7200000,  -7200000, -10800000,  -7200000, -10800000, -10800000}
210485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    };
210585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
210685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t i, j;
210785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
210885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Get test times
21098de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert    UDate times[UPRV_LENGTHOF(TestDates)];
211085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t numTimes;
211185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
211285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode status = U_ZERO_ERROR;
211385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    TimeZone *utc = TimeZone::createTimeZone("Etc/GMT");
211485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    GregorianCalendar cal(utc, status);
211585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
211650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: Failed to creat a GregorianCalendar: %s", u_errorName(status));
211785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
211885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
211985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (i = 0; TestDates[i][2] != 0; i++) {
212085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        cal.clear();
212185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        cal.set(TestDates[i][0], TestDates[i][1], TestDates[i][2]);
212285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        times[i] = cal.getTime(status);
212385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
212485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            errln("FAIL: getTime failed");
212585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
212685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
212785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
212885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    numTimes = i;
212985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
213085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Test offset
213185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (i = 0; !TestZones[i].isEmpty(); i++) {
213285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        VTimeZone *vtz = VTimeZone::createVTimeZone(TestZones[i], status);
213385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
213485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            errln("FAIL: failed to create VTimeZone");
213585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            continue;
213685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
213785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        for (j = 0; j < numTimes; j++) {
213885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            int32_t raw, dst;
213985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            status = U_ZERO_ERROR;
214085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            vtz->getOffset(times[j], FALSE, raw, dst, status);
214185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (U_FAILURE(status)) {
214285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                errln((UnicodeString)"FAIL: getOffset failed for time zone " + i + " at " + times[j]);
214385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
214485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            int32_t offset = raw + dst;
214585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (offset != Expected[i][j]) {
214685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                errln((UnicodeString)"FAIL: Invalid offset at time(" + times[j] + "):" + offset + " Expected:" + Expected[i][j]);
214785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
214885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
214985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        delete vtz;
215085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
215185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
215285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
215385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
215485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeZoneRuleTest::TestT6669(void) {
215585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode status = U_ZERO_ERROR;
215685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    SimpleTimeZone stz(0, "CustomID", UCAL_JANUARY, 1, UCAL_SUNDAY, 0, UCAL_JULY, 1, UCAL_SUNDAY, 0, status);
215785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
215885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errln("FAIL: Failed to creat a SimpleTimeZone");
215985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
216085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
216185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
216285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDate t = 1230681600000.0; //2008-12-31T00:00:00
216385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDate expectedNext = 1231027200000.0; //2009-01-04T00:00:00
216485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDate expectedPrev = 1215298800000.0; //2008-07-06T00:00:00
216585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
216685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    TimeZoneTransition tzt;
216785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool avail = stz.getNextTransition(t, FALSE, tzt);
216885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (!avail) {
216985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errln("FAIL: No transition returned by getNextTransition.");
217085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else if (tzt.getTime() != expectedNext) {
217185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errln((UnicodeString)"FAIL: Wrong transition time returned by getNextTransition - "
217285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            + tzt.getTime() + " Expected: " + expectedNext);
217385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
217485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
217585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    avail = stz.getPreviousTransition(t, TRUE, tzt);
217685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (!avail) {
217785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errln("FAIL: No transition returned by getPreviousTransition.");
217885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else if (tzt.getTime() != expectedPrev) {
217985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        errln((UnicodeString)"FAIL: Wrong transition time returned by getPreviousTransition - "
218085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            + tzt.getTime() + " Expected: " + expectedPrev);
218185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
218285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
218385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
218450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
218550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoTimeZoneRuleTest::TestVTimeZoneWrapper(void) {
218650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if 0
218750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // local variables
218850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UBool b;
218950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar * data = NULL;
219050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t length = 0;
219150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t i;
219250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UDate result;
219350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UDate base = 1231027200000.0; //2009-01-04T00:00:00
219450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UErrorCode status;
219550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
219650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    const char *name = "Test Initial";
219750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UChar uname[20];
219850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
219950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UClassID cid1;
220050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UClassID cid2;
220150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
220250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ZRule * r;
220350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    IZRule* ir1;
220450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    IZRule* ir2;
220550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ZTrans* zt1;
220650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ZTrans* zt2;
220750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    VZone*  v1;
220850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    VZone*  v2;
220950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
221050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_memset(uname, 0, sizeof(uname));
221150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    u_uastrcpy(uname, name);
221250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
221350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // create rules
221450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ir1 = izrule_open(uname, 13, 2*HOUR, 0);
221550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ir2 = izrule_clone(ir1);
221650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
221750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test equality
221850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = izrule_equals(ir1, ir2);
221950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = izrule_isEquivalentTo(ir1, ir2);
222050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
222150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test accessors
222250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    izrule_getName(ir1, data, length);
222350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    i = izrule_getRawOffset(ir1);
222450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    i = izrule_getDSTSavings(ir1);
222550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
222650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = izrule_getFirstStart(ir1, 2*HOUR, 0, result);
222750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = izrule_getFinalStart(ir1, 2*HOUR, 0, result);
222850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = izrule_getNextStart(ir1, base , 2*HOUR, 0, true, result);
222950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = izrule_getPreviousStart(ir1, base, 2*HOUR, 0, true, result);
223050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
223150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test class ids
223250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    cid1 = izrule_getStaticClassID(ir1);
223350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    cid2 = izrule_getDynamicClassID(ir1);
223450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
223550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test transitions
223650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    zt1 = ztrans_open(base, ir1, ir2);
223750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    zt2 = ztrans_clone(zt1);
223850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    zt2 = ztrans_openEmpty();
223950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
224050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test equality
224150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = ztrans_equals(zt1, zt2);
224250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
224350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test accessors
224450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    result = ztrans_getTime(zt1);
224550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ztrans_setTime(zt1, result);
224650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
224750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    r = (ZRule*)ztrans_getFrom(zt1);
224850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ztrans_setFrom(zt1, (void*)ir1);
224950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ztrans_adoptFrom(zt1, (void*)ir1);
225050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
225150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    r = (ZRule*)ztrans_getTo(zt1);
225250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ztrans_setTo(zt1, (void*)ir2);
225350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ztrans_adoptTo(zt1, (void*)ir2);
225450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
225550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test class ids
225650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    cid1 = ztrans_getStaticClassID(zt1);
225750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    cid2 = ztrans_getDynamicClassID(zt2);
225850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
225950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test vzone
226050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    v1 = vzone_openID((UChar*)"America/Chicago", sizeof("America/Chicago"));
226150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    v2 = vzone_clone(v1);
226250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    //v2 = vzone_openData(const UChar* vtzdata, int32_t vtzdataLength, UErrorCode& status);
226350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
226450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test equality
226550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_equals(v1, v2);
226650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_hasSameRules(v1, v2);
226750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
226850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test accessors
226950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_getTZURL(v1, data, length);
227050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_setTZURL(v1, data, length);
227150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
227250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_getLastModified(v1, result);
227350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_setLastModified(v1, result);
227450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
227550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test writers
227650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_write(v1, data, length, status);
227750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_writeFromStart(v1, result, data, length, status);
227850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_writeSimple(v1, result, data, length, status);
227950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
228050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // test more accessors
228150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    i = vzone_getRawOffset(v1);
228250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_setRawOffset(v1, i);
228350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
228450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_useDaylightTime(v1);
228550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_inDaylightTime(v1, result, status);
228650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
228750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_getNextTransition(v1, result, false, zt1);
228850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    b = vzone_getPreviousTransition(v1, result, false, zt1);
228950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    i = vzone_countTransitionRules(v1, status);
229050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
229150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    cid1 = vzone_getStaticClassID(v1);
229250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    cid2 = vzone_getDynamicClassID(v1);
229350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
229450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    // cleanup
229550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_close(v1);
229650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    vzone_close(v2);
229750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ztrans_close(zt1);
229850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ztrans_close(zt2);
229950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
230050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
230150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//----------- private test helpers -------------------------------------------------
2303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUDate
2305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::getUTCMillis(int32_t y, int32_t m, int32_t d,
2306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               int32_t hr, int32_t min, int32_t sec, int32_t msec) {
2307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
2308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const TimeZone *tz = TimeZone::getGMT();
2309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Calendar *cal = Calendar::createInstance(*tz, status);
2310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
2311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete cal;
231250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("FAIL: Calendar::createInstance failed: %s", u_errorName(status));
2313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0.0;
2314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->set(y, m, d, hr, min, sec);
2316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->set(UCAL_MILLISECOND, msec);
2317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate utc = cal->getTime(status);
2318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
2319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete cal;
2320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: Calendar::getTime failed");
2321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0.0;
2322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete cal;
2324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return utc;
2325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Check if a time shift really happens on each transition returned by getNextTransition or
2329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * getPreviousTransition in the specified time range
2330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
2332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::verifyTransitions(BasicTimeZone& icutz, UDate start, UDate end) {
2333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
2334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time;
2335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t raw, dst, raw0, dst0;
2336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZoneTransition tzt, tzt0;
2337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool avail;
2338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool first = TRUE;
2339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString tzid;
2340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Ascending
2342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time = start;
2343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
2344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        avail = icutz.getNextTransition(time, FALSE, tzt);
2345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!avail) {
2346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        time = tzt.getTime();
2349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (time >= end) {
2350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        icutz.getOffset(time, FALSE, raw, dst, status);
2353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        icutz.getOffset(time - 1, FALSE, raw0, dst0, status);
2354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
2355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: Error in getOffset");
2356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (raw == raw0 && dst == dst0) {
2360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: False transition returned by getNextTransition for "
2361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                + icutz.getID(tzid) + " at " + dateToString(time));
2362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!first &&
2364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (tzt0.getTo()->getRawOffset() != tzt.getFrom()->getRawOffset()
2365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                || tzt0.getTo()->getDSTSavings() != tzt.getFrom()->getDSTSavings())) {
2366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: TO rule of the previous transition does not match FROM rule of this transtion at "
2367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    + dateToString(time) + " for " + icutz.getID(tzid));
2368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tzt0 = tzt;
2370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        first = FALSE;
2371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Descending
2374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    first = TRUE;
2375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    time = end;
2376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while(true) {
2377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        avail = icutz.getPreviousTransition(time, FALSE, tzt);
2378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!avail) {
2379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        time = tzt.getTime();
2382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (time <= start) {
2383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        icutz.getOffset(time, FALSE, raw, dst, status);
2386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        icutz.getOffset(time - 1, FALSE, raw0, dst0, status);
2387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
2388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("FAIL: Error in getOffset");
2389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (raw == raw0 && dst == dst0) {
2393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: False transition returned by getPreviousTransition for "
2394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                + icutz.getID(tzid) + " at " + dateToString(time));
2395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!first &&
2398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (tzt0.getFrom()->getRawOffset() != tzt.getTo()->getRawOffset()
2399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                || tzt0.getFrom()->getDSTSavings() != tzt.getTo()->getDSTSavings())) {
2400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: TO rule of the next transition does not match FROM rule in this transtion at "
2401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    + dateToString(time) + " for " + icutz.getID(tzid));
2402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tzt0 = tzt;
2404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        first = FALSE;
2405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Compare all time transitions in 2 time zones in the specified time range in ascending order
2410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
2412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::compareTransitionsAscending(BasicTimeZone& z1, BasicTimeZone& z2,
2413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                              UDate start, UDate end, UBool inclusive) {
2414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString zid1, zid2;
2415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZoneTransition tzt1, tzt2;
2416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool avail1, avail2;
2417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool inRange1, inRange2;
2418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    z1.getID(zid1);
2420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    z2.getID(zid2);
2421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time = start;
2423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
2424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        avail1 = z1.getNextTransition(time, inclusive, tzt1);
2425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        avail2 = z2.getNextTransition(time, inclusive, tzt2);
2426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        inRange1 = inRange2 = FALSE;
2428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (avail1) {
2429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (tzt1.getTime() < end || (inclusive && tzt1.getTime() == end)) {
2430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                inRange1 = TRUE;
2431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (avail2) {
2434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (tzt2.getTime() < end || (inclusive && tzt2.getTime() == end)) {
2435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                inRange2 = TRUE;
2436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!inRange1 && !inRange2) {
2439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // No more transition in the range
2440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!inRange1) {
2443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: " + zid1 + " does not have any transitions after "
2444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                + dateToString(time) + " before " + dateToString(end));
2445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!inRange2) {
2448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: " + zid2 + " does not have any transitions after "
2449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                + dateToString(time) + " before " + dateToString(end));
2450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzt1.getTime() != tzt2.getTime()) {
2453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: First transition after " + dateToString(time) + " "
2454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    + zid1 + "[" + dateToString(tzt1.getTime()) + "] "
2455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    + zid2 + "[" + dateToString(tzt2.getTime()) + "]");
2456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        time = tzt1.getTime();
2459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (inclusive) {
2460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            time += 1;
2461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Compare all time transitions in 2 time zones in the specified time range in descending order
2467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
2468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
2469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneRuleTest::compareTransitionsDescending(BasicTimeZone& z1, BasicTimeZone& z2,
2470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                               UDate start, UDate end, UBool inclusive) {
2471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString zid1, zid2;
2472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZoneTransition tzt1, tzt2;
2473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool avail1, avail2;
2474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool inRange1, inRange2;
2475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    z1.getID(zid1);
2477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    z2.getID(zid2);
2478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time = end;
2480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (TRUE) {
2481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        avail1 = z1.getPreviousTransition(time, inclusive, tzt1);
2482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        avail2 = z2.getPreviousTransition(time, inclusive, tzt2);
2483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        inRange1 = inRange2 = FALSE;
2485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (avail1) {
2486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (tzt1.getTime() > start || (inclusive && tzt1.getTime() == start)) {
2487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                inRange1 = TRUE;
2488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (avail2) {
2491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (tzt2.getTime() > start || (inclusive && tzt2.getTime() == start)) {
2492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                inRange2 = TRUE;
2493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!inRange1 && !inRange2) {
2496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // No more transition in the range
2497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!inRange1) {
2500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: " + zid1 + " does not have any transitions before "
2501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                + dateToString(time) + " after " + dateToString(start));
2502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!inRange2) {
2505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: " + zid2 + " does not have any transitions before "
2506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                + dateToString(time) + " after " + dateToString(start));
2507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tzt1.getTime() != tzt2.getTime()) {
2510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln((UnicodeString)"FAIL: Last transition before " + dateToString(time) + " "
2511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    + zid1 + "[" + dateToString(tzt1.getTime()) + "] "
2512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    + zid2 + "[" + dateToString(tzt2.getTime()) + "]");
2513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
2514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        time = tzt1.getTime();
2516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (inclusive) {
2517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            time -= 1;
2518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
2520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
2521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
252227f654740f2a26ad62a5c155af9199af9e69b889claireho// Slightly modified version of BasicTimeZone::hasEquivalentTransitions.
252327f654740f2a26ad62a5c155af9199af9e69b889claireho// This version returns TRUE if transition time delta is within the given
252427f654740f2a26ad62a5c155af9199af9e69b889claireho// delta range.
252527f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool hasEquivalentTransitions(/*const*/ BasicTimeZone& tz1, /*const*/BasicTimeZone& tz2,
252627f654740f2a26ad62a5c155af9199af9e69b889claireho                                        UDate start, UDate end,
252727f654740f2a26ad62a5c155af9199af9e69b889claireho                                        UBool ignoreDstAmount, int32_t maxTransitionTimeDelta,
252827f654740f2a26ad62a5c155af9199af9e69b889claireho                                        UErrorCode& status) {
252927f654740f2a26ad62a5c155af9199af9e69b889claireho    if (U_FAILURE(status)) {
253027f654740f2a26ad62a5c155af9199af9e69b889claireho        return FALSE;
253127f654740f2a26ad62a5c155af9199af9e69b889claireho    }
253227f654740f2a26ad62a5c155af9199af9e69b889claireho    if (tz1.hasSameRules(tz2)) {
253327f654740f2a26ad62a5c155af9199af9e69b889claireho        return TRUE;
253427f654740f2a26ad62a5c155af9199af9e69b889claireho    }
253527f654740f2a26ad62a5c155af9199af9e69b889claireho    // Check the offsets at the start time
253627f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t raw1, raw2, dst1, dst2;
253727f654740f2a26ad62a5c155af9199af9e69b889claireho    tz1.getOffset(start, FALSE, raw1, dst1, status);
253827f654740f2a26ad62a5c155af9199af9e69b889claireho    if (U_FAILURE(status)) {
253927f654740f2a26ad62a5c155af9199af9e69b889claireho        return FALSE;
254027f654740f2a26ad62a5c155af9199af9e69b889claireho    }
254127f654740f2a26ad62a5c155af9199af9e69b889claireho    tz2.getOffset(start, FALSE, raw2, dst2, status);
254227f654740f2a26ad62a5c155af9199af9e69b889claireho    if (U_FAILURE(status)) {
254327f654740f2a26ad62a5c155af9199af9e69b889claireho        return FALSE;
254427f654740f2a26ad62a5c155af9199af9e69b889claireho    }
254527f654740f2a26ad62a5c155af9199af9e69b889claireho    if (ignoreDstAmount) {
254627f654740f2a26ad62a5c155af9199af9e69b889claireho        if ((raw1 + dst1 != raw2 + dst2)
254727f654740f2a26ad62a5c155af9199af9e69b889claireho            || (dst1 != 0 && dst2 == 0)
254827f654740f2a26ad62a5c155af9199af9e69b889claireho            || (dst1 == 0 && dst2 != 0)) {
254927f654740f2a26ad62a5c155af9199af9e69b889claireho            return FALSE;
255027f654740f2a26ad62a5c155af9199af9e69b889claireho        }
255127f654740f2a26ad62a5c155af9199af9e69b889claireho    } else {
255227f654740f2a26ad62a5c155af9199af9e69b889claireho        if (raw1 != raw2 || dst1 != dst2) {
255327f654740f2a26ad62a5c155af9199af9e69b889claireho            return FALSE;
255427f654740f2a26ad62a5c155af9199af9e69b889claireho        }
255527f654740f2a26ad62a5c155af9199af9e69b889claireho    }
255627f654740f2a26ad62a5c155af9199af9e69b889claireho    // Check transitions in the range
255727f654740f2a26ad62a5c155af9199af9e69b889claireho    UDate time = start;
255827f654740f2a26ad62a5c155af9199af9e69b889claireho    TimeZoneTransition tr1, tr2;
255927f654740f2a26ad62a5c155af9199af9e69b889claireho    while (TRUE) {
256027f654740f2a26ad62a5c155af9199af9e69b889claireho        UBool avail1 = tz1.getNextTransition(time, FALSE, tr1);
256127f654740f2a26ad62a5c155af9199af9e69b889claireho        UBool avail2 = tz2.getNextTransition(time, FALSE, tr2);
256227f654740f2a26ad62a5c155af9199af9e69b889claireho
256327f654740f2a26ad62a5c155af9199af9e69b889claireho        if (ignoreDstAmount) {
256427f654740f2a26ad62a5c155af9199af9e69b889claireho            // Skip a transition which only differ the amount of DST savings
256527f654740f2a26ad62a5c155af9199af9e69b889claireho            while (TRUE) {
256627f654740f2a26ad62a5c155af9199af9e69b889claireho                if (avail1
256727f654740f2a26ad62a5c155af9199af9e69b889claireho                        && tr1.getTime() <= end
256827f654740f2a26ad62a5c155af9199af9e69b889claireho                        && (tr1.getFrom()->getRawOffset() + tr1.getFrom()->getDSTSavings()
256927f654740f2a26ad62a5c155af9199af9e69b889claireho                                == tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings())
257027f654740f2a26ad62a5c155af9199af9e69b889claireho                        && (tr1.getFrom()->getDSTSavings() != 0 && tr1.getTo()->getDSTSavings() != 0)) {
257127f654740f2a26ad62a5c155af9199af9e69b889claireho                    tz1.getNextTransition(tr1.getTime(), FALSE, tr1);
257227f654740f2a26ad62a5c155af9199af9e69b889claireho                } else {
257327f654740f2a26ad62a5c155af9199af9e69b889claireho                    break;
257427f654740f2a26ad62a5c155af9199af9e69b889claireho                }
257527f654740f2a26ad62a5c155af9199af9e69b889claireho            }
257627f654740f2a26ad62a5c155af9199af9e69b889claireho            while (TRUE) {
257727f654740f2a26ad62a5c155af9199af9e69b889claireho                if (avail2
257827f654740f2a26ad62a5c155af9199af9e69b889claireho                        && tr2.getTime() <= end
257927f654740f2a26ad62a5c155af9199af9e69b889claireho                        && (tr2.getFrom()->getRawOffset() + tr2.getFrom()->getDSTSavings()
258027f654740f2a26ad62a5c155af9199af9e69b889claireho                                == tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings())
258127f654740f2a26ad62a5c155af9199af9e69b889claireho                        && (tr2.getFrom()->getDSTSavings() != 0 && tr2.getTo()->getDSTSavings() != 0)) {
258227f654740f2a26ad62a5c155af9199af9e69b889claireho                    tz2.getNextTransition(tr2.getTime(), FALSE, tr2);
258327f654740f2a26ad62a5c155af9199af9e69b889claireho                } else {
258427f654740f2a26ad62a5c155af9199af9e69b889claireho                    break;
258527f654740f2a26ad62a5c155af9199af9e69b889claireho                }
258627f654740f2a26ad62a5c155af9199af9e69b889claireho            }
258727f654740f2a26ad62a5c155af9199af9e69b889claireho        }
258827f654740f2a26ad62a5c155af9199af9e69b889claireho
258927f654740f2a26ad62a5c155af9199af9e69b889claireho        UBool inRange1 = (avail1 && tr1.getTime() <= end);
259027f654740f2a26ad62a5c155af9199af9e69b889claireho        UBool inRange2 = (avail2 && tr2.getTime() <= end);
259127f654740f2a26ad62a5c155af9199af9e69b889claireho        if (!inRange1 && !inRange2) {
259227f654740f2a26ad62a5c155af9199af9e69b889claireho            // No more transition in the range
259327f654740f2a26ad62a5c155af9199af9e69b889claireho            break;
259427f654740f2a26ad62a5c155af9199af9e69b889claireho        }
259527f654740f2a26ad62a5c155af9199af9e69b889claireho        if (!inRange1 || !inRange2) {
259627f654740f2a26ad62a5c155af9199af9e69b889claireho            return FALSE;
259727f654740f2a26ad62a5c155af9199af9e69b889claireho        }
259827f654740f2a26ad62a5c155af9199af9e69b889claireho        double delta = tr1.getTime() >= tr2.getTime() ? tr1.getTime() - tr2.getTime() : tr2.getTime() - tr1.getTime();
259927f654740f2a26ad62a5c155af9199af9e69b889claireho        if (delta > (double)maxTransitionTimeDelta) {
260027f654740f2a26ad62a5c155af9199af9e69b889claireho            return FALSE;
260127f654740f2a26ad62a5c155af9199af9e69b889claireho        }
260227f654740f2a26ad62a5c155af9199af9e69b889claireho        if (ignoreDstAmount) {
260327f654740f2a26ad62a5c155af9199af9e69b889claireho            if (tr1.getTo()->getRawOffset() + tr1.getTo()->getDSTSavings()
260427f654740f2a26ad62a5c155af9199af9e69b889claireho                        != tr2.getTo()->getRawOffset() + tr2.getTo()->getDSTSavings()
260527f654740f2a26ad62a5c155af9199af9e69b889claireho                    || (tr1.getTo()->getDSTSavings() != 0 &&  tr2.getTo()->getDSTSavings() == 0)
260627f654740f2a26ad62a5c155af9199af9e69b889claireho                    || (tr1.getTo()->getDSTSavings() == 0 &&  tr2.getTo()->getDSTSavings() != 0)) {
260727f654740f2a26ad62a5c155af9199af9e69b889claireho                return FALSE;
260827f654740f2a26ad62a5c155af9199af9e69b889claireho            }
260927f654740f2a26ad62a5c155af9199af9e69b889claireho        } else {
261027f654740f2a26ad62a5c155af9199af9e69b889claireho            if (tr1.getTo()->getRawOffset() != tr2.getTo()->getRawOffset() ||
261127f654740f2a26ad62a5c155af9199af9e69b889claireho                tr1.getTo()->getDSTSavings() != tr2.getTo()->getDSTSavings()) {
261227f654740f2a26ad62a5c155af9199af9e69b889claireho                return FALSE;
261327f654740f2a26ad62a5c155af9199af9e69b889claireho            }
261427f654740f2a26ad62a5c155af9199af9e69b889claireho        }
261527f654740f2a26ad62a5c155af9199af9e69b889claireho        time = tr1.getTime() > tr2.getTime() ? tr1.getTime() : tr2.getTime();
261627f654740f2a26ad62a5c155af9199af9e69b889claireho    }
261727f654740f2a26ad62a5c155af9199af9e69b889claireho    return TRUE;
261827f654740f2a26ad62a5c155af9199af9e69b889claireho}
261927f654740f2a26ad62a5c155af9199af9e69b889claireho
262083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius// Test case for ticket#8943
262183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius// RuleBasedTimeZone#getOffsets throws NPE
262283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Corneliusvoid
262383a171d1a62abf406f7f44ae671823d5ec20db7dCraig CorneliusTimeZoneRuleTest::TestT8943(void) {
262483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    UErrorCode status = U_ZERO_ERROR;
262583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    UnicodeString id("Ekaterinburg Time");
262683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    UnicodeString stdName("Ekaterinburg Standard Time");
262783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    UnicodeString dstName("Ekaterinburg Daylight Time");
262883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
262983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    InitialTimeZoneRule *initialRule = new InitialTimeZoneRule(stdName, 18000000, 0);
263083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    RuleBasedTimeZone *rbtz = new RuleBasedTimeZone(id, initialRule);
263183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
263283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    DateTimeRule *dtRule = new DateTimeRule(UCAL_OCTOBER, -1, UCAL_SUNDAY, 10800000, DateTimeRule::WALL_TIME);
263383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    AnnualTimeZoneRule *atzRule = new AnnualTimeZoneRule(stdName, 18000000, 0, dtRule, 2000, 2010);
263483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    rbtz->addTransitionRule(atzRule, status);
263583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
263683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    dtRule = new DateTimeRule(UCAL_MARCH, -1, UCAL_SUNDAY, 7200000, DateTimeRule::WALL_TIME);
263783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    atzRule = new AnnualTimeZoneRule(dstName, 18000000, 3600000, dtRule, 2000, 2010);
263883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    rbtz->addTransitionRule(atzRule, status);
263983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
264083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    dtRule = new DateTimeRule(UCAL_JANUARY, 1, 0, DateTimeRule::WALL_TIME);
264183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    atzRule = new AnnualTimeZoneRule(stdName, 21600000, 0, dtRule, 2011, AnnualTimeZoneRule::MAX_YEAR);
264283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    rbtz->addTransitionRule(atzRule, status);
264383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
264483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    dtRule = new DateTimeRule(UCAL_JANUARY, 1, 1, DateTimeRule::WALL_TIME);
264583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    atzRule = new AnnualTimeZoneRule(dstName, 21600000, 0, dtRule, 2011, AnnualTimeZoneRule::MAX_YEAR);
264683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    rbtz->addTransitionRule(atzRule, status);
264783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    rbtz->complete(status);
264883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
264983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    if (U_FAILURE(status)) {
265083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        errln("Failed to construct a RuleBasedTimeZone");
265183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    } else {
265283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        int32_t raw, dst;
265383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        rbtz->getOffset(1293822000000.0 /* 2010-12-31 19:00:00 UTC */, FALSE, raw, dst, status);
265483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        if (U_FAILURE(status)) {
265583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            errln("Error invoking getOffset");
265683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        } else if (raw != 21600000 || dst != 0) {
265783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            errln(UnicodeString("Fail: Wrong offsets: ") + raw + "/" + dst + " Expected: 21600000/0");
265883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        }
265983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    }
266083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
266183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    delete rbtz;
266283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius}
266327f654740f2a26ad62a5c155af9199af9e69b889claireho
2664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
2665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof
2667