1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/***********************************************************************
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * COPYRIGHT:
350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Copyright (c) 1997-2010, International Business Machines Corporation
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and 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 "tzbdtest.h"
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/timezone.h"
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/simpletz.h"
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/gregocal.h"
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h"
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid TimeZoneBoundaryTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (exec) logln("TestSuite TestTimeZoneBoundary");
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (index) {
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case 0:
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "TestBoundaries";
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (exec) {
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                logln("TestBoundaries---"); logln("");
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                TestBoundaries();
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case 1:
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "TestNewRules";
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (exec) {
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                logln("TestNewRules---"); logln("");
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                TestNewRules();
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case 2:
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            name = "TestStepwise";
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (exec) {
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                logln("TestStepwise---"); logln("");
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                TestStepwise();
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        default: name = ""; break;
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// *****************************************************************************
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// class TimeZoneBoundaryTest
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// *****************************************************************************
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::TimeZoneBoundaryTest()
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru:
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_SECOND(1000),
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_MINUTE(60 * ONE_SECOND),
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_HOUR(60 * ONE_MINUTE),
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_DAY(24 * ONE_HOUR),
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruONE_YEAR(uprv_floor(365.25 * ONE_DAY)),
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSIX_MONTHS(ONE_YEAR / 2)
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int32_t TimeZoneBoundaryTest::MONTH_LENGTH[] = {
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UDate TimeZoneBoundaryTest::PST_1997_BEG = 860320800000.0;
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UDate TimeZoneBoundaryTest::PST_1997_END = 877856400000.0;
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UDate TimeZoneBoundaryTest::INTERVAL = 10;
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::findDaylightBoundaryUsingDate(UDate d, const char* startMode, UDate expectedBoundary)
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString str;
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dateToString(d, str).indexOf(startMode) == - 1) {
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("Error: ") + startMode + " not present in " + str);
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate min = d;
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate max = min + SIX_MONTHS;
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while ((max - min) > INTERVAL) {
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UDate mid = (min + max) / 2;
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString* s = &dateToString(mid, str);
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (s->indexOf(startMode) != - 1) {
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            min = mid;
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            max = mid;
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln("Date Before: " + showDate(min));
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln("Date After:  " + showDate(max));
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate mindelta = expectedBoundary - min;
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate maxdelta = max - expectedBoundary;
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (mindelta >= 0 &&
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        mindelta <= INTERVAL &&
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        maxdelta >= 0 &&
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        maxdelta <= INTERVAL) logln(UnicodeString("PASS: Expected boundary at ") + expectedBoundary);
1006d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    else dataerrln(UnicodeString("FAIL: Expected boundary at ") + expectedBoundary);
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::findDaylightBoundaryUsingTimeZone(UDate d, UBool startsInDST, UDate expectedBoundary)
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone *zone = TimeZone::createDefault();
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    findDaylightBoundaryUsingTimeZone(d, startsInDST, expectedBoundary, zone);
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete zone;
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::findDaylightBoundaryUsingTimeZone(UDate d, UBool startsInDST, UDate expectedBoundary, TimeZone* tz)
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString str;
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate min = d;
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate max = min + SIX_MONTHS;
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tz->inDaylightTime(d, status) != startsInDST) {
1236d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln("FAIL: " + tz->getID(str) + " inDaylightTime(" + dateToString(d) + ") != " + (startsInDST ? "true" : "false"));
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        startsInDST = !startsInDST;
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (failure(status, "TimeZone::inDaylightTime", TRUE)) return;
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tz->inDaylightTime(max, status) == startsInDST) {
1286d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln("FAIL: " + tz->getID(str) + " inDaylightTime(" + dateToString(max) + ") != " + (startsInDST ? "false" : "true"));
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (failure(status, "TimeZone::inDaylightTime")) return;
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while ((max - min) > INTERVAL) {
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UDate mid = (min + max) / 2;
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UBool isIn = tz->inDaylightTime(mid, status);
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (failure(status, "TimeZone::inDaylightTime")) return;
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (isIn == startsInDST) {
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            min = mid;
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            max = mid;
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln(tz->getID(str) + " Before: " + showDate(min));
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln(tz->getID(str) + " After:  " + showDate(max));
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate mindelta = expectedBoundary - min;
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate maxdelta = max - expectedBoundary;
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (mindelta >= 0 &&
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        mindelta <= INTERVAL &&
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        maxdelta >= 0 &&
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        maxdelta <= INTERVAL) logln(UnicodeString("PASS: Expected boundary at ") + expectedBoundary);
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else errln(UnicodeString("FAIL: Expected boundary at ") + expectedBoundary);
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString*
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::showDate(int32_t l)
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return showDate(new Date(l));
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::showDate(UDate d)
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t y, m, day, h, min, sec;
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dateToFields(d, y, m, day, h, min, sec);
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return UnicodeString("") + y + "/" + showNN(m + 1) + "/" +
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        showNN(day) + " " + showNN(h) + ":" + showNN(min) +
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        " \"" + dateToString(d) + "\" = " + uprv_floor(d+0.5);
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::showNN(int32_t n)
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString nStr;
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (n < 10) {
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        nStr += UnicodeString("0", "");
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return nStr + n;
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::verifyDST(UDate d, TimeZone* time_zone, UBool expUseDaylightTime, UBool expInDaylightTime, UDate expZoneOffset, UDate expDSTOffset)
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString str;
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln("-- Verifying time " + dateToString(d) + " in zone " + time_zone->getID(str));
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (time_zone->inDaylightTime(d, status) == expInDaylightTime)
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("PASS: inDaylightTime = ") + (time_zone->inDaylightTime(d, status)?"true":"false"));
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
1976d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln(UnicodeString("FAIL: inDaylightTime = ") + (time_zone->inDaylightTime(d, status)?"true":"false"));
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (failure(status, "TimeZone::inDaylightTime", TRUE))
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (time_zone->useDaylightTime() == expUseDaylightTime)
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("PASS: useDaylightTime = ") + (time_zone->useDaylightTime()?"true":"false"));
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
2036d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln(UnicodeString("FAIL: useDaylightTime = ") + (time_zone->useDaylightTime()?"true":"false"));
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (time_zone->getRawOffset() == expZoneOffset)
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("PASS: getRawOffset() = ") + (expZoneOffset / ONE_HOUR));
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
2076d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln(UnicodeString("FAIL: getRawOffset() = ") + (time_zone->getRawOffset() / ONE_HOUR) + ";  expected " + (expZoneOffset / ONE_HOUR));
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    GregorianCalendar *gc = new GregorianCalendar(time_zone->clone(), status);
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    gc->setTime(d, status);
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (failure(status, "GregorianCalendar::setTime")) return;
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t offset = time_zone->getOffset((uint8_t)gc->get(UCAL_ERA, status),
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gc->get(UCAL_YEAR, status), gc->get(UCAL_MONTH, status),
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gc->get(UCAL_DATE, status), (uint8_t)gc->get(UCAL_DAY_OF_WEEK, status),
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ((gc->get(UCAL_HOUR_OF_DAY, status) * 60 + gc->get(UCAL_MINUTE, status)) * 60 + gc->get(UCAL_SECOND, status)) * 1000 + gc->get(UCAL_MILLISECOND, status),
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status);
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (failure(status, "GregorianCalendar::get")) return;
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (offset == expDSTOffset) logln(UnicodeString("PASS: getOffset() = ") + (offset / ONE_HOUR));
2196d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    else dataerrln(UnicodeString("FAIL: getOffset() = ") + (offset / ONE_HOUR) + "; expected " + (expDSTOffset / ONE_HOUR));
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete gc;
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * Check that the given year/month/dom/hour maps to and from the
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * given epochHours.  This verifies the functioning of the
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * calendar and time zone in conjunction with one another,
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * including the calendar time->fields and fields->time and
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * the time zone getOffset method.
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    * @param epochHours hours after Jan 1 1970 0:00 GMT.
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid TimeZoneBoundaryTest::verifyMapping(Calendar& cal, int year, int month, int dom, int hour,
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    double epochHours) {
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    double H = 3600000.0;
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal.clear();
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal.set(year, month, dom, hour, 0, 0);
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate e = cal.getTime(status)/ H;
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate ed = (epochHours * H);
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (e == epochHours) {
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("Ok: ") + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                e + " (" + ed + ")");
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
2456d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln(UnicodeString("FAIL: ") + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                e + " (" + (e * H) + ")" +
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ", expected " + epochHours + " (" + ed + ")");
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    cal.setTime(ed, status);
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (cal.get(UCAL_YEAR, status) == year &&
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        cal.get(UCAL_MONTH, status) == month &&
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        cal.get(UCAL_DATE, status) == dom &&
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        cal.get(UCAL_MILLISECONDS_IN_DAY, status) == hour * 3600000) {
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("Ok: ") + epochHours + " (" + ed + ") => " +
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                cal.get(UCAL_YEAR, status) + "/" +
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (cal.get(UCAL_MONTH, status)+1) + "/" +
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                cal.get(UCAL_DATE, status) + " " +
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                cal.get(UCAL_MILLISECOND, status)/H);
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
2606d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln(UnicodeString("FAIL: ") + epochHours + " (" + ed + ") => " +
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                cal.get(UCAL_YEAR, status) + "/" +
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (cal.get(UCAL_MONTH, status)+1) + "/" +
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                cal.get(UCAL_DATE, status) + " " +
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                cal.get(UCAL_MILLISECOND, status)/H +
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ", expected " + year + "/" + (month+1) + "/" + dom +
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                " " + hour);
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Test the behavior of SimpleTimeZone at the transition into and out of DST.
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Use a binary search to find boundaries.
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::TestBoundaries()
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone* pst = TimeZone::createTimeZone("PST");
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Calendar* tempcal = Calendar::createInstance(pst, status);
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_SUCCESS(status)){
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*tempcal, 1997, Calendar::APRIL, 3,  0, 238904.0);
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*tempcal, 1997, Calendar::APRIL, 4,  0, 238928.0);
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*tempcal, 1997, Calendar::APRIL, 5,  0, 238952.0);
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*tempcal, 1997, Calendar::APRIL, 5, 23, 238975.0);
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*tempcal, 1997, Calendar::APRIL, 6,  0, 238976.0);
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*tempcal, 1997, Calendar::APRIL, 6,  1, 238977.0);
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*tempcal, 1997, Calendar::APRIL, 6,  3, 238978.0);
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }else{
28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("Could not create calendar. Error: %s", u_errorName(status));
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone* utc = TimeZone::createTimeZone("UTC");
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Calendar* utccal =  Calendar::createInstance(utc, status);
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_SUCCESS(status)){
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        verifyMapping(*utccal, 1997, Calendar::APRIL, 6, 0, 238968.0);
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }else{
29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        dataerrln("Could not create calendar. Error: %s", u_errorName(status));
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone* save = TimeZone::createDefault();
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone::setDefault(*pst);
30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (tempcal != NULL) {
30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // DST changeover for PST is 4/6/1997 at 2 hours past midnight
30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // at 238978.0 epoch hours.
30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        tempcal->clear();
30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        tempcal->set(1997, Calendar::APRIL, 6);
30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        UDate d = tempcal->getTime(status);
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // i is minutes past midnight standard time
30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        for (int i=-120; i<=180; i+=60)
31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        {
31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            UBool inDST = (i >= 120);
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            tempcal->setTime(d + i*60*1000, status);
31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            verifyDST(tempcal->getTime(status),pst, TRUE, inDST, -8*ONE_HOUR,inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone::setDefault(*save);
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete save;
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete utccal;
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete tempcal;
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 1
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("--- Test a ---");
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UDate d = date(97, UCAL_APRIL, 6);
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TimeZone *z = TimeZone::createTimeZone("PST");
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (int32_t i = 60; i <= 180; i += 15) {
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UBool inDST = (i >= 120);
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate e = d + i * 60 * 1000;
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            verifyDST(e, z, TRUE, inDST, - 8 * ONE_HOUR, inDST ? - 7 * ONE_HOUR: - 8 * ONE_HOUR);
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete z;
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 1
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("--- Test b ---");
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TimeZone *tz;
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TimeZone::setDefault(*(tz = TimeZone::createTimeZone("PST")));
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tz;
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        findDaylightBoundaryUsingDate(date(97, 0, 1), "PST", PST_1997_BEG);
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        findDaylightBoundaryUsingDate(date(97, 6, 1), "PDT", PST_1997_END);
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 1
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("--- Test c ---");
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TimeZone* z = TimeZone::createTimeZone("Australia/Adelaide");
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        findDaylightBoundaryUsingTimeZone(date(97, 0, 1), TRUE, 859653000000.0, z);
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        findDaylightBoundaryUsingTimeZone(date(97, 6, 1), FALSE, 877797000000.0, z);
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete z;
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 1
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("--- Test d ---");
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        findDaylightBoundaryUsingTimeZone(date(97, 0, 1), FALSE, PST_1997_BEG);
362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        findDaylightBoundaryUsingTimeZone(date(97, 6, 1), TRUE, PST_1997_END);
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("--- Test e ---");
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        TimeZone *z = TimeZone::createDefault();
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("") + z->getOffset(1, 97, 3, 4, 6, 0) + " " + date(97, 3, 4));
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("") + z->getOffset(1, 97, 3, 5, 7, 0) + " " + date(97, 3, 5));
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("") + z->getOffset(1, 97, 3, 6, 1, 0) + " " + date(97, 3, 6));
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln(UnicodeString("") + z->getOffset(1, 97, 3, 7, 2, 0) + " " + date(97, 3, 7));
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete z;
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::testUsingBinarySearch(SimpleTimeZone* tz, UDate d, UDate expectedBoundary)
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate min = d;
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate max = min + SIX_MONTHS;
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool startsInDST = tz->inDaylightTime(d, status);
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (failure(status, "SimpleTimeZone::inDaylightTime", TRUE)) return;
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tz->inDaylightTime(max, status) == startsInDST) {
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("Error: inDaylightTime(" + dateToString(max) + ") != " + ((!startsInDST)?"true":"false"));
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while ((max - min) > INTERVAL) {
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UDate mid = (min + max) / 2;
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tz->inDaylightTime(mid, status) == startsInDST) {
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            min = mid;
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            max = mid;
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln("Binary Search Before: " + showDate(min));
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln("Binary Search After:  " + showDate(max));
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate mindelta = expectedBoundary - min;
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate maxdelta = max - expectedBoundary;
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (mindelta >= 0 &&
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        mindelta <= INTERVAL &&
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        maxdelta >= 0 &&
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        maxdelta <= INTERVAL) logln(UnicodeString("PASS: Expected boundary at ") + expectedBoundary);
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else errln(UnicodeString("FAIL: Expected boundary at ") + expectedBoundary);
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Test the handling of the "new" rules; that is, rules other than nth Day of week.
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::TestNewRules()
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 1
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        SimpleTimeZone *tz;
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("-----------------------------------------------------------------");
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("Aug 2ndTues .. Mar 15");
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tz = new SimpleTimeZone(- 8 * (int32_t)ONE_HOUR, "Test_1", UCAL_AUGUST, 2, UCAL_TUESDAY, 2 * (int32_t)ONE_HOUR, UCAL_MARCH, 15, 0, 2 * (int32_t)ONE_HOUR, status);
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testUsingBinarySearch(tz, date(97, 0, 1), 858416400000.0);
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testUsingBinarySearch(tz, date(97, 6, 1), 871380000000.0);
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tz;
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("-----------------------------------------------------------------");
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("Apr Wed>=14 .. Sep Sun<=20");
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tz = new SimpleTimeZone(- 8 * (int32_t)ONE_HOUR, "Test_2", UCAL_APRIL, 14, - UCAL_WEDNESDAY, 2 *(int32_t)ONE_HOUR, UCAL_SEPTEMBER, - 20, - UCAL_SUNDAY, 2 * (int32_t)ONE_HOUR, status);
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testUsingBinarySearch(tz, date(97, 0, 1), 861184800000.0);
439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        logln("========================================");
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testUsingBinarySearch(tz, date(97, 6, 1), 874227600000.0);
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete tz;
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::findBoundariesStepwise(int32_t year, UDate interval, TimeZone* z, int32_t expectedChanges)
450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString str;
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate d = date(year - 1900, UCAL_JANUARY, 1);
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate time = d;
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDate limit = time + ONE_YEAR + ONE_DAY;
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool lastState = z->inDaylightTime(d, status);
45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (failure(status, "TimeZone::inDaylightTime", TRUE)) return;
458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t changes = 0;
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln(UnicodeString("-- Zone ") + z->getID(str) + " starts in " + year + " with DST = " + (lastState?"true":"false"));
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    logln(UnicodeString("useDaylightTime = ") + (z->useDaylightTime()?"true":"false"));
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (time < limit) {
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        d = time;
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UBool state = z->inDaylightTime(d, status);
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (failure(status, "TimeZone::inDaylightTime")) return;
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (state != lastState) {
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            logln(UnicodeString(state ? "Entry ": "Exit ") + "at " + d);
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            lastState = state;++changes;
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        time += interval;
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (changes == 0) {
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!lastState &&
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            !z->useDaylightTime()) logln("No DST");
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else errln("FAIL: DST all year, or no DST with true useDaylightTime");
475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else if (changes != 2) {
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln(UnicodeString("FAIL: ") + changes + " changes seen; should see 0 or 2");
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else if (!z->useDaylightTime()) {
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        errln("FAIL: useDaylightTime false but 2 changes seen");
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (changes != expectedChanges) {
4836d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        dataerrln(UnicodeString("FAIL: ") + changes + " changes seen; expected " + expectedChanges);
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// -------------------------------------
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This test is problematic. It makes assumptions about the behavior
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * of specific zones. Since ICU's zone table is based on the Olson
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * zones (the UNIX zones), and those change from time to time, this
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * test can fail after a zone table update. If that happens, the
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * selected zones need to be updated to have the behavior
495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * expected. That is, they should have DST, not have DST, and have DST
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * -- other than that this test isn't picky. 12/3/99 aliu
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Test the behavior of SimpleTimeZone at the transition into and out of DST.
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Use a stepwise march to find boundaries.
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZoneBoundaryTest::TestStepwise()
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    TimeZone *zone =  TimeZone::createTimeZone("America/New_York");
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    findBoundariesStepwise(1997, ONE_DAY, zone, 2);
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete zone;
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    zone = TimeZone::createTimeZone("UTC"); // updated 12/3/99 aliu
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    findBoundariesStepwise(1997, ONE_DAY, zone, 0);
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete zone;
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    zone = TimeZone::createTimeZone("Australia/Adelaide");
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    findBoundariesStepwise(1997, ONE_DAY, zone, 2);
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete zone;
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
516