1// © 2016 and later: Unicode, Inc. and others. 2// License & terms of use: http://www.unicode.org/copyright.html#License 3/** 4 ******************************************************************************* 5 * Copyright (C) 2000-2014, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 */ 9 10/** 11 * @test 1.18 99/09/21 12 * @bug 4052967 4073209 4073215 4084933 4096952 4109314 4126678 4151406 4151429 13 * @bug 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960 14 */ 15 16package com.ibm.icu.dev.test.timezone; 17import java.io.ByteArrayInputStream; 18import java.io.ByteArrayOutputStream; 19import java.io.IOException; 20import java.io.ObjectInputStream; 21import java.io.ObjectOutputStream; 22import java.security.AccessControlException; 23import java.util.Date; 24import java.util.Locale; 25 26import org.junit.Test; 27 28import com.ibm.icu.dev.test.TestFmwk; 29import com.ibm.icu.text.DateFormat; 30import com.ibm.icu.text.SimpleDateFormat; 31import com.ibm.icu.util.Calendar; 32import com.ibm.icu.util.GregorianCalendar; 33import com.ibm.icu.util.SimpleTimeZone; 34import com.ibm.icu.util.TimeZone; 35import com.ibm.icu.util.ULocale; 36 37public class TimeZoneRegressionTest extends TestFmwk { 38 @Test 39 public void Test4052967() { 40 logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***"); 41 String id = TimeZone.getDefault().getID(); 42 try { 43 try { 44 logln("user.timezone: " + System.getProperty("user.timezone", "<not set>")); 45 } catch (AccessControlException e) { 46 // user.timezone is a protected system property - ignore 47 } 48 logln("TimeZone.getDefault().getID(): " + id); 49 logln(new Date().toString()); 50 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***"); 51 } 52 catch (SecurityException e) { 53 warnln("security exception: " + e.toString()); 54 } 55 } 56 57 @Test 58 public void Test4073209() { 59 TimeZone z1 = TimeZone.getTimeZone("PST"); 60 TimeZone z2 = TimeZone.getTimeZone("PST"); 61 if (z1 == z2) errln("Fail: TimeZone should return clones"); 62 } 63 64 @Test 65 public void Test4073215() { 66 SimpleTimeZone z = new SimpleTimeZone(0, "GMT"); 67 if (z.useDaylightTime()) 68 errln("Fail: Fix test to start with non-DST zone"); 69 z.setStartRule(Calendar.FEBRUARY, 1, Calendar.SUNDAY, 0); 70 z.setEndRule(Calendar.MARCH, -1, Calendar.SUNDAY, 0); 71 if (!z.useDaylightTime()) 72 errln("Fail: DST not active"); 73 Calendar tempcal = Calendar.getInstance(); 74 tempcal.clear(); 75 tempcal.setTimeZone(z); 76 tempcal.set(1997, Calendar.JANUARY, 31); 77 Date d1 = tempcal.getTime(); 78 if (z.inDaylightTime(d1)) { 79 errln("Fail: DST not working as expected"); 80 } 81 82 tempcal.set(1997, Calendar.MARCH, 1); 83 Date d2 = tempcal.getTime(); 84 if (!z.inDaylightTime(d2)) { 85 errln("Fail: DST not working as expected"); 86 } 87 tempcal.clear(); 88 tempcal.set(1997, Calendar.MARCH, 31); 89 Date d3 = tempcal.getTime(); 90 if (z.inDaylightTime(d3)) { 91 errln("Fail: DST not working as expected"); 92 } 93 } 94 95 /** 96 * The expected behavior of TimeZone around the boundaries is: 97 * (Assume transition time of 2:00 AM) 98 * day of onset 1:59 AM STD = display name 1:59 AM ST 99 * 2:00 AM STD = display name 3:00 AM DT 100 * day of end 0:59 AM STD = display name 1:59 AM DT 101 * 1:00 AM STD = display name 1:00 AM ST 102 */ 103 @Test 104 public void Test4084933() { 105 TimeZone tz = TimeZone.getTimeZone("PST"); 106 107 long offset1 = tz.getOffset(1, 108 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)); 109 long offset2 = tz.getOffset(1, 110 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)-1); 111 112 long offset3 = tz.getOffset(1, 113 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)); 114 long offset4 = tz.getOffset(1, 115 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)-1); 116 117 /* 118 * The following was added just for consistency. It shows that going *to* Daylight 119 * Savings Time (PDT) does work at 2am. 120 */ 121 122 long offset5 = tz.getOffset(1, 123 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)); 124 long offset6 = tz.getOffset(1, 125 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)-1); 126 127 long offset7 = tz.getOffset(1, 128 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)); 129 long offset8 = tz.getOffset(1, 130 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)-1); 131 132 long SToffset = -8 * 60*60*1000L; 133 long DToffset = -7 * 60*60*1000L; 134 if (offset1 != SToffset || offset2 != SToffset || 135 offset3 != SToffset || offset4 != DToffset || 136 offset5 != DToffset || offset6 != SToffset || 137 offset7 != SToffset || offset8 != SToffset) 138 warnln("Fail: TimeZone misbehaving"); 139 } 140 141 @Test 142 public void Test4096952() { 143 String[] ZONES = { "GMT", "MET", "IST" }; 144 boolean pass = true; 145 try { 146 for (int i=0; i<ZONES.length; ++i) { 147 TimeZone zone = TimeZone.getTimeZone(ZONES[i]); 148 if (!zone.getID().equals(ZONES[i])) 149 warnln("Fail: Test broken; zones not instantiating"); 150 151 ByteArrayOutputStream baos; 152 ObjectOutputStream ostream = 153 new ObjectOutputStream(baos = new 154 ByteArrayOutputStream()); 155 ostream.writeObject(zone); 156 ostream.close(); 157 baos.close(); 158 ObjectInputStream istream = 159 new ObjectInputStream(new 160 ByteArrayInputStream(baos.toByteArray())); 161 TimeZone frankenZone = (TimeZone) istream.readObject(); 162 //logln("Zone: " + zone); 163 //logln("FrankenZone: " + frankenZone); 164 if (!zone.equals(frankenZone)) { 165 logln("TimeZone " + zone.getID() + 166 " not equal to serialized/deserialized one"); 167 pass = false; 168 } 169 } 170 if (!pass) errln("Fail: TimeZone serialization/equality bug"); 171 } 172 catch (IOException e) { 173 errln("Fail: " + e); 174 e.printStackTrace(); 175 } 176 catch (ClassNotFoundException e) { 177 errln("Fail: " + e); 178 e.printStackTrace(); 179 } 180 } 181 182 @Test 183 public void Test4109314() { 184 GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance(); 185 TimeZone PST = TimeZone.getTimeZone("PST"); 186 java.util.Calendar tempcal = java.util.Calendar.getInstance(); 187 tempcal.clear(); 188 tempcal.set(1998,Calendar.APRIL,4,22,0); 189 Date d1 = tempcal.getTime(); 190 tempcal.set(1998,Calendar.APRIL,5,6,0); 191 Date d2 = tempcal.getTime(); 192 tempcal.set(1998,Calendar.OCTOBER,24,22,0); 193 Date d3 = tempcal.getTime(); 194 tempcal.set(1998,Calendar.OCTOBER,25,6,0); 195 Date d4 = tempcal.getTime(); 196 Object[] testData = { 197 PST, d1, d2, 198 PST, d3, d4, 199 }; 200 boolean pass=true; 201 for (int i=0; i<testData.length; i+=3) { 202 testCal.setTimeZone((TimeZone) testData[i]); 203 long t = ((Date)testData[i+1]).getTime(); 204 Date end = (Date) testData[i+2]; 205 while (t < end.getTime()) { 206 testCal.setTime(new Date(t)); 207 if (!checkCalendar314(testCal, (TimeZone) testData[i])) 208 pass = false; 209 t += 60*60*1000L; 210 } 211 } 212 if (!pass) errln("Fail: TZ API inconsistent"); 213 } 214 215 boolean checkCalendar314(GregorianCalendar testCal, TimeZone testTZ) { 216 // GregorianCalendar testCal = (GregorianCalendar)aCal.clone(); 217 218 final int ONE_DAY = 24*60*60*1000; 219 220 int tzOffset, tzRawOffset; 221 Float tzOffsetFloat,tzRawOffsetFloat; 222 // Here is where the user made an error. They were passing in the value of 223 // the MILLSECOND field; you need to pass in the millis in the day in STANDARD 224 // time. 225 int millis = testCal.get(Calendar.MILLISECOND) + 226 1000 * (testCal.get(Calendar.SECOND) + 227 60 * (testCal.get(Calendar.MINUTE) + 228 60 * (testCal.get(Calendar.HOUR_OF_DAY)))) - 229 testCal.get(Calendar.DST_OFFSET); 230 231 /* Fix up millis to be in range. ASSUME THAT WE ARE NOT AT THE 232 * BEGINNING OR END OF A MONTH. We must add this code because 233 * getOffset() has been changed to be more strict about the parameters 234 * it receives -- it turns out that this test was passing in illegal 235 * values. */ 236 int date = testCal.get(Calendar.DATE); 237 int dow = testCal.get(Calendar.DAY_OF_WEEK); 238 while (millis < 0) { 239 millis += ONE_DAY; 240 --date; 241 dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 6) % 7); 242 } 243 while (millis >= ONE_DAY) { 244 millis -= ONE_DAY; 245 ++date; 246 dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 1) % 7); 247 } 248 249 tzOffset = testTZ.getOffset(testCal.get(Calendar.ERA), 250 testCal.get(Calendar.YEAR), 251 testCal.get(Calendar.MONTH), 252 date, 253 dow, 254 millis); 255 tzRawOffset = testTZ.getRawOffset(); 256 tzOffsetFloat = new Float((float)tzOffset/(float)3600000); 257 tzRawOffsetFloat = new Float((float)tzRawOffset/(float)3600000); 258 259 Date testDate = testCal.getTime(); 260 261 boolean inDaylightTime = testTZ.inDaylightTime(testDate); 262 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm"); 263 sdf.setCalendar(testCal); 264 String inDaylightTimeString; 265 266 boolean passed; 267 268 if (inDaylightTime) 269 { 270 inDaylightTimeString = " DST "; 271 passed = (tzOffset == (tzRawOffset + 3600000)); 272 } 273 else 274 { 275 inDaylightTimeString = " "; 276 passed = (tzOffset == tzRawOffset); 277 } 278 279 String output = testTZ.getID() + " " + sdf.format(testDate) + 280 " Offset(" + tzOffsetFloat + ")" + 281 " RawOffset(" + tzRawOffsetFloat + ")" + 282 " " + millis/(float)3600000 + " " + 283 inDaylightTimeString; 284 285 if (passed) 286 output += " "; 287 else 288 output += "ERROR"; 289 290 if (passed) logln(output); else errln(output); 291 return passed; 292 } 293 294 /** 295 * CANNOT REPRODUDE 296 * 297 * Yet another _alleged_ bug in TimeZone.getOffset(), a method that never 298 * should have been made public. It's simply too hard to use correctly. 299 * 300 * The original test code failed to do the following: 301 * (1) Call Calendar.setTime() before getting the fields! 302 * (2) Use the right millis (as usual) for getOffset(); they were passing 303 * in the MILLIS field, instead of the STANDARD MILLIS IN DAY. 304 * When you fix these two problems, the test passes, as expected. 305 */ 306 @Test 307 public void Test4126678() { 308 // Note: this test depends on the PST time zone. 309 TimeZone initialZone = TimeZone.getDefault(); 310 Calendar cal = Calendar.getInstance(); 311 TimeZone tz = TimeZone.getTimeZone("PST"); 312 TimeZone.setDefault(tz); 313 cal.setTimeZone(tz); 314 315 java.util.Calendar tempcal = java.util.Calendar.getInstance(); 316 tempcal.clear(); 317 tempcal.set(1998, Calendar.APRIL, 5, 10, 0); 318 Date dt = tempcal.getTime(); 319 // the dt value is local time in PST. 320 if (!tz.inDaylightTime(dt)) 321 errln("We're not in Daylight Savings Time and we should be.\n"); 322 323 cal.setTime(dt); 324 int era = cal.get(Calendar.ERA); 325 int year = cal.get(Calendar.YEAR); 326 int month = cal.get(Calendar.MONTH); 327 int day = cal.get(Calendar.DATE); 328 int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); 329 int millis = cal.get(Calendar.MILLISECOND) + 330 (cal.get(Calendar.SECOND) + 331 (cal.get(Calendar.MINUTE) + 332 (cal.get(Calendar.HOUR) * 60) * 60) * 1000) - 333 cal.get(Calendar.DST_OFFSET); 334 335 long offset = tz.getOffset(era, year, month, day, dayOfWeek, millis); 336 long raw_offset = tz.getRawOffset(); 337 if (offset == raw_offset) 338 errln("Offsets should not match when in DST"); 339 340 // restore the initial time zone so that this test case 341 // doesn't affect the others. 342 TimeZone.setDefault(initialZone); 343 } 344 345 /** 346 * TimeZone.getAvailableIDs(int) throws exception for certain values, 347 * due to a faulty constant in TimeZone.java. 348 */ 349 @Test 350 public void Test4151406() { 351 int max = 0; 352 for (int h=-28; h<=30; ++h) { 353 // h is in half-hours from GMT; rawoffset is in millis 354 int rawoffset = h * 1800000; 355 int hh = (h<0) ? -h : h; 356 String hname = ((h<0) ? "GMT-" : "GMT+") + 357 ((hh/2 < 10) ? "0" : "") + 358 (hh/2) + ':' + 359 ((hh%2==0) ? "00" : "30"); 360 try { 361 String[] ids = TimeZone.getAvailableIDs(rawoffset); 362 if (ids.length > max) max = ids.length; 363 logln(hname + ' ' + ids.length + 364 ((ids.length > 0) ? (" e.g. " + ids[0]) : "")); 365 } catch (Exception e) { 366 errln(hname + ' ' + "Fail: " + e); 367 } 368 } 369 logln("Maximum zones per offset = " + max); 370 } 371 372 @Test 373 public void Test4151429() { 374 try { 375 TimeZone tz = TimeZone.getTimeZone("GMT"); 376 /*String name =*/ tz.getDisplayName(true, Integer.MAX_VALUE, 377 Locale.getDefault()); 378 errln("IllegalArgumentException not thrown by TimeZone.getDisplayName()"); 379 } catch(IllegalArgumentException e) { 380 System.out.print(""); 381 } 382 } 383 384 /** 385 * SimpleTimeZone accepts illegal DST savings values. These values 386 * must be non-zero. There is no upper limit at this time. 387 */ 388 @Test 389 public void Test4154525() { 390 final int GOOD = 1, BAD = 0; 391 int[] DATA = { 392 1, GOOD, 393 0, BAD, 394 -1, BAD, 395 60*60*1000, GOOD, 396 Integer.MIN_VALUE, BAD, 397 // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time 398 }; 399 for (int i=0; i<DATA.length; i+=2) { 400 int savings = DATA[i]; 401 boolean valid = DATA[i+1] == GOOD; 402 String method = null; 403 for (int j=0; j<2; ++j) { 404 try { 405 switch (j) { 406 case 0: 407 method = "constructor"; 408 SimpleTimeZone z = new SimpleTimeZone(0, "id", 409 Calendar.JANUARY, 1, 0, 0, 410 Calendar.MARCH, 1, 0, 0, 411 savings); // <- what we're interested in 412 break; 413 case 1: 414 method = "setDSTSavings()"; 415 z = new SimpleTimeZone(0, "GMT"); 416 z.setDSTSavings(savings); 417 break; 418 } 419 if (valid) { 420 logln("Pass: DST savings of " + savings + " accepted by " + method); 421 } else { 422 errln("Fail: DST savings of " + savings + " accepted by " + method); 423 } 424 } catch (IllegalArgumentException e) { 425 if (valid) { 426 errln("Fail: DST savings of " + savings + " to " + method + " gave " + e); 427 } else { 428 logln("Pass: DST savings of " + savings + " to " + method + " gave " + e); 429 } 430 } 431 } 432 } 433 } 434 435 /** 436 * SimpleTimeZone.hasSameRules() doesn't work for zones with no DST 437 * and different DST parameters. 438 */ 439 @Test 440 public void Test4154537() { 441 // tz1 and tz2 have no DST and different rule parameters 442 SimpleTimeZone tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0); 443 SimpleTimeZone tz2 = new SimpleTimeZone(0, "2", 1, 0, 0, 0, 3, 0, 0, 0); 444 // tza and tzA have the same rule params 445 SimpleTimeZone tza = new SimpleTimeZone(0, "a", 0, 1, 0, 0, 3, 2, 0, 0); 446 SimpleTimeZone tzA = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 3, 2, 0, 0); 447 // tzb differs from tza 448 SimpleTimeZone tzb = new SimpleTimeZone(0, "b", 0, 1, 0, 0, 3, 1, 0, 0); 449 if (tz1.useDaylightTime() || tz2.useDaylightTime() || 450 !tza.useDaylightTime() || !tzA.useDaylightTime() || 451 !tzb.useDaylightTime()) { 452 errln("Test is broken -- rewrite it"); 453 } 454 if (!tza.hasSameRules(tzA) || tza.hasSameRules(tzb)) { 455 errln("Fail: hasSameRules() broken for zones with rules"); 456 } 457 if (!tz1.hasSameRules(tz2)) { 458 errln("Fail: hasSameRules() returns false for zones without rules"); 459 errln("zone 1 = " + tz1); 460 errln("zone 2 = " + tz2); 461 } 462 } 463 464 /** 465 * SimpleTimeZone constructors, setStartRule(), and setEndRule() don't 466 * check for out-of-range arguments. 467 */ 468 @Test 469 public void Test4154542() { 470 final int GOOD = 1; 471 final int BAD = 0; 472 473 final int GOOD_MONTH = Calendar.JANUARY; 474 final int GOOD_DAY = 1; 475 final int GOOD_DAY_OF_WEEK = Calendar.SUNDAY; 476 final int GOOD_TIME = 0; 477 478 int[] DATA = { 479 GOOD, Integer.MIN_VALUE, 0, Integer.MAX_VALUE, Integer.MIN_VALUE, 480 GOOD, Calendar.JANUARY, -5, Calendar.SUNDAY, 0, 481 GOOD, Calendar.DECEMBER, 5, Calendar.SATURDAY, 24*60*60*1000-1, 482 BAD, Calendar.DECEMBER, 5, Calendar.SATURDAY, 24*60*60*1000+1, 483 BAD, Calendar.DECEMBER, 5, Calendar.SATURDAY, -1, 484 BAD, Calendar.JANUARY, -6, Calendar.SUNDAY, 0, 485 BAD, Calendar.DECEMBER, 6, Calendar.SATURDAY, 24*60*60*1000, 486 GOOD, Calendar.DECEMBER, 1, 0, 0, 487 GOOD, Calendar.DECEMBER, 31, 0, 0, 488 BAD, Calendar.APRIL, 31, 0, 0, 489 BAD, Calendar.DECEMBER, 32, 0, 0, 490 BAD, Calendar.JANUARY-1, 1, Calendar.SUNDAY, 0, 491 BAD, Calendar.DECEMBER+1, 1, Calendar.SUNDAY, 0, 492 GOOD, Calendar.DECEMBER, 31, -Calendar.SUNDAY, 0, 493 GOOD, Calendar.DECEMBER, 31, -Calendar.SATURDAY, 0, 494 BAD, Calendar.DECEMBER, 32, -Calendar.SATURDAY, 0, 495 BAD, Calendar.DECEMBER, -32, -Calendar.SATURDAY, 0, 496 BAD, Calendar.DECEMBER, 31, -Calendar.SATURDAY-1, 0, 497 }; 498 SimpleTimeZone zone = new SimpleTimeZone(0, "Z"); 499 for (int i=0; i<DATA.length; i+=5) { 500 boolean shouldBeGood = (DATA[i] == GOOD); 501 int month = DATA[i+1]; 502 int day = DATA[i+2]; 503 int dayOfWeek = DATA[i+3]; 504 int time = DATA[i+4]; 505 506 Exception ex = null; 507 try { 508 zone.setStartRule(month, day, dayOfWeek, time); 509 } catch (IllegalArgumentException e) { 510 ex = e; 511 } 512 if ((ex == null) != shouldBeGood) { 513 errln("setStartRule(month=" + month + ", day=" + day + 514 ", dayOfWeek=" + dayOfWeek + ", time=" + time + 515 (shouldBeGood ? (") should work but throws " + ex) 516 : ") should fail but doesn't")); 517 } 518 519 ex = null; 520 try { 521 zone.setEndRule(month, day, dayOfWeek, time); 522 } catch (IllegalArgumentException e) { 523 ex = e; 524 } 525 if ((ex == null) != shouldBeGood) { 526 errln("setEndRule(month=" + month + ", day=" + day + 527 ", dayOfWeek=" + dayOfWeek + ", time=" + time + 528 (shouldBeGood ? (") should work but throws " + ex) 529 : ") should fail but doesn't")); 530 } 531 532 ex = null; 533 try { 534 /*SimpleTimeZone temp =*/ new SimpleTimeZone(0, "Z", 535 month, day, dayOfWeek, time, 536 GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME); 537 } catch (IllegalArgumentException e) { 538 ex = e; 539 } 540 if ((ex == null) != shouldBeGood) { 541 errln("SimpleTimeZone(month=" + month + ", day=" + day + 542 ", dayOfWeek=" + dayOfWeek + ", time=" + time + 543 (shouldBeGood ? (", <end>) should work but throws " + ex) 544 : ", <end>) should fail but doesn't")); 545 } 546 547 ex = null; 548 try { 549 /*SimpleTimeZone temp = */new SimpleTimeZone(0, "Z", 550 GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME, 551 month, day, dayOfWeek, time); 552 // temp = null; 553 } catch (IllegalArgumentException e) { 554 ex = e; 555 } 556 if ((ex == null) != shouldBeGood) { 557 errln("SimpleTimeZone(<start>, month=" + month + ", day=" + day + 558 ", dayOfWeek=" + dayOfWeek + ", time=" + time + 559 (shouldBeGood ? (") should work but throws " + ex) 560 : ") should fail but doesn't")); 561 } 562 } 563 } 564 565 /** 566 * SimpleTimeZone.getOffset accepts illegal arguments. 567 */ 568 @Test 569 public void Test4154650() { 570 final int GOOD=1, BAD=0; 571 final int GOOD_ERA=GregorianCalendar.AD, GOOD_YEAR=1998, GOOD_MONTH=Calendar.AUGUST; 572 final int GOOD_DAY=2, GOOD_DOW=Calendar.SUNDAY, GOOD_TIME=16*3600000; 573 int[] DATA = { 574 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, 575 576 GOOD, GregorianCalendar.BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, 577 GOOD, GregorianCalendar.AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, 578 BAD, GregorianCalendar.BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, 579 BAD, GregorianCalendar.AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, 580 581 GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME, 582 GOOD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME, 583 BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME, 584 BAD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIME, 585 586 GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 1, GOOD_DOW, GOOD_TIME, 587 GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 31, GOOD_DOW, GOOD_TIME, 588 BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 0, GOOD_DOW, GOOD_TIME, 589 BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 32, GOOD_DOW, GOOD_TIME, 590 591 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY, GOOD_TIME, 592 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY, GOOD_TIME, 593 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY-1, GOOD_TIME, 594 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY+1, GOOD_TIME, 595 596 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0, 597 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1, 598 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1, 599 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000, 600 }; 601 602 TimeZone tz = TimeZone.getDefault(); 603 for (int i=0; i<DATA.length; i+=7) { 604 boolean good = DATA[i] == GOOD; 605 IllegalArgumentException e = null; 606 try { 607 /*int offset =*/ tz.getOffset(DATA[i+1], DATA[i+2], DATA[i+3], 608 DATA[i+4], DATA[i+5], DATA[i+6]); 609 //offset = 0; 610 } catch (IllegalArgumentException ex) { 611 e = ex; 612 } 613 if (good != (e == null)) { 614 errln("Fail: getOffset(" + 615 DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " + 616 DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] + 617 (good ? (") threw " + e) : ") accepts invalid args")); 618 } 619 } 620 } 621 622 /** 623 * TimeZone constructors allow null IDs. 624 */ 625 @Test 626 public void Test4159922() { 627 TimeZone z = null; 628 629 // TimeZone API. Only hasSameRules() and setDefault() should 630 // allow null. 631 try { 632 z = TimeZone.getTimeZone(null); 633 errln("FAIL: Null allowed in getTimeZone"); 634 } catch (NullPointerException e) { 635 System.out.print(""); 636 } 637 z = TimeZone.getTimeZone("GMT"); 638 try { 639 // {dlf} requiring cast for disambiguation is ok for compatibility since null 640 // is not a valid argument to this API 641 z.getDisplayName(false, TimeZone.SHORT, (ULocale)null); 642 errln("FAIL: Null allowed in getDisplayName(3)"); 643 } catch (NullPointerException e) { 644 System.out.print(""); 645 } 646 try { 647 // {dlf} see above 648 z.getDisplayName((ULocale)null); 649 errln("FAIL: Null allowed in getDisplayName(1)"); 650 } catch (NullPointerException e) { 651 System.out.print(""); 652 } 653 try { 654 if (z.hasSameRules(null)) { 655 errln("FAIL: hasSameRules returned true"); 656 } 657 } catch (NullPointerException e) { 658 errln("FAIL: Null NOT allowed in hasSameRules"); 659 } 660 try { 661 z.inDaylightTime(null); 662 errln("FAIL: Null allowed in inDaylightTime"); 663 } catch (NullPointerException e) { 664 System.out.print(""); 665 } 666 try { 667 z.setID(null); 668 errln("FAIL: Null allowed in setID"); 669 } catch (NullPointerException e) { 670 System.out.print(""); 671 } 672 673 TimeZone save = TimeZone.getDefault(); 674 try { 675 TimeZone.setDefault(null); 676 } catch (NullPointerException e) { 677 errln("FAIL: Null NOT allowed in setDefault"); 678 } finally { 679 TimeZone.setDefault(save); 680 } 681 682 // SimpleTimeZone API 683 SimpleTimeZone s = null; 684 try { 685 s = new SimpleTimeZone(0, null); 686 errln("FAIL: Null allowed in SimpleTimeZone(2)"); 687 } catch (NullPointerException e) { 688 System.out.print(""); 689 } 690 try { 691 s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0); 692 errln("FAIL: Null allowed in SimpleTimeZone(10)"); 693 } catch (NullPointerException e) { 694 System.out.print(""); 695 } 696 try { 697 s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0, 1000); 698 errln("FAIL: Null allowed in SimpleTimeZone(11)"); 699 } catch (NullPointerException e) { 700 System.out.print(""); 701 } 702 if(s!=null){ 703 errln("FAIL: Did not get the expected Exception"); 704 } 705 } 706 707 /** 708 * TimeZone broken at midnight. The TimeZone code fails to handle 709 * transitions at midnight correctly. 710 */ 711 @Test 712 public void Test4162593() { 713 SimpleDateFormat fmt = new SimpleDateFormat("z", Locale.US); 714 final int ONE_HOUR = 60*60*1000; 715 final float H = (float) ONE_HOUR; 716 TimeZone initialZone = TimeZone.getDefault(); 717 SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm z"); 718 719 SimpleTimeZone asuncion = new SimpleTimeZone(-4*ONE_HOUR, "America/Asuncion" /*PY%sT*/, 720 Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, 721 Calendar.MARCH, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR); 722 723 /* Zone 724 * Starting time 725 * Transition expected between start+1H and start+2H 726 */ 727 Object[] DATA = { 728 new SimpleTimeZone(2*ONE_HOUR, "Asia/Damascus" /*EE%sT*/, 729 Calendar.APRIL, 1, 0 /*DOM*/, 0*ONE_HOUR, 730 Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR), 731 new int[] {1998, Calendar.SEPTEMBER, 30, 22, 0}, 732 Boolean.TRUE, 733 734 asuncion, 735 new int[] {2000, Calendar.FEBRUARY, 28, 22, 0}, 736 Boolean.FALSE, 737 738 asuncion, 739 new int[] {2000, Calendar.FEBRUARY, 29, 22, 0}, 740 Boolean.TRUE, 741 }; 742 743 String[] zone = new String[4]; 744 745 for (int j=0; j<DATA.length; j+=3) { 746 TimeZone tz = (TimeZone)DATA[j]; 747 TimeZone.setDefault(tz); 748 fmt.setTimeZone(tz); 749 sdf.setTimeZone(tz); 750 751 // Must construct the Date object AFTER setting the default zone 752 int[] p = (int[])DATA[j+1]; 753 Calendar cal = Calendar.getInstance(); 754 cal.clear(); 755 cal.set(p[0], p[1], p[2], p[3], p[4]); 756 long start = cal.getTime().getTime(); 757 boolean transitionExpected = ((Boolean)DATA[j+2]).booleanValue(); 758 759 logln(tz.getID() + ":"); 760 for (int i=0; i<4; ++i) { 761 Date d = new Date(start + i*ONE_HOUR); 762 zone[i] = fmt.format(d); 763 logln("" + i + ": " + sdf.format(d) + " => " + zone[i] + 764 " (" + d.getTime()/H + ")"); 765 } 766 cal.set(p[0], p[1], p[2], 0, 0); 767 for (int i=0; i<4; ++i) { 768 int h = 22+i; 769 int dom = p[2]+(h>=24?1:0); 770 h %= 24; 771 int ms = h*ONE_HOUR; 772 cal.clear(); 773 cal.set(p[0], p[1], dom, 0, 0); 774 int off = tz.getOffset(GregorianCalendar.AD, 775 cal.get(Calendar.YEAR), 776 cal.get(Calendar.MONTH), 777 cal.get(Calendar.DATE), 778 cal.get(Calendar.DAY_OF_WEEK), 779 ms); 780 cal.add(Calendar.HOUR, h); 781 int dstOffset = cal.get(Calendar.DST_OFFSET); 782 logln("h=" + h + "; dom=" + dom + 783 "; ZONE_OFFSET=" + cal.get(Calendar.ZONE_OFFSET)/H + 784 "; DST_OFFSET=" + dstOffset/H + 785 "; getOffset()=" + off/H + 786 " (" + cal.getTime().getTime()/H + ")"); 787 } 788 if (zone[0].equals(zone[1]) && 789 (zone[1].equals(zone[2]) != transitionExpected) && 790 zone[2].equals(zone[3])) { 791 logln("Ok: transition " + transitionExpected); 792 } else { 793 errln("FAIL: expected " + 794 (transitionExpected?"transition":"no transition")); 795 } 796 } 797 798 // restore the initial time zone so that this test case 799 // doesn't affect the others. 800 TimeZone.setDefault(initialZone); 801 } 802 803 /** 804 * TimeZone broken in last hour of year 805 */ 806 @Test 807 public void Test4173604() { 808 TimeZone pst = TimeZone.getTimeZone("PST"); 809 int o22 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 22*60*60*1000); 810 int o23 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 23*60*60*1000); 811 int o00 = pst.getOffset(1, 1999, 0, 1, Calendar.FRIDAY, 0); 812 if (o22 != o23 || o22 != o00) { 813 errln("Offsets should be the same (for PST), but got: " + 814 "12/31 22:00 " + o22 + 815 ", 12/31 23:00 " + o23 + 816 ", 01/01 00:00 " + o00); 817 } 818 819 GregorianCalendar cal = new GregorianCalendar(); 820 cal.setTimeZone(pst); 821 cal.clear(); 822 cal.set(1998, Calendar.JANUARY, 1); 823 int lastDST = cal.get(Calendar.DST_OFFSET); 824 int transitions = 0; 825 int delta = 5; 826 while (cal.get(Calendar.YEAR) < 2000) { 827 cal.add(Calendar.MINUTE, delta); 828 if (cal.get(Calendar.DST_OFFSET) != lastDST) { 829 ++transitions; 830 Calendar t = (Calendar)cal.clone(); 831 t.add(Calendar.MINUTE, -delta); 832 logln(t.getTime() + " " + t.get(Calendar.DST_OFFSET)); 833 logln(cal.getTime() + " " + (lastDST=cal.get(Calendar.DST_OFFSET))); 834 } 835 } 836 if (transitions != 4) { 837 errln("Saw " + transitions + " transitions; should have seen 4"); 838 } 839 } 840 841 /** 842 * getDisplayName doesn't work with unusual savings/offsets. 843 */ 844 @Test 845 public void Test4176686() { 846 // Construct a zone that does not observe DST but 847 // that does have a DST savings (which should be ignored). 848 int offset = 90 * 60000; // 1:30 849 SimpleTimeZone z1 = new SimpleTimeZone(offset, "_std_zone_"); 850 z1.setDSTSavings(45 * 60000); // 0:45 851 852 // Construct a zone that observes DST for the first 6 months. 853 SimpleTimeZone z2 = new SimpleTimeZone(offset, "_dst_zone_"); 854 z2.setDSTSavings(45 * 60000); // 0:45 855 z2.setStartRule(Calendar.JANUARY, 1, 0); 856 z2.setEndRule(Calendar.JULY, 1, 0); 857 858 // Also check DateFormat 859 DateFormat fmt1 = new SimpleDateFormat("z"); 860 fmt1.setTimeZone(z1); // Format uses standard zone 861 DateFormat fmt2 = new SimpleDateFormat("z"); 862 fmt2.setTimeZone(z2); // Format uses DST zone 863 java.util.Calendar tempcal = java.util.Calendar.getInstance(); 864 tempcal.clear(); 865 tempcal.set(1970, Calendar.FEBRUARY, 1); 866 Date dst = tempcal.getTime(); // Time in DST 867 tempcal.set(1970, Calendar.AUGUST, 1); 868 Date std = tempcal.getTime(); // Time in standard 869 870 // Description, Result, Expected Result 871 String[] DATA = { 872 "getDisplayName(false, SHORT)/std zone", 873 z1.getDisplayName(false, TimeZone.SHORT), "GMT+1:30", 874 "getDisplayName(false, LONG)/std zone", 875 z1.getDisplayName(false, TimeZone.LONG ), "GMT+01:30", 876 "getDisplayName(true, SHORT)/std zone", 877 z1.getDisplayName(true, TimeZone.SHORT), "GMT+1:30", 878 "getDisplayName(true, LONG)/std zone", 879 z1.getDisplayName(true, TimeZone.LONG ), "GMT+01:30", 880 "getDisplayName(false, SHORT)/dst zone", 881 z2.getDisplayName(false, TimeZone.SHORT), "GMT+1:30", 882 "getDisplayName(false, LONG)/dst zone", 883 z2.getDisplayName(false, TimeZone.LONG ), "GMT+01:30", 884 "getDisplayName(true, SHORT)/dst zone", 885 z2.getDisplayName(true, TimeZone.SHORT), "GMT+2:15", 886 "getDisplayName(true, LONG)/dst zone", 887 z2.getDisplayName(true, TimeZone.LONG ), "GMT+02:15", 888 "DateFormat.format(std)/std zone", fmt1.format(std), "GMT+1:30", 889 "DateFormat.format(dst)/std zone", fmt1.format(dst), "GMT+1:30", 890 "DateFormat.format(std)/dst zone", fmt2.format(std), "GMT+1:30", 891 "DateFormat.format(dst)/dst zone", fmt2.format(dst), "GMT+2:15", 892 }; 893 894 for (int i=0; i<DATA.length; i+=3) { 895 if (!DATA[i+1].equals(DATA[i+2])) { 896 errln("FAIL: " + DATA[i] + " -> " + DATA[i+1] + ", exp " + DATA[i+2]); 897 } 898 } 899 } 900 901 /** 902 * SimpleTimeZone allows invalid DOM values. 903 */ 904 // Current orgnaization of data in zoneinfor.res allows negative 905 // values from DOM so comment these tests out 906 907 @Test 908 public void Test4184229() { 909 SimpleTimeZone zone = null; 910 try { 911 zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0); 912 errln("Failed. No exception has been thrown for DOM -1 startDay"); 913 } catch(IllegalArgumentException e) { 914 logln("(a) " + e.getMessage()); 915 } 916 try { 917 zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0); 918 errln("Failed. No exception has been thrown for DOM -1 endDay"); 919 } catch(IllegalArgumentException e) { 920 logln("(b) " + e.getMessage()); 921 } 922 try { 923 zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, 1000); 924 errln("Failed. No exception has been thrown for DOM -1 startDay +savings"); 925 } catch(IllegalArgumentException e) { 926 logln("(c) " + e.getMessage()); 927 } 928 try { 929 zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000); 930 errln("Failed. No exception has been thrown for DOM -1 endDay +savings"); 931 } catch(IllegalArgumentException e) { 932 logln("(d) " + e.getMessage()); 933 } 934 // Make a valid constructor call for subsequent tests. 935 936 zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0); 937 938 try { 939 zone.setStartRule(0, -1, 0, 0); 940 errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings"); 941 } catch(IllegalArgumentException e) { 942 logln("(e) " + e.getMessage()); 943 } 944 try { 945 zone.setStartRule(0, -1, 0); 946 errln("Failed. No exception has been thrown for DOM -1 setStartRule"); 947 } catch(IllegalArgumentException e) { 948 logln("(f) " + e.getMessage()); 949 } 950 try { 951 zone.setEndRule(0, -1, 0, 0); 952 errln("Failed. No exception has been thrown for DOM -1 setEndRule +savings"); 953 } catch(IllegalArgumentException e) { 954 logln("(g) " + e.getMessage()); 955 } 956 try { 957 zone.setEndRule(0, -1, 0); 958 errln("Failed. No exception has been thrown for DOM -1 setEndRule"); 959 } catch(IllegalArgumentException e) { 960 logln("(h) " + e.getMessage()); 961 } 962 963 } 964 965 /** 966 * SimpleTimeZone.getOffset() throws IllegalArgumentException when to get 967 * of 2/29/1996 (leap day). 968 */ 969 @Test 970 public void Test4208960 () { 971 TimeZone tz = TimeZone.getTimeZone("PST"); 972 try { 973 /*int offset =*/ tz.getOffset(GregorianCalendar.AD, 1996, Calendar.FEBRUARY, 29, 974 Calendar.THURSDAY, 0); 975 //offset = 0; 976 } catch (IllegalArgumentException e) { 977 errln("FAILED: to get TimeZone.getOffset(2/29/96)"); 978 } 979 try { 980 /*int offset =*/ tz.getOffset(GregorianCalendar.AD, 1997, Calendar.FEBRUARY, 29, 981 Calendar.THURSDAY, 0); 982 //offset = 0; 983 warnln("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception."); 984 } catch (IllegalArgumentException e) { 985 logln("got IllegalArgumentException"); 986 } 987 } 988 989 /** 990 * Test to see if DateFormat understands zone equivalency groups. It 991 * might seem that this should be a DateFormat test, but it's really a 992 * TimeZone test -- the changes to DateFormat are minor. 993 * 994 * We use two known, zones that are equivalent, where one zone has 995 * localized name data, and the other doesn't, in some locale. 996 */ 997 @Test 998 public void TestJ449() { 999 // not used String str; 1000 1001 // Modify the following three as necessary. The two IDs must 1002 // specify two zones in the same equivalency group. One must have 1003 // locale data in 'loc'; the other must not. 1004 String idWithLocaleData = "America/Los_Angeles"; 1005 String idWithoutLocaleData = "PST"; // "US/Pacific"; 1006 Locale loc = new Locale("en", "", ""); 1007 1008 TimeZone zoneWith = TimeZone.getTimeZone(idWithLocaleData); 1009 TimeZone zoneWithout = TimeZone.getTimeZone(idWithoutLocaleData); 1010 // Make sure we got valid zones 1011 if (!(zoneWith.getID().equals(idWithLocaleData) && 1012 zoneWithout.getID().equals(idWithoutLocaleData))) { 1013 warnln("Fail: Unable to create zones"); 1014 } else { 1015 GregorianCalendar calWith = new GregorianCalendar(zoneWith); 1016 GregorianCalendar calWithout = new GregorianCalendar(zoneWithout); 1017 SimpleDateFormat fmt = 1018 new SimpleDateFormat("MMM d yyyy hh:mm a zzz", loc); 1019 Date date = new Date(0L); 1020 fmt.setCalendar(calWith); 1021 String strWith = fmt.format(date); 1022 fmt.setCalendar(calWithout); 1023 String strWithout = fmt.format(date); 1024 if (strWith.equals(strWithout)) { 1025 logln("Ok: " + idWithLocaleData + " -> " + 1026 strWith + "; " + idWithoutLocaleData + " -> " + 1027 strWithout); 1028 } else { 1029 errln("FAIL: " + idWithLocaleData + " -> " + 1030 strWith + "; " + idWithoutLocaleData + " -> " + 1031 strWithout); 1032 } 1033 } 1034 } 1035 1036 /** 1037 * getOffset returns wrong offset for days in early 20th century 1038 */ 1039 @Test 1040 public void TestJ5134() { 1041 GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance(); 1042 TimeZone icuEastern = TimeZone.getTimeZone("America/New_York"); 1043 testCal.setTimeZone(icuEastern); 1044 testCal.set(1900, Calendar.JANUARY, 1, 0, 0, 0); 1045 long time = testCal.getTimeInMillis(); 1046 1047 int offset = icuEastern.getOffset(time); 1048 if (offset != -18000000) { 1049 errln("FAIL: UTC offset in time zone America/New_York on Jan 1, 1900 -> " + offset); 1050 } 1051 boolean isDst = icuEastern.inDaylightTime(new Date(time)); 1052 if (isDst) { 1053 errln("FAIL: DST is observed in time zone America/New_York on Jan 1, 1900"); 1054 } 1055 1056 if (System.getProperty("java.vendor", "").startsWith("IBM") && 1057 System.getProperty("java.version", "").equals("1.4.1")) { 1058 // IBM JDK 1.4.1 has a bug and fails to run this test case. 1059 return; 1060 } 1061 java.util.TimeZone jdkEastern = java.util.TimeZone.getTimeZone("America/New_York"); 1062 // Compare offset and DST observation with JDK and ICU for 50 years since 1900 1063 testCal.add(Calendar.YEAR, 50); 1064 long endTime = testCal.getTimeInMillis(); 1065 int jdkOffset; 1066 boolean isDstJdk; 1067 while (time < endTime) { 1068 offset = icuEastern.getOffset(time); 1069 jdkOffset = jdkEastern.getOffset(time); 1070 if (offset != jdkOffset) { 1071 errln("FAIL: Incompatible UTC offset -> JDK:" + jdkOffset + "/ICU:" + offset + " [" + time + "]"); 1072 } 1073 Date d = new Date(time); 1074 isDst = icuEastern.inDaylightTime(d); 1075 isDstJdk = jdkEastern.inDaylightTime(d); 1076 if (isDst != isDstJdk) { 1077 errln("FAIL: Incompatible DST -> JDK:" + isDstJdk + "/ICU:" + isDst + " [" + time + "]"); 1078 } 1079 time += 24*60*60*1000L; // increment 1 day 1080 } 1081 } 1082 1083 /** 1084 * Test setRawOffset works OK with system timezone 1085 */ 1086 @Test 1087 public void TestT5280() { 1088 boolean isJdkZone = (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_JDK); 1089 String[] tzids = TimeZone.getAvailableIDs(); 1090 for (int i = 0; i < tzids.length; i++) { 1091 TimeZone tz = TimeZone.getTimeZone(tzids[i]); 1092 boolean useDst = tz.useDaylightTime(); 1093 1094 // Increase offset for 30 minutes 1095 int newRawOffset = tz.getRawOffset() + 30*60*1000; 1096 try { 1097 tz.setRawOffset(newRawOffset); 1098 } catch (Exception e) { 1099 errln("FAIL: setRawOffset throws an exception"); 1100 } 1101 int offset = tz.getRawOffset(); 1102 if (offset != newRawOffset) { 1103 if (isJdkZone) { 1104 // JDK TimeZone#setRawOffset() only update the last rule, and getRawOffset() returns 1105 // the current raw offset. Therefore, they might be different. 1106 logln("Modified zone(" + tz.getID() + ") - getRawOffset returns " + offset + "/ Expected: " + newRawOffset); 1107 } else { 1108 errln("FAIL: Modified zone(" + tz.getID() + ") - getRawOffset returns " + offset + "/ Expected: " + newRawOffset); 1109 } 1110 } 1111 // Ticket#5917 1112 // Check if DST observation status is not unexpectedly changed. 1113 boolean newDst = tz.useDaylightTime(); 1114 if (useDst != newDst) { 1115 errln("FAIL: Modified zone(" + tz.getID() + ") - useDaylightTime has changed from " + useDst + " to " + newDst); 1116 } 1117 // Make sure the offset is preserved in a clone 1118 TimeZone tzClone = (TimeZone)tz.clone(); 1119 int offsetC = tzClone.getRawOffset(); 1120 if (offsetC != newRawOffset) { 1121 if (isJdkZone) { 1122 logln("Cloned modified zone(" + tz.getID() + ") - getRawOffset returns " + offsetC + "/ Expected: " + newRawOffset); 1123 } else { 1124 errln("FAIL: Cloned modified zone(" + tz.getID() + ") - getRawOffset returns " + offsetC + "/ Expected: " + newRawOffset); 1125 } 1126 } 1127 1128 if (offset != offsetC) { 1129 errln("FAIL: Different raw offset - Original:" + offset + ", Cloned:" + offsetC); 1130 } 1131 } 1132 } 1133 1134 /* 1135 * Zone ID is not set by a SimpleTimeZone constructor 1136 */ 1137 @Test 1138 public void TestT5432() { 1139 String tzid = "MyZone"; 1140 SimpleTimeZone stz; 1141 1142 // 2-arg constructor 1143 stz = new SimpleTimeZone(0, tzid); 1144 if (!tzid.equals(stz.getID())) { 1145 errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected (" 1146 + tzid + ") [2-arg constructor]"); 1147 } 1148 1149 // 10-arg constructor 1150 stz = new SimpleTimeZone(0, tzid, 3, -1, 1, 3600000, 9, -1, 1, 3600000); 1151 if (!tzid.equals(stz.getID())) { 1152 errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected (" 1153 + tzid + ") [10-arg constructor]"); 1154 } 1155 1156 // 11-arg constructor 1157 stz = new SimpleTimeZone(0, tzid, 3, -1, 1, 3600000, 9, -1, 1, 3600000, 3600000); 1158 if (!tzid.equals(stz.getID())) { 1159 errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected (" 1160 + tzid + ") [11-arg constructor]"); 1161 } 1162 1163 // 13-arg constructor - this version had a problem reported by trac#5432 1164 stz = new SimpleTimeZone(0, tzid, 3, -1, 1, 3600000, SimpleTimeZone.WALL_TIME, 1165 9, -1, 1, 3600000, SimpleTimeZone.WALL_TIME, 3600000); 1166 if (!tzid.equals(stz.getID())) { 1167 errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected (" 1168 + tzid + ") [13-arg constructor]"); 1169 } 1170 } 1171 1172 // test bug #4265 1173 @Test 1174 public void TestJohannesburg() { 1175 String j_id="Africa/Johannesburg"; 1176 TimeZone johannesburg = TimeZone.getTimeZone(j_id); 1177 final int ONE_HOUR = 60*60*1000; 1178 int expectedOffset = ONE_HOUR*2; // GMT+2 - NO DST 1179 int offset = johannesburg.getOffset(GregorianCalendar.AD,2007,Calendar.JULY,5,Calendar.THURSDAY,0); 1180 1181 if(offset != expectedOffset) { 1182 errln("FAIL: zone " + j_id +" returned offset in July " + offset +", expected "+expectedOffset); 1183 } else { 1184 logln("OK: zone " + j_id +" returned offset in July: " + offset); 1185 } 1186 1187 int offset2 = johannesburg.getOffset(GregorianCalendar.AD,2007,Calendar.DECEMBER,12,Calendar.WEDNESDAY,0); 1188 1189 if(offset2 != expectedOffset) { 1190 errln("FAIL: zone " + j_id +" returned offset in December " + offset2 +", expected "+expectedOffset); 1191 } else { 1192 logln("OK: zone " + j_id +" returned offset in December: " + offset2); 1193 } 1194 } 1195 1196 @Test 1197 public void TestT7107() { 1198 Thread[] workers = new Thread[20]; 1199 for (int i = 0 ; i < workers.length; i++) { 1200 workers[i] = new Thread(new Runnable() { 1201 public void run() { 1202 for (int j = 0; j < 10000; j++) { 1203 try { 1204 com.ibm.icu.util.TimeZone.getTimeZone("GMT").getDisplayName(); 1205 } catch (Exception e) { 1206 errln("FAIL: Caught an exception " + e); 1207 } 1208 } 1209 } 1210 }); 1211 } 1212 for (Thread wk : workers) { 1213 wk.start(); 1214 } 1215 for (Thread wk : workers) { 1216 try { 1217 wk.join(); 1218 } catch (InterruptedException ie) { 1219 1220 } 1221 } 1222 } 1223} 1224 1225//eof 1226