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