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