]>
Commit | Line | Data |
---|---|---|
1 | /******************************************************************** | |
2 | * COPYRIGHT: | |
3 | * Copyright (c) 1997-2003, International Business Machines Corporation and | |
4 | * others. All Rights Reserved. | |
5 | ********************************************************************/ | |
6 | ||
7 | #include "unicode/utypes.h" | |
8 | ||
9 | #if !UCONFIG_NO_FORMATTING | |
10 | ||
11 | #include "unicode/simpletz.h" | |
12 | #include "unicode/smpdtfmt.h" | |
13 | #include "unicode/strenum.h" | |
14 | #include "tzregts.h" | |
15 | #include "calregts.h" | |
16 | #include "cmemory.h" | |
17 | ||
18 | // ***************************************************************************** | |
19 | // class TimeZoneRegressionTest | |
20 | // ***************************************************************************** | |
21 | ||
22 | #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break | |
23 | ||
24 | void | |
25 | TimeZoneRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) | |
26 | { | |
27 | // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest"); | |
28 | switch (index) { | |
29 | ||
30 | CASE(0, Test4052967); | |
31 | CASE(1, Test4073209); | |
32 | CASE(2, Test4073215); | |
33 | CASE(3, Test4084933); | |
34 | CASE(4, Test4096952); | |
35 | CASE(5, Test4109314); | |
36 | CASE(6, Test4126678); | |
37 | CASE(7, Test4151406); | |
38 | CASE(8, Test4151429); | |
39 | CASE(9, Test4154537); | |
40 | CASE(10, Test4154542); | |
41 | CASE(11, Test4154650); | |
42 | CASE(12, Test4154525); | |
43 | CASE(13, Test4162593); | |
44 | CASE(14, TestJ186); | |
45 | CASE(15, TestJ449); | |
46 | CASE(16, TestJDK12API); | |
47 | ||
48 | default: name = ""; break; | |
49 | } | |
50 | } | |
51 | ||
52 | UBool | |
53 | TimeZoneRegressionTest::failure(UErrorCode status, const char* msg) | |
54 | { | |
55 | if(U_FAILURE(status)) { | |
56 | errln(UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status)); | |
57 | return TRUE; | |
58 | } | |
59 | ||
60 | return FALSE; | |
61 | } | |
62 | ||
63 | /** | |
64 | * @bug 4052967 | |
65 | */ | |
66 | void TimeZoneRegressionTest:: Test4052967() { | |
67 | // {sfb} not applicable in C++ ? | |
68 | /*logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***"); | |
69 | logln("user.timezone:" + System.getProperty("user.timezone", "<not set>")); | |
70 | logln(new Date().toString()); | |
71 | logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");*/ | |
72 | } | |
73 | ||
74 | /** | |
75 | * @bug 4073209 | |
76 | */ | |
77 | void TimeZoneRegressionTest:: Test4073209() { | |
78 | TimeZone *z1 = TimeZone::createTimeZone("PST"); | |
79 | TimeZone *z2 = TimeZone::createTimeZone("PST"); | |
80 | if (z1 == z2) | |
81 | errln("Fail: TimeZone should return clones"); | |
82 | delete z1; | |
83 | delete z2; | |
84 | } | |
85 | ||
86 | UDate TimeZoneRegressionTest::findTransitionBinary(const SimpleTimeZone& tz, UDate min, UDate max) { | |
87 | UErrorCode status = U_ZERO_ERROR; | |
88 | UBool startsInDST = tz.inDaylightTime(min, status); | |
89 | if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
90 | if (tz.inDaylightTime(max, status) == startsInDST) { | |
91 | logln((UnicodeString)"Error: inDaylightTime() != " + ((!startsInDST)?"TRUE":"FALSE")); | |
92 | return 0; | |
93 | } | |
94 | if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
95 | while ((max - min) > 100) { // Min accuracy in ms | |
96 | UDate mid = (min + max) / 2; | |
97 | if (tz.inDaylightTime(mid, status) == startsInDST) { | |
98 | min = mid; | |
99 | } else { | |
100 | max = mid; | |
101 | } | |
102 | if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
103 | } | |
104 | return (min + max) / 2; | |
105 | } | |
106 | ||
107 | UDate TimeZoneRegressionTest::findTransitionStepwise(const SimpleTimeZone& tz, UDate min, UDate max) { | |
108 | UErrorCode status = U_ZERO_ERROR; | |
109 | UBool startsInDST = tz.inDaylightTime(min, status); | |
110 | if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
111 | while (min < max) { | |
112 | if (tz.inDaylightTime(min, status) != startsInDST) { | |
113 | return min; | |
114 | } | |
115 | if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
116 | min += (UDate)24*60*60*1000; // one day | |
117 | } | |
118 | return 0; | |
119 | } | |
120 | ||
121 | /** | |
122 | * @bug 4073215 | |
123 | */ | |
124 | // {sfb} will this work using a Calendar? | |
125 | void TimeZoneRegressionTest:: Test4073215() | |
126 | { | |
127 | UErrorCode status = U_ZERO_ERROR; | |
128 | UnicodeString str, str2; | |
129 | SimpleTimeZone *z = new SimpleTimeZone(0, "GMT"); | |
130 | if (z->useDaylightTime()) | |
131 | errln("Fail: Fix test to start with non-DST zone"); | |
132 | z->setStartRule(UCAL_FEBRUARY, 1, UCAL_SUNDAY, 0, status); | |
133 | failure(status, "z->setStartRule()"); | |
134 | z->setEndRule(UCAL_MARCH, -1, UCAL_SUNDAY, 0, status); | |
135 | failure(status, "z->setStartRule()"); | |
136 | if (!z->useDaylightTime()) | |
137 | errln("Fail: DST not active"); | |
138 | ||
139 | GregorianCalendar cal(1997, UCAL_JANUARY, 31, status); | |
140 | if(U_FAILURE(status)) { | |
141 | errln("Error creating calendar %s", u_errorName(status)); | |
142 | return; | |
143 | } | |
144 | failure(status, "new GregorianCalendar"); | |
145 | cal.adoptTimeZone(z); | |
146 | ||
147 | SimpleDateFormat sdf((UnicodeString)"E d MMM yyyy G HH:mm", status); | |
148 | if(U_FAILURE(status)) { | |
149 | errln("Error creating date format %s", u_errorName(status)); | |
150 | return; | |
151 | } | |
152 | sdf.setCalendar(cal); | |
153 | failure(status, "new SimpleDateFormat"); | |
154 | ||
155 | UDate jan31, mar1, mar31; | |
156 | ||
157 | UBool indt = z->inDaylightTime(jan31=cal.getTime(status), status); | |
158 | failure(status, "inDaylightTime or getTime call on Jan 31"); | |
159 | if (indt) { | |
160 | errln("Fail: Jan 31 inDaylightTime=TRUE, exp FALSE"); | |
161 | } | |
162 | cal.set(1997, UCAL_MARCH, 1); | |
163 | indt = z->inDaylightTime(mar1=cal.getTime(status), status); | |
164 | failure(status, "inDaylightTime or getTime call on Mar 1"); | |
165 | if (!indt) { | |
166 | UnicodeString str; | |
167 | sdf.format(cal.getTime(status), str); | |
168 | failure(status, "getTime"); | |
169 | errln((UnicodeString)"Fail: " + str + " inDaylightTime=FALSE, exp TRUE"); | |
170 | } | |
171 | cal.set(1997, UCAL_MARCH, 31); | |
172 | indt = z->inDaylightTime(mar31=cal.getTime(status), status); | |
173 | failure(status, "inDaylightTime or getTime call on Mar 31"); | |
174 | if (indt) { | |
175 | errln("Fail: Mar 31 inDaylightTime=TRUE, exp FALSE"); | |
176 | } | |
177 | ||
178 | /* | |
179 | cal.set(1997, Calendar::DECEMBER, 31); | |
180 | UDate dec31 = cal.getTime(status); | |
181 | failure(status, "getTime"); | |
182 | UDate trans = findTransitionStepwise(*z, jan31, dec31); | |
183 | logln((UnicodeString)"Stepwise from " + | |
184 | sdf.format(jan31, str.remove()) + "; transition at " + | |
185 | (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE")); | |
186 | trans = findTransitionStepwise(*z, mar1, dec31); | |
187 | logln((UnicodeString)"Stepwise from " + | |
188 | sdf.format(mar1, str.remove()) + "; transition at " + | |
189 | (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE")); | |
190 | trans = findTransitionStepwise(*z, mar31, dec31); | |
191 | logln((UnicodeString)"Stepwise from " + | |
192 | sdf.format(mar31, str.remove()) + "; transition at " + | |
193 | (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE")); | |
194 | */ | |
195 | } | |
196 | ||
197 | /** | |
198 | * @bug 4084933 | |
199 | * The expected behavior of TimeZone around the boundaries is: | |
200 | * (Assume transition time of 2:00 AM) | |
201 | * day of onset 1:59 AM STD = display name 1:59 AM ST | |
202 | * 2:00 AM STD = display name 3:00 AM DT | |
203 | * day of end 0:59 AM STD = display name 1:59 AM DT | |
204 | * 1:00 AM STD = display name 1:00 AM ST | |
205 | */ | |
206 | void TimeZoneRegressionTest:: Test4084933() { | |
207 | UErrorCode status = U_ZERO_ERROR; | |
208 | TimeZone *tz = TimeZone::createTimeZone("PST"); | |
209 | ||
210 | int32_t offset1 = tz->getOffset(1, | |
211 | 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), status); | |
212 | int32_t offset2 = tz->getOffset(1, | |
213 | 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000)-1, status); | |
214 | ||
215 | int32_t offset3 = tz->getOffset(1, | |
216 | 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (1*60*60*1000), status); | |
217 | int32_t offset4 = tz->getOffset(1, | |
218 | 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (1*60*60*1000)-1, status); | |
219 | ||
220 | /* | |
221 | * The following was added just for consistency. It shows that going *to* Daylight | |
222 | * Savings Time (PDT) does work at 2am. | |
223 | */ | |
224 | ||
225 | int32_t offset5 = tz->getOffset(1, | |
226 | 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (2*60*60*1000), status); | |
227 | int32_t offset6 = tz->getOffset(1, | |
228 | 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (2*60*60*1000)-1, status); | |
229 | ||
230 | int32_t offset7 = tz->getOffset(1, | |
231 | 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (1*60*60*1000), status); | |
232 | int32_t offset8 = tz->getOffset(1, | |
233 | 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (1*60*60*1000)-1, status); | |
234 | ||
235 | int32_t SToffset = (int32_t)(-8 * 60*60*1000L); | |
236 | int32_t DToffset = (int32_t)(-7 * 60*60*1000L); | |
237 | if (offset1 != SToffset || offset2 != SToffset || | |
238 | offset3 != SToffset || offset4 != DToffset || | |
239 | offset5 != DToffset || offset6 != SToffset || | |
240 | offset7 != SToffset || offset8 != SToffset | |
241 | || U_FAILURE(status)) | |
242 | errln("Fail: TimeZone misbehaving"); | |
243 | ||
244 | delete tz; | |
245 | } | |
246 | ||
247 | /** | |
248 | * @bug 4096952 | |
249 | */ | |
250 | void TimeZoneRegressionTest:: Test4096952() { | |
251 | // {sfb} serialization not applicable | |
252 | /* | |
253 | UnicodeString ZONES [] = { UnicodeString("GMT"), UnicodeString("MET"), UnicodeString("IST") }; | |
254 | UBool pass = TRUE; | |
255 | //try { | |
256 | for (int32_t i=0; i < ZONES.length; ++i) { | |
257 | TimeZone *zone = TimeZone::createTimeZone(ZONES[i]); | |
258 | UnicodeString id; | |
259 | if (zone->getID(id) != ZONES[i]) | |
260 | errln("Fail: Test broken; zones not instantiating"); | |
261 | ||
262 | ByteArrayOutputStream baos; | |
263 | ObjectOutputStream ostream = | |
264 | new ObjectOutputStream(baos = new | |
265 | ByteArrayOutputStream()); | |
266 | ostream.writeObject(zone); | |
267 | ostream.close(); | |
268 | baos.close(); | |
269 | ObjectInputStream istream = | |
270 | new ObjectInputStream(new | |
271 | ByteArrayInputStream(baos.toByteArray())); | |
272 | TimeZone frankenZone = (TimeZone) istream.readObject(); | |
273 | //logln("Zone: " + zone); | |
274 | //logln("FrankenZone: " + frankenZone); | |
275 | if (!zone.equals(frankenZone)) { | |
276 | logln("TimeZone " + zone.getID() + | |
277 | " not equal to serialized/deserialized one"); | |
278 | pass = false; | |
279 | } | |
280 | } | |
281 | if (!pass) errln("Fail: TimeZone serialization/equality bug"); | |
282 | } | |
283 | catch (IOException e) { | |
284 | errln("Fail: " + e); | |
285 | e.print32_tStackTrace(); | |
286 | } | |
287 | catch (ClassNotFoundException e) { | |
288 | errln("Fail: " + e); | |
289 | e.print32_tStackTrace(); | |
290 | } | |
291 | */ | |
292 | } | |
293 | ||
294 | /** | |
295 | * @bug 4109314 | |
296 | */ | |
297 | void TimeZoneRegressionTest:: Test4109314() { | |
298 | UErrorCode status = U_ZERO_ERROR; | |
299 | GregorianCalendar *testCal = (GregorianCalendar*)Calendar::createInstance(status); | |
300 | if(U_FAILURE(status)) { | |
301 | errln("Error creating calendar %s", u_errorName(status)); | |
302 | delete testCal; | |
303 | return; | |
304 | } | |
305 | failure(status, "Calendar::createInstance"); | |
306 | TimeZone *PST = TimeZone::createTimeZone("PST"); | |
307 | /*Object[] testData = { | |
308 | PST, new Date(98,Calendar.APRIL,4,22,0), new Date(98, Calendar.APRIL, 5,6,0), | |
309 | PST, new Date(98,Calendar.OCTOBER,24,22,0), new Date(98,Calendar.OCTOBER,25,6,0), | |
310 | };*/ | |
311 | UDate testData [] = { | |
312 | CalendarRegressionTest::makeDate(98,UCAL_APRIL,4,22,0), | |
313 | CalendarRegressionTest::makeDate(98, UCAL_APRIL,5,6,0), | |
314 | CalendarRegressionTest::makeDate(98,UCAL_OCTOBER,24,22,0), | |
315 | CalendarRegressionTest::makeDate(98,UCAL_OCTOBER,25,6,0) | |
316 | }; | |
317 | UBool pass = TRUE; | |
318 | for (int32_t i = 0; i < 4; i+=2) { | |
319 | //testCal->setTimeZone((TimeZone) testData[i]); | |
320 | testCal->setTimeZone(*PST); | |
321 | UDate t = testData[i]; | |
322 | UDate end = testData[i+1]; | |
323 | while(testCal->getTime(status) < end) { | |
324 | testCal->setTime(t, status); | |
325 | if ( ! checkCalendar314(testCal, PST)) | |
326 | pass = FALSE; | |
327 | t += 60*60*1000.0; | |
328 | } | |
329 | } | |
330 | if ( ! pass) | |
331 | errln("Fail: TZ API inconsistent"); | |
332 | ||
333 | delete testCal; | |
334 | delete PST; | |
335 | } | |
336 | ||
337 | UBool | |
338 | TimeZoneRegressionTest::checkCalendar314(GregorianCalendar *testCal, TimeZone *testTZ) | |
339 | { | |
340 | UErrorCode status = U_ZERO_ERROR; | |
341 | // GregorianCalendar testCal = (GregorianCalendar)aCal.clone(); | |
342 | ||
343 | int32_t tzOffset, tzRawOffset; | |
344 | float tzOffsetFloat,tzRawOffsetFloat; | |
345 | // Here is where the user made an error. They were passing in the value of | |
346 | // the MILLSECOND field; you need to pass in the millis in the day in STANDARD | |
347 | // time. | |
348 | UDate millis = testCal->get(UCAL_MILLISECOND, status) + | |
349 | 1000.0 * (testCal->get(UCAL_SECOND, status) + | |
350 | 60.0 * (testCal->get(UCAL_MINUTE, status) + | |
351 | 60.0 * (testCal->get(UCAL_HOUR_OF_DAY, status)))) - | |
352 | testCal->get(UCAL_DST_OFFSET, status); | |
353 | ||
354 | /* Fix up millis to be in range. ASSUME THAT WE ARE NOT AT THE | |
355 | * BEGINNING OR END OF A MONTH. We must add this code because | |
356 | * getOffset() has been changed to be more strict about the parameters | |
357 | * it receives -- it turns out that this test was passing in illegal | |
358 | * values. */ | |
359 | int32_t date = testCal->get(UCAL_DATE, status); | |
360 | int32_t dow = testCal->get(UCAL_DAY_OF_WEEK, status); | |
361 | while(millis < 0) { | |
362 | millis += U_MILLIS_PER_DAY; | |
363 | --date; | |
364 | dow = UCAL_SUNDAY + ((dow - UCAL_SUNDAY + 6) % 7); | |
365 | } | |
366 | while (millis >= U_MILLIS_PER_DAY) { | |
367 | millis -= U_MILLIS_PER_DAY; | |
368 | ++date; | |
369 | dow = UCAL_SUNDAY + ((dow - UCAL_SUNDAY + 1) % 7); | |
370 | } | |
371 | ||
372 | tzOffset = testTZ->getOffset((uint8_t)testCal->get(UCAL_ERA, status), | |
373 | testCal->get(UCAL_YEAR, status), | |
374 | testCal->get(UCAL_MONTH, status), | |
375 | date, | |
376 | (uint8_t)dow, | |
377 | (int32_t)millis, | |
378 | status); | |
379 | tzRawOffset = testTZ->getRawOffset(); | |
380 | tzOffsetFloat = (float)tzOffset/(float)3600000; | |
381 | tzRawOffsetFloat = (float)tzRawOffset/(float)3600000; | |
382 | ||
383 | UDate testDate = testCal->getTime(status); | |
384 | ||
385 | UBool inDaylightTime = testTZ->inDaylightTime(testDate, status); | |
386 | SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)"MM/dd/yyyy HH:mm", status); | |
387 | sdf->setCalendar(*testCal); | |
388 | UnicodeString inDaylightTimeString; | |
389 | ||
390 | UBool passed; | |
391 | ||
392 | if(inDaylightTime) | |
393 | { | |
394 | inDaylightTimeString = " DST "; | |
395 | passed = (tzOffset == (tzRawOffset + 3600000)); | |
396 | } | |
397 | else | |
398 | { | |
399 | inDaylightTimeString = " "; | |
400 | passed = (tzOffset == tzRawOffset); | |
401 | } | |
402 | ||
403 | UnicodeString output; | |
404 | FieldPosition pos(0); | |
405 | output = testTZ->getID(output) + " " + sdf->format(testDate, output, pos) + | |
406 | " Offset(" + tzOffsetFloat + ")" + | |
407 | " RawOffset(" + tzRawOffsetFloat + ")" + | |
408 | " " + millis/(float)3600000 + " " + | |
409 | inDaylightTimeString; | |
410 | ||
411 | if (passed) | |
412 | output += " "; | |
413 | else | |
414 | output += "ERROR"; | |
415 | ||
416 | if (passed) | |
417 | logln(output); | |
418 | else | |
419 | errln(output); | |
420 | ||
421 | delete sdf; | |
422 | return passed; | |
423 | } | |
424 | ||
425 | /** | |
426 | * @bug 4126678 | |
427 | * CANNOT REPRODUDE | |
428 | * | |
429 | * Yet another _alleged_ bug in TimeZone::getOffset(), a method that never | |
430 | * should have been made public. It's simply too hard to use correctly. | |
431 | * | |
432 | * The original test code failed to do the following: | |
433 | * (1) Call Calendar::setTime() before getting the fields! | |
434 | * (2) Use the right millis (as usual) for getOffset(); they were passing | |
435 | * in the MILLIS field, instead of the STANDARD MILLIS IN DAY. | |
436 | * When you fix these two problems, the test passes, as expected. | |
437 | */ | |
438 | void TimeZoneRegressionTest:: Test4126678() | |
439 | { | |
440 | UErrorCode status = U_ZERO_ERROR; | |
441 | Calendar *cal = Calendar::createInstance(status); | |
442 | if(U_FAILURE(status)) { | |
443 | errln("Error creating calendar %s", u_errorName(status)); | |
444 | delete cal; | |
445 | return; | |
446 | } | |
447 | failure(status, "Calendar::createInstance"); | |
448 | TimeZone *tz = TimeZone::createTimeZone("PST"); | |
449 | cal->adoptTimeZone(tz); | |
450 | ||
451 | cal->set(1998 - 1900, UCAL_APRIL, 5, 10, 0); | |
452 | //Date dt = new Date(1998-1900, Calendar::APRIL, 5, 10, 0); | |
453 | ||
454 | if (! tz->useDaylightTime() || U_FAILURE(status)) | |
455 | errln("We're not in Daylight Savings Time and we should be.\n"); | |
456 | ||
457 | //cal.setTime(dt); | |
458 | int32_t era = cal->get(UCAL_ERA, status); | |
459 | int32_t year = cal->get(UCAL_YEAR, status); | |
460 | int32_t month = cal->get(UCAL_MONTH, status); | |
461 | int32_t day = cal->get(UCAL_DATE, status); | |
462 | int32_t dayOfWeek = cal->get(UCAL_DAY_OF_WEEK, status); | |
463 | int32_t millis = cal->get(UCAL_MILLISECOND, status) + | |
464 | (cal->get(UCAL_SECOND, status) + | |
465 | (cal->get(UCAL_MINUTE, status) + | |
466 | (cal->get(UCAL_HOUR, status) * 60) * 60) * 1000) - | |
467 | cal->get(UCAL_DST_OFFSET, status); | |
468 | ||
469 | failure(status, "cal->get"); | |
470 | int32_t offset = tz->getOffset((uint8_t)era, year, month, day, (uint8_t)dayOfWeek, millis, status); | |
471 | int32_t raw_offset = tz->getRawOffset(); | |
472 | if (offset == raw_offset) | |
473 | errln("Offsets should not match when in DST"); | |
474 | ||
475 | delete cal; | |
476 | } | |
477 | ||
478 | /** | |
479 | * @bug 4151406 | |
480 | * TimeZone::getAvailableIDs(int32_t) throws exception for certain values, | |
481 | * due to a faulty constant in TimeZone::java. | |
482 | */ | |
483 | void TimeZoneRegressionTest:: Test4151406() { | |
484 | int32_t max = 0; | |
485 | for (int32_t h=-28; h<=30; ++h) { | |
486 | // h is in half-hours from GMT; rawoffset is in millis | |
487 | int32_t rawoffset = h * 1800000; | |
488 | int32_t hh = (h<0) ? -h : h; | |
489 | UnicodeString hname = UnicodeString((h<0) ? "GMT-" : "GMT+") + | |
490 | ((hh/2 < 10) ? "0" : "") + | |
491 | (hh/2) + ':' + | |
492 | ((hh%2==0) ? "00" : "30"); | |
493 | //try { | |
494 | UErrorCode ec = U_ZERO_ERROR; | |
495 | int32_t count; | |
496 | StringEnumeration* ids = TimeZone::createEnumeration(rawoffset); | |
497 | count = ids->count(ec); | |
498 | if (count> max) | |
499 | max = count; | |
500 | if (count > 0) { | |
501 | logln(hname + ' ' + (UnicodeString)count + (UnicodeString)" e.g. " + *ids->snext(ec)); | |
502 | } else { | |
503 | logln(hname + ' ' + count); | |
504 | } | |
505 | // weiv 11/27/2002: why uprv_free? This should be a delete | |
506 | delete ids; | |
507 | //delete [] ids; | |
508 | //uprv_free(ids); | |
509 | /*} catch (Exception e) { | |
510 | errln(hname + ' ' + "Fail: " + e); | |
511 | }*/ | |
512 | } | |
513 | logln("Maximum zones per offset = %d", max); | |
514 | } | |
515 | ||
516 | /** | |
517 | * @bug 4151429 | |
518 | */ | |
519 | void TimeZoneRegressionTest:: Test4151429() { | |
520 | // {sfb} silly test in C++, since we are using an enum and not an int | |
521 | //try { | |
522 | /*TimeZone *tz = TimeZone::createTimeZone("GMT"); | |
523 | UnicodeString name; | |
524 | tz->getDisplayName(TRUE, TimeZone::LONG, | |
525 | Locale.getDefault(), name); | |
526 | errln("IllegalArgumentException not thrown by TimeZone::getDisplayName()");*/ | |
527 | //} catch(IllegalArgumentException e) {} | |
528 | } | |
529 | ||
530 | /** | |
531 | * @bug 4154537 | |
532 | * SimpleTimeZone::hasSameRules() doesn't work for zones with no DST | |
533 | * and different DST parameters. | |
534 | */ | |
535 | void TimeZoneRegressionTest:: Test4154537() { | |
536 | UErrorCode status = U_ZERO_ERROR; | |
537 | // tz1 and tz2 have no DST and different rule parameters | |
538 | SimpleTimeZone *tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0, status); | |
539 | SimpleTimeZone *tz2 = new SimpleTimeZone(0, "2", 1, 0, 0, 0, 3, 0, 0, 0, status); | |
540 | // tza and tzA have the same rule params | |
541 | SimpleTimeZone *tza = new SimpleTimeZone(0, "a", 0, 1, 0, 0, 3, 2, 0, 0, status); | |
542 | SimpleTimeZone *tzA = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 3, 2, 0, 0, status); | |
543 | // tzb differs from tza | |
544 | SimpleTimeZone *tzb = new SimpleTimeZone(0, "b", 0, 1, 0, 0, 3, 1, 0, 0, status); | |
545 | ||
546 | if(U_FAILURE(status)) | |
547 | errln("Couldn't create TimeZones"); | |
548 | ||
549 | if (tz1->useDaylightTime() || tz2->useDaylightTime() || | |
550 | !tza->useDaylightTime() || !tzA->useDaylightTime() || | |
551 | !tzb->useDaylightTime()) { | |
552 | errln("Test is broken -- rewrite it"); | |
553 | } | |
554 | if (!tza->hasSameRules(*tzA) || tza->hasSameRules(*tzb)) { | |
555 | errln("Fail: hasSameRules() broken for zones with rules"); | |
556 | } | |
557 | if (!tz1->hasSameRules(*tz2)) { | |
558 | errln("Fail: hasSameRules() returns false for zones without rules"); | |
559 | //errln("zone 1 = " + tz1); | |
560 | //errln("zone 2 = " + tz2); | |
561 | } | |
562 | ||
563 | delete tz1; | |
564 | delete tz2; | |
565 | delete tza; | |
566 | delete tzA; | |
567 | delete tzb; | |
568 | } | |
569 | ||
570 | /** | |
571 | * @bug 4154542 | |
572 | * SimpleTimeZOne constructors, setStartRule(), and setEndRule() don't | |
573 | * check for out-of-range arguments. | |
574 | */ | |
575 | void TimeZoneRegressionTest:: Test4154542() | |
576 | { | |
577 | const int32_t GOOD = 1; | |
578 | const int32_t BAD = 0; | |
579 | ||
580 | const int32_t GOOD_MONTH = UCAL_JANUARY; | |
581 | const int32_t GOOD_DAY = 1; | |
582 | const int32_t GOOD_DAY_OF_WEEK = UCAL_SUNDAY; | |
583 | const int32_t GOOD_TIME = 0; | |
584 | ||
585 | int32_t DATA [] = { | |
586 | GOOD, INT32_MIN, 0, INT32_MAX, INT32_MIN, | |
587 | GOOD, UCAL_JANUARY, -5, UCAL_SUNDAY, 0, | |
588 | GOOD, UCAL_DECEMBER, 5, UCAL_SATURDAY, 24*60*60*1000, | |
589 | BAD, UCAL_DECEMBER, 5, UCAL_SATURDAY, 24*60*60*1000+1, | |
590 | BAD, UCAL_DECEMBER, 5, UCAL_SATURDAY, -1, | |
591 | BAD, UCAL_JANUARY, -6, UCAL_SUNDAY, 0, | |
592 | BAD, UCAL_DECEMBER, 6, UCAL_SATURDAY, 24*60*60*1000, | |
593 | GOOD, UCAL_DECEMBER, 1, 0, 0, | |
594 | GOOD, UCAL_DECEMBER, 31, 0, 0, | |
595 | BAD, UCAL_APRIL, 31, 0, 0, | |
596 | BAD, UCAL_DECEMBER, 32, 0, 0, | |
597 | BAD, UCAL_JANUARY-1, 1, UCAL_SUNDAY, 0, | |
598 | BAD, UCAL_DECEMBER+1, 1, UCAL_SUNDAY, 0, | |
599 | GOOD, UCAL_DECEMBER, 31, -UCAL_SUNDAY, 0, | |
600 | GOOD, UCAL_DECEMBER, 31, -UCAL_SATURDAY, 0, | |
601 | BAD, UCAL_DECEMBER, 32, -UCAL_SATURDAY, 0, | |
602 | BAD, UCAL_DECEMBER, -32, -UCAL_SATURDAY, 0, | |
603 | BAD, UCAL_DECEMBER, 31, -UCAL_SATURDAY-1, 0, | |
604 | }; | |
605 | SimpleTimeZone *zone = new SimpleTimeZone(0, "Z"); | |
606 | for (int32_t i=0; i < 18*5; i+=5) { | |
607 | UBool shouldBeGood = (DATA[i] == GOOD); | |
608 | int32_t month = DATA[i+1]; | |
609 | int32_t day = DATA[i+2]; | |
610 | int32_t dayOfWeek = DATA[i+3]; | |
611 | int32_t time = DATA[i+4]; | |
612 | ||
613 | UErrorCode status = U_ZERO_ERROR; | |
614 | ||
615 | //Exception ex = null; | |
616 | //try { | |
617 | zone->setStartRule(month, day, dayOfWeek, time, status); | |
618 | //} catch (IllegalArgumentException e) { | |
619 | // ex = e; | |
620 | //} | |
621 | if (U_SUCCESS(status) != shouldBeGood) { | |
622 | errln(UnicodeString("setStartRule(month=") + month + ", day=" + day + | |
623 | ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
624 | (shouldBeGood ? (") should work") | |
625 | : ") should fail but doesn't")); | |
626 | } | |
627 | ||
628 | //ex = null; | |
629 | //try { | |
630 | status = U_ZERO_ERROR; | |
631 | zone->setEndRule(month, day, dayOfWeek, time, status); | |
632 | //} catch (IllegalArgumentException e) { | |
633 | // ex = e; | |
634 | //} | |
635 | if (U_SUCCESS(status) != shouldBeGood) { | |
636 | errln(UnicodeString("setEndRule(month=") + month + ", day=" + day + | |
637 | ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
638 | (shouldBeGood ? (") should work") | |
639 | : ") should fail but doesn't")); | |
640 | } | |
641 | ||
642 | //ex = null; | |
643 | //try { | |
644 | // {sfb} need to look into ctor problems! (UErrorCode vs. dst signature confusion) | |
645 | status = U_ZERO_ERROR; | |
646 | SimpleTimeZone *temp = new SimpleTimeZone(0, "Z", | |
647 | (int8_t)month, (int8_t)day, (int8_t)dayOfWeek, time, | |
648 | (int8_t)GOOD_MONTH, (int8_t)GOOD_DAY, (int8_t)GOOD_DAY_OF_WEEK, | |
649 | GOOD_TIME,status); | |
650 | //} catch (IllegalArgumentException e) { | |
651 | // ex = e; | |
652 | //} | |
653 | if (U_SUCCESS(status) != shouldBeGood) { | |
654 | errln(UnicodeString("SimpleTimeZone(month=") + month + ", day=" + day + | |
655 | ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
656 | (shouldBeGood ? (", <end>) should work")// + ex) | |
657 | : ", <end>) should fail but doesn't")); | |
658 | } | |
659 | ||
660 | delete temp; | |
661 | //ex = null; | |
662 | //try { | |
663 | status = U_ZERO_ERROR; | |
664 | temp = new SimpleTimeZone(0, "Z", | |
665 | (int8_t)GOOD_MONTH, (int8_t)GOOD_DAY, (int8_t)GOOD_DAY_OF_WEEK, | |
666 | GOOD_TIME, | |
667 | (int8_t)month, (int8_t)day, (int8_t)dayOfWeek, time,status); | |
668 | //} catch (IllegalArgumentException e) { | |
669 | // ex = e; | |
670 | //} | |
671 | if (U_SUCCESS(status) != shouldBeGood) { | |
672 | errln(UnicodeString("SimpleTimeZone(<start>, month=") + month + ", day=" + day + | |
673 | ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
674 | (shouldBeGood ? (") should work")// + ex) | |
675 | : ") should fail but doesn't")); | |
676 | } | |
677 | delete temp; | |
678 | } | |
679 | delete zone; | |
680 | } | |
681 | ||
682 | ||
683 | /** | |
684 | * @bug 4154525 | |
685 | * SimpleTimeZone accepts illegal DST savings values. These values | |
686 | * must be non-zero. There is no upper limit at this time. | |
687 | */ | |
688 | void | |
689 | TimeZoneRegressionTest::Test4154525() | |
690 | { | |
691 | const int32_t GOOD = 1, BAD = 0; | |
692 | ||
693 | int32_t DATA [] = { | |
694 | 1, GOOD, | |
695 | 0, BAD, | |
696 | -1, BAD, | |
697 | 60*60*1000, GOOD, | |
698 | INT32_MIN, BAD, | |
699 | // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time | |
700 | }; | |
701 | ||
702 | UErrorCode status = U_ZERO_ERROR; | |
703 | for(int32_t i = 0; i < 10; i+=2) { | |
704 | int32_t savings = DATA[i]; | |
705 | UBool valid = DATA[i+1] == GOOD; | |
706 | UnicodeString method; | |
707 | for(int32_t j=0; j < 2; ++j) { | |
708 | SimpleTimeZone *z=NULL; | |
709 | switch (j) { | |
710 | case 0: | |
711 | method = "constructor"; | |
712 | z = new SimpleTimeZone(0, "id", | |
713 | UCAL_JANUARY, 1, 0, 0, | |
714 | UCAL_MARCH, 1, 0, 0, | |
715 | savings, status); // <- what we're interested in | |
716 | break; | |
717 | case 1: | |
718 | method = "setDSTSavings()"; | |
719 | z = new SimpleTimeZone(0, "GMT"); | |
720 | z->setDSTSavings(savings, status); | |
721 | break; | |
722 | } | |
723 | ||
724 | if(U_FAILURE(status)) { | |
725 | if(valid) { | |
726 | errln(UnicodeString("Fail: DST savings of ") + savings + " to " + method + " gave " + u_errorName(status)); | |
727 | } | |
728 | else { | |
729 | logln(UnicodeString("Pass: DST savings of ") + savings + " to " + method + " gave " + u_errorName(status)); | |
730 | } | |
731 | } | |
732 | else { | |
733 | if(valid) { | |
734 | logln(UnicodeString("Pass: DST savings of ") + savings + " accepted by " + method); | |
735 | } | |
736 | else { | |
737 | errln(UnicodeString("Fail: DST savings of ") + savings + " accepted by " + method); | |
738 | } | |
739 | } | |
740 | status = U_ZERO_ERROR; | |
741 | delete z; | |
742 | } | |
743 | } | |
744 | } | |
745 | ||
746 | /** | |
747 | * @bug 4154650 | |
748 | * SimpleTimeZone.getOffset accepts illegal arguments. | |
749 | */ | |
750 | void | |
751 | TimeZoneRegressionTest::Test4154650() | |
752 | { | |
753 | const int32_t GOOD = 1, BAD = 0; | |
754 | const int32_t GOOD_ERA = GregorianCalendar::AD, GOOD_YEAR = 1998, GOOD_MONTH = UCAL_AUGUST; | |
755 | const int32_t GOOD_DAY = 2, GOOD_DOW = UCAL_SUNDAY, GOOD_TIME = 16*3600000; | |
756 | ||
757 | int32_t DATA []= { | |
758 | GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
759 | ||
760 | GOOD, GregorianCalendar::BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
761 | GOOD, GregorianCalendar::AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
762 | BAD, GregorianCalendar::BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
763 | BAD, GregorianCalendar::AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
764 | ||
765 | GOOD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
766 | GOOD, GOOD_ERA, GOOD_YEAR, UCAL_DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
767 | BAD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
768 | BAD, GOOD_ERA, GOOD_YEAR, UCAL_DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
769 | ||
770 | GOOD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 1, GOOD_DOW, GOOD_TIME, | |
771 | GOOD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 31, GOOD_DOW, GOOD_TIME, | |
772 | BAD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 0, GOOD_DOW, GOOD_TIME, | |
773 | BAD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 32, GOOD_DOW, GOOD_TIME, | |
774 | ||
775 | GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SUNDAY, GOOD_TIME, | |
776 | GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SATURDAY, GOOD_TIME, | |
777 | BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SUNDAY-1, GOOD_TIME, | |
778 | BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SATURDAY+1, GOOD_TIME, | |
779 | ||
780 | GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0, | |
781 | GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1, | |
782 | BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1, | |
783 | BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000, | |
784 | }; | |
785 | ||
786 | int32_t dataLen = (int32_t)(sizeof(DATA) / sizeof(DATA[0])); | |
787 | ||
788 | UErrorCode status = U_ZERO_ERROR; | |
789 | TimeZone *tz = TimeZone::createDefault(); | |
790 | for(int32_t i = 0; i < dataLen; i += 7) { | |
791 | UBool good = DATA[i] == GOOD; | |
792 | //IllegalArgumentException e = null; | |
793 | //try { | |
794 | /*int32_t offset = */ | |
795 | tz->getOffset((uint8_t)DATA[i+1], DATA[i+2], DATA[i+3], | |
796 | DATA[i+4], (uint8_t)DATA[i+5], DATA[i+6], status); | |
797 | //} catch (IllegalArgumentException ex) { | |
798 | // e = ex; | |
799 | //} | |
800 | if(good != U_SUCCESS(status)) { | |
801 | UnicodeString errMsg; | |
802 | if (good) { | |
803 | errMsg = (UnicodeString(") threw ") + u_errorName(status)); | |
804 | } | |
805 | else { | |
806 | errMsg = UnicodeString(") accepts invalid args", ""); | |
807 | } | |
808 | errln(UnicodeString("Fail: getOffset(") + | |
809 | DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " + | |
810 | DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] + | |
811 | errMsg); | |
812 | } | |
813 | status = U_ZERO_ERROR; // reset | |
814 | } | |
815 | delete tz; | |
816 | } | |
817 | ||
818 | /** | |
819 | * @bug 4162593 | |
820 | * TimeZone broken at midnight. The TimeZone code fails to handle | |
821 | * transitions at midnight correctly. | |
822 | */ | |
823 | void | |
824 | TimeZoneRegressionTest::Test4162593() | |
825 | { | |
826 | UErrorCode status = U_ZERO_ERROR; | |
827 | SimpleDateFormat *fmt = new SimpleDateFormat("z", Locale::getUS(), status); | |
828 | if(U_FAILURE(status)) { | |
829 | errln("Error creating calendar %s", u_errorName(status)); | |
830 | delete fmt; | |
831 | return; | |
832 | } | |
833 | const int32_t ONE_HOUR = 60*60*1000; | |
834 | ||
835 | SimpleTimeZone *asuncion = new SimpleTimeZone(-4*ONE_HOUR, "America/Asuncion" /*PY%sT*/, | |
836 | UCAL_OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, | |
837 | UCAL_MARCH, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR, status); | |
838 | ||
839 | /* Zone | |
840 | * Starting time | |
841 | * Transition expected between start+1H and start+2H | |
842 | */ | |
843 | TimeZone *DATA_TZ [] = { | |
844 | 0, 0, 0 }; | |
845 | ||
846 | int32_t DATA_INT [] [5] = { | |
847 | // These years must be AFTER the Gregorian cutover | |
848 | {1998, UCAL_SEPTEMBER, 30, 22, 0}, | |
849 | {2000, UCAL_FEBRUARY, 28, 22, 0}, | |
850 | {2000, UCAL_FEBRUARY, 29, 22, 0}, | |
851 | }; | |
852 | ||
853 | UBool DATA_BOOL [] = { | |
854 | TRUE, | |
855 | FALSE, | |
856 | TRUE, | |
857 | }; | |
858 | ||
859 | UnicodeString zone [4];// = new String[4]; | |
860 | DATA_TZ[0] = | |
861 | new SimpleTimeZone(2*ONE_HOUR, "Asia/Damascus" /*EE%sT*/, | |
862 | UCAL_APRIL, 1, 0 /*DOM*/, 0*ONE_HOUR, | |
863 | UCAL_OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR, status); | |
864 | DATA_TZ[1] = asuncion; DATA_TZ[2] = asuncion; | |
865 | ||
866 | for(int32_t j = 0; j < 3; j++) { | |
867 | TimeZone *tz = (TimeZone*)DATA_TZ[j]; | |
868 | TimeZone::setDefault(*tz); | |
869 | fmt->setTimeZone(*tz); | |
870 | ||
871 | // Must construct the Date object AFTER setting the default zone | |
872 | int32_t *p = (int32_t*)DATA_INT[j]; | |
873 | UDate d = CalendarRegressionTest::makeDate(p[0], p[1], p[2], p[3], p[4]); | |
874 | UBool transitionExpected = DATA_BOOL[j]; | |
875 | ||
876 | UnicodeString temp; | |
877 | logln(tz->getID(temp) + ":"); | |
878 | for (int32_t i = 0; i < 4; ++i) { | |
879 | FieldPosition pos(0); | |
880 | zone[i].remove(); | |
881 | zone[i] = fmt->format(d, zone[i], pos); | |
882 | logln(UnicodeString("") + i + ": " + d + " / " + zone[i]); | |
883 | d += (double) ONE_HOUR; | |
884 | } | |
885 | if(zone[0] == zone[1] && | |
886 | (zone[1] == zone[2]) != transitionExpected && | |
887 | zone[2] == zone[3]) { | |
888 | logln(UnicodeString("Ok: transition ") + transitionExpected); | |
889 | } | |
890 | else { | |
891 | errln("Fail: boundary transition incorrect"); | |
892 | } | |
893 | } | |
894 | delete fmt; | |
895 | delete asuncion; | |
896 | delete DATA_TZ[0]; | |
897 | } | |
898 | ||
899 | /** | |
900 | * Make sure setStartRule and setEndRule set the DST savings to nonzero | |
901 | * if it was zero. | |
902 | */ | |
903 | void TimeZoneRegressionTest::TestJ186() { | |
904 | UErrorCode status = U_ZERO_ERROR; | |
905 | // NOTE: Setting the DST savings to zero is illegal, so we | |
906 | // are limited in the testing we can do here. This is why | |
907 | // lines marked //~ are commented out. | |
908 | SimpleTimeZone z(0, "ID"); | |
909 | //~z.setDSTSavings(0, status); // Must do this! | |
910 | z.setStartRule(UCAL_FEBRUARY, 1, UCAL_SUNDAY, 0, status); | |
911 | failure(status, "setStartRule()"); | |
912 | if (z.useDaylightTime()) { | |
913 | errln("Fail: useDaylightTime true with start rule only"); | |
914 | } | |
915 | //~if (z.getDSTSavings() != 0) { | |
916 | //~ errln("Fail: dst savings != 0 with start rule only"); | |
917 | //~} | |
918 | z.setEndRule(UCAL_MARCH, -1, UCAL_SUNDAY, 0, status); | |
919 | failure(status, "setStartRule()"); | |
920 | if (!z.useDaylightTime()) { | |
921 | errln("Fail: useDaylightTime false with rules set"); | |
922 | } | |
923 | if (z.getDSTSavings() == 0) { | |
924 | errln("Fail: dst savings == 0 with rules set"); | |
925 | } | |
926 | } | |
927 | ||
928 | /** | |
929 | * Test to see if DateFormat understands zone equivalency groups. It | |
930 | * might seem that this should be a DateFormat test, but it's really a | |
931 | * TimeZone test -- the changes to DateFormat are minor. | |
932 | * | |
933 | * We use two known, stable zones that shouldn't change much over time | |
934 | * -- America/Vancouver and America/Los_Angeles. However, they MAY | |
935 | * change at some point -- if that happens, replace them with any two | |
936 | * zones in an equivalency group where one zone has localized name | |
937 | * data, and the other doesn't, in some locale. | |
938 | */ | |
939 | void TimeZoneRegressionTest::TestJ449() { | |
940 | UErrorCode status = U_ZERO_ERROR; | |
941 | UnicodeString str; | |
942 | ||
943 | // Modify the following three as necessary. The two IDs must | |
944 | // specify two zones in the same equivalency group. One must have | |
945 | // locale data in 'loc'; the other must not. | |
946 | const char* idWithLocaleData = "America/Los_Angeles"; | |
947 | const char* idWithoutLocaleData = "US/Pacific"; | |
948 | const Locale loc("en", "", ""); | |
949 | ||
950 | TimeZone *zoneWith = TimeZone::createTimeZone(idWithLocaleData); | |
951 | TimeZone *zoneWithout = TimeZone::createTimeZone(idWithoutLocaleData); | |
952 | // Make sure we got valid zones | |
953 | if (zoneWith->getID(str) != UnicodeString(idWithLocaleData) || | |
954 | zoneWithout->getID(str) != UnicodeString(idWithoutLocaleData)) { | |
955 | errln(UnicodeString("Fail: Unable to create zones - wanted ") + idWithLocaleData + ", got " + zoneWith->getID(str) + ", and wanted " + idWithoutLocaleData + " but got " + zoneWithout->getID(str)); | |
956 | } else { | |
957 | GregorianCalendar calWith(*zoneWith, status); | |
958 | GregorianCalendar calWithout(*zoneWithout, status); | |
959 | SimpleDateFormat fmt("MMM d yyyy hh:mm a zzz", loc, status); | |
960 | if (U_FAILURE(status)) { | |
961 | errln("Fail: Unable to create GregorianCalendar/SimpleDateFormat"); | |
962 | } else { | |
963 | UDate date = 0; | |
964 | UnicodeString strWith, strWithout; | |
965 | fmt.setCalendar(calWith); | |
966 | fmt.format(date, strWith); | |
967 | fmt.setCalendar(calWithout); | |
968 | fmt.format(date, strWithout); | |
969 | if (strWith == strWithout) { | |
970 | logln((UnicodeString)"Ok: " + idWithLocaleData + " -> " + | |
971 | strWith + "; " + idWithoutLocaleData + " -> " + | |
972 | strWithout); | |
973 | } else { | |
974 | errln((UnicodeString)"FAIL: " + idWithLocaleData + " -> " + | |
975 | strWith + "; " + idWithoutLocaleData + " -> " + | |
976 | strWithout); | |
977 | } | |
978 | } | |
979 | } | |
980 | ||
981 | delete zoneWith; | |
982 | delete zoneWithout; | |
983 | } | |
984 | ||
985 | // test new API for JDK 1.2 8/31 putback | |
986 | void | |
987 | TimeZoneRegressionTest::TestJDK12API() | |
988 | { | |
989 | // TimeZone *pst = TimeZone::createTimeZone("PST"); | |
990 | // TimeZone *cst1 = TimeZone::createTimeZone("CST"); | |
991 | UErrorCode ec = U_ZERO_ERROR; | |
992 | //d,-28800,3,1,-1,120,w,9,-1,1,120,w,60 | |
993 | TimeZone *pst = new SimpleTimeZone(-28800*U_MILLIS_PER_SECOND, | |
994 | "PST", | |
995 | 3,1,-1,120*U_MILLIS_PER_MINUTE, | |
996 | SimpleTimeZone::WALL_TIME, | |
997 | 9,-1,1,120*U_MILLIS_PER_MINUTE, | |
998 | SimpleTimeZone::WALL_TIME, | |
999 | 60*U_MILLIS_PER_MINUTE,ec); | |
1000 | //d,-21600,3,1,-1,120,w,9,-1,1,120,w,60 | |
1001 | TimeZone *cst1 = new SimpleTimeZone(-21600*U_MILLIS_PER_SECOND, | |
1002 | "CST", | |
1003 | 3,1,-1,120*U_MILLIS_PER_MINUTE, | |
1004 | SimpleTimeZone::WALL_TIME, | |
1005 | 9,-1,1,120*U_MILLIS_PER_MINUTE, | |
1006 | SimpleTimeZone::WALL_TIME, | |
1007 | 60*U_MILLIS_PER_MINUTE,ec); | |
1008 | if (U_FAILURE(ec)) { | |
1009 | errln("FAIL: SimpleTimeZone constructor"); | |
1010 | return; | |
1011 | } | |
1012 | ||
1013 | SimpleTimeZone *cst = 0; | |
1014 | ||
1015 | if(cst1->getDynamicClassID() == SimpleTimeZone::getStaticClassID()) | |
1016 | cst = (SimpleTimeZone*) cst1; | |
1017 | ||
1018 | if(pst->hasSameRules(*cst)) { | |
1019 | errln("FAILURE: PST and CST have same rules"); | |
1020 | } | |
1021 | ||
1022 | UErrorCode status = U_ZERO_ERROR; | |
1023 | int32_t offset1 = pst->getOffset(1, | |
1024 | 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), status); | |
1025 | failure(status, "getOffset() failed"); | |
1026 | ||
1027 | ||
1028 | int32_t offset2 = cst->getOffset(1, | |
1029 | 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), 31, status); | |
1030 | failure(status, "getOffset() failed"); | |
1031 | ||
1032 | if(offset1 == offset2) | |
1033 | errln("FAILURE: Sunday Oct. 26 1997 2:00 has same offset for PST and CST"); | |
1034 | ||
1035 | // verify error checking | |
1036 | pst->getOffset(1, | |
1037 | 1997, (UCalendarDateFields)-1, 26, UCAL_SUNDAY, (2*60*60*1000), status); | |
1038 | if(U_SUCCESS(status)) | |
1039 | errln("FAILURE: getOffset() succeeded with -1 for month"); | |
1040 | ||
1041 | status = U_ZERO_ERROR; | |
1042 | cst->setDSTSavings(60*60*1000, status); | |
1043 | failure(status, "setDSTSavings() failed"); | |
1044 | ||
1045 | int32_t savings = cst->getDSTSavings(); | |
1046 | if(savings != 60*60*1000) { | |
1047 | errln("setDSTSavings() failed"); | |
1048 | } | |
1049 | ||
1050 | delete pst; | |
1051 | delete cst; | |
1052 | } | |
1053 | ||
1054 | #endif /* #if !UCONFIG_NO_FORMATTING */ |