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