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