1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius* Copyright (C) 2007-2011, International Business Machines Corporation and         *
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* others. All Rights Reserved.                                                *
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "tzoffloc.h"
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ucal.h"
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/timezone.h"
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/calendar.h"
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/dtrule.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/tzrule.h"
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/rbtz.h"
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/simpletz.h"
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/tzrule.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/smpdtfmt.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/gregocal.h"
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneOffsetLocalTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (exec) {
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("TestSuite TimeZoneOffsetLocalTest");
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (index) {
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TESTCASE(0, TestGetOffsetAroundTransition);
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        default: name = ""; break;
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Testing getOffset APIs around rule transition by local standard/wall time.
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneOffsetLocalTest::TestGetOffsetAroundTransition() {
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t NUM_DATES = 10;
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t NUM_TIMEZONES = 3;
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t HOUR = 60*60*1000;
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t MINUTE = 60*1000;
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t DATES[NUM_DATES][6] = {
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_APRIL, 2, 1, 30, 1*HOUR+30*MINUTE},
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_APRIL, 2, 2, 00, 2*HOUR},
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_APRIL, 2, 2, 30, 2*HOUR+30*MINUTE},
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_APRIL, 2, 3, 00, 3*HOUR},
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_APRIL, 2, 3, 30, 3*HOUR+30*MINUTE},
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_OCTOBER, 29, 0, 30, 0*HOUR+30*MINUTE},
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_OCTOBER, 29, 1, 00, 1*HOUR},
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_OCTOBER, 29, 1, 30, 1*HOUR+30*MINUTE},
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_OCTOBER, 29, 2, 00, 2*HOUR},
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {2006, UCAL_OCTOBER, 29, 2, 30, 2*HOUR+30*MINUTE},
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Expected offsets by int32_t getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // uint8_t dayOfWeek, int32_t millis, UErrorCode& status)
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t OFFSETS1[NUM_DATES] = {
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // April 2, 2006
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -8*HOUR,
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -7*HOUR,
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -7*HOUR,
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -7*HOUR,
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -7*HOUR,
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // October 29, 2006
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -7*HOUR,
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -8*HOUR,
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -8*HOUR,
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -8*HOUR,
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        -8*HOUR,
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Expected offsets by void getOffset(UDate date, UBool local, int32_t& rawOffset,
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t& dstOffset, UErrorCode& ec) with local=TRUE
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // or void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) with
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // nonExistingTimeOpt=kStandard/duplicatedTimeOpt=kStandard
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t OFFSETS2[NUM_DATES][2] = {
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // April 2, 2006
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Oct 29, 2006
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Expected offsets by void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt,
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t duplicatedTimeOpt, int32_t& rawOffset, int32_t& dstOffset, UErrorCode& status) with
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // nonExistingTimeOpt=kDaylight/duplicatedTimeOpt=kDaylight
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t OFFSETS3[][2] = {
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // April 2, 2006
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // October 29, 2006
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 1*HOUR},
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {-8*HOUR, 0},
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    };
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t rawOffset, dstOffset;
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone* utc = TimeZone::createTimeZone("UTC");
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Calendar* cal = Calendar::createInstance(*utc, status);
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("Calendar::createInstance failed: %s", u_errorName(status));
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal->clear();
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Set up TimeZone objects - OlsonTimeZone, SimpleTimeZone and RuleBasedTimeZone
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    BasicTimeZone *TESTZONES[NUM_TIMEZONES];
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TESTZONES[0] = (BasicTimeZone*)TimeZone::createTimeZone("America/Los_Angeles");
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TESTZONES[1] = new SimpleTimeZone(-8*HOUR, "Simple Pacific Time",
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        UCAL_APRIL, 1, UCAL_SUNDAY, 2*HOUR,
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        UCAL_OCTOBER, -1, UCAL_SUNDAY, 2*HOUR, status);
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("SimpleTimeZone constructor failed");
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    InitialTimeZoneRule *ir = new InitialTimeZoneRule(
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "Pacific Standard Time", // Initial time Name
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            -8*HOUR,        // Raw offset
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            0*HOUR);        // DST saving amount
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    RuleBasedTimeZone *rbPT = new RuleBasedTimeZone("Rule based Pacific Time", ir);
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    DateTimeRule *dtr;
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    AnnualTimeZoneRule *atzr;
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const int32_t STARTYEAR = 2000;
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_APRIL, 1, UCAL_SUNDAY,
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        2*HOUR, DateTimeRule::WALL_TIME); // 1st Sunday in April, at 2AM wall time
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("Pacific Daylight Time",
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            -8*HOUR /* rawOffset */, 1*HOUR /* dstSavings */, dtr,
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbPT->addTransitionRule(atzr, status);
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("Could not add DST start rule to the RuleBasedTimeZone rbPT");
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dtr = new DateTimeRule(UCAL_OCTOBER, -1, UCAL_SUNDAY,
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        2*HOUR, DateTimeRule::WALL_TIME); // last Sunday in October, at 2AM wall time
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    atzr = new AnnualTimeZoneRule("Pacific Standard Time",
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            -8*HOUR /* rawOffset */, 0 /* dstSavings */, dtr,
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            STARTYEAR, AnnualTimeZoneRule::MAX_YEAR);
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbPT->addTransitionRule(atzr, status);
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("Could not add STD start rule to the RuleBasedTimeZone rbPT");
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    rbPT->complete(status);
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("complete() failed for RuleBasedTimeZone rbPT");
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TESTZONES[2] = rbPT;
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Calculate millis
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate MILLIS[NUM_DATES];
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_DATES; i++) {
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        cal->clear();
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        cal->set(DATES[i][0], DATES[i][1], DATES[i][2], DATES[i][3], DATES[i][4]);
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        MILLIS[i] = cal->getTime(status);
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            errln("cal->getTime failed");
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return;
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    SimpleDateFormat df(UnicodeString("yyyy-MM-dd HH:mm:ss"), status);
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
19683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        dataerrln("Failed to initialize a SimpleDateFormat - %s", u_errorName(status));
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    df.setTimeZone(*utc);
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString dateStr;
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Test getOffset(uint8_t era, int32_t year, int32_t month, int32_t day,
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // uint8_t dayOfWeek, int32_t millis, UErrorCode& status)
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t d = 0; d < NUM_DATES; d++) {
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ZERO_ERROR;
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t offset = TESTZONES[i]->getOffset(GregorianCalendar::AD, DATES[d][0], DATES[d][1], DATES[d][2],
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                UCAL_SUNDAY, DATES[d][5], status);
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"getOffset(era,year,month,day,dayOfWeek,millis,status) failed for TESTZONES[" + i + "]");
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (offset != OFFSETS1[d]) {
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                dateStr.remove();
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                df.format(MILLIS[d], dateStr);
2136d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + dateStr + "(standard) - Got: " + offset + " Expected: " + OFFSETS1[d]);
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Test getOffset(UDate date, UBool local, int32_t& rawOffset,
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t& dstOffset, UErrorCode& ec) with local = TRUE
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t m = 0; m < NUM_DATES; m++) {
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ZERO_ERROR;
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            TESTZONES[i]->getOffset(MILLIS[m], TRUE, rawOffset, dstOffset, status);
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"getOffset(date,local,rawOfset,dstOffset,ec) failed for TESTZONES[" + i + "]");
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1]) {
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                dateStr.remove();
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                df.format(MILLIS[m], dateStr);
2306d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + dateStr + "(wall) - Got: "
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + rawOffset + "/" + dstOffset
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // with nonExistingTimeOpt=kStandard/duplicatedTimeOpt=kStandard
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int m = 0; m < NUM_DATES; m++) {
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ZERO_ERROR;
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kStandard, BasicTimeZone::kStandard,
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                rawOffset, dstOffset, status);
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"getOffsetFromLocal with kStandard/kStandard failed for TESTZONES[" + i + "]");
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1]) {
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                dateStr.remove();
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                df.format(MILLIS[m], dateStr);
2516d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + dateStr + "(wall/kStandard/kStandard) - Got: "
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + rawOffset + "/" + dstOffset
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // with nonExistingTimeOpt=kDaylight/duplicatedTimeOpt=kDaylight
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int m = 0; m < NUM_DATES; m++) {
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ZERO_ERROR;
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kDaylight, BasicTimeZone::kDaylight,
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                rawOffset, dstOffset, status);
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"getOffsetFromLocal with kDaylight/kDaylight failed for TESTZONES[" + i + "]");
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1]) {
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                dateStr.remove();
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                df.format(MILLIS[m], dateStr);
2726d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + dateStr + "(wall/kDaylight/kDaylight) - Got: "
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + rawOffset + "/" + dstOffset
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]);
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // with nonExistingTimeOpt=kFormer/duplicatedTimeOpt=kLatter
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int m = 0; m < NUM_DATES; m++) {
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ZERO_ERROR;
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kFormer, BasicTimeZone::kLatter,
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                rawOffset, dstOffset, status);
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"getOffsetFromLocal with kFormer/kLatter failed for TESTZONES[" + i + "]");
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (rawOffset != OFFSETS2[m][0] || dstOffset != OFFSETS2[m][1]) {
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                dateStr.remove();
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                df.format(MILLIS[m], dateStr);
2936d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + dateStr + "(wall/kFormer/kLatter) - Got: "
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + rawOffset + "/" + dstOffset
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]);
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Test getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt,
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // int32_t& rawOffset, int32_t& dstOffset, UErroCode& status)
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // with nonExistingTimeOpt=kLatter/duplicatedTimeOpt=kFormer
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int m = 0; m < NUM_DATES; m++) {
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ZERO_ERROR;
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            TESTZONES[i]->getOffsetFromLocal(MILLIS[m], BasicTimeZone::kLatter, BasicTimeZone::kFormer,
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                rawOffset, dstOffset, status);
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (U_FAILURE(status)) {
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                errln((UnicodeString)"getOffsetFromLocal with kLatter/kFormer failed for TESTZONES[" + i + "]");
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (rawOffset != OFFSETS3[m][0] || dstOffset != OFFSETS3[m][1]) {
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                dateStr.remove();
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                df.format(MILLIS[m], dateStr);
3146d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                dataerrln((UnicodeString)"Bad offset returned by TESTZONES[" + i + "] at "
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + dateStr + "(wall/kLatter/kFormer) - Got: "
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + rawOffset + "/" + dstOffset
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]);
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < NUM_TIMEZONES; i++) {
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete TESTZONES[i];
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete utc;
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete cal;
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
330