1/* 2 * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 4031502 4035301 4040996 4051765 4059654 4061476 4070502 4071197 4071385 27 * 4073929 4083167 4086724 4092362 4095407 4096231 4096539 4100311 4103271 28 * 4106136 4108764 4114578 4118384 4125881 4125892 4136399 4141665 4142933 29 * 4145158 4145983 4147269 4149677 4162587 4165343 4166109 4167060 4173516 30 * 4174361 4177484 4197699 4209071 4288792 4328747 4413980 4546637 4623997 31 * 4685354 4655637 4683492 4080631 4080631 4167995 4340146 4639407 32 * 4652815 4652830 4740554 4936355 4738710 4633646 4846659 4822110 4960642 33 * 4973919 4980088 4965624 5013094 5006864 8152077 34 * @library /java/text/testlib 35 * @run main CalendarRegression 36 */ 37import java.io.ByteArrayInputStream; 38import java.io.ByteArrayOutputStream; 39import java.io.IOException; 40import java.io.ObjectInputStream; 41import java.io.ObjectOutputStream; 42import java.text.DateFormat; 43import java.text.NumberFormat; 44import java.text.SimpleDateFormat; 45import java.util.Calendar; 46import java.util.Date; 47import java.util.GregorianCalendar; 48import java.util.HashMap; 49import java.util.Locale; 50import java.util.Map; 51import java.util.SimpleTimeZone; 52import java.util.TimeZone; 53 54import static java.util.Calendar.*; 55 56public class CalendarRegression extends IntlTest { 57 58 public static void main(String[] args) throws Exception { 59 new CalendarRegression().run(args); 60 } 61 62 /* 63 Synopsis: java.sql.Timestamp constructor works wrong on Windows 95 64 65 ==== Here is the test ==== 66 public static void main (String args[]) { 67 java.sql.Timestamp t= new java.sql.Timestamp(0,15,5,5,8,13,123456700); 68 logln("expected=1901-04-05 05:08:13.1234567"); 69 logln(" result="+t); 70 } 71 72 ==== Here is the output of the test on Solaris or NT ==== 73 expected=1901-04-05 05:08:13.1234567 74 result=1901-04-05 05:08:13.1234567 75 76 ==== Here is the output of the test on Windows95 ==== 77 expected=1901-04-05 05:08:13.1234567 78 result=1901-04-05 06:08:13.1234567 79 */ 80 public void Test4031502() { 81 // This bug actually occurs on Windows NT as well, and doesn't 82 // require the host zone to be set; it can be set in Java. 83 String[] ids = TimeZone.getAvailableIDs(); 84 boolean bad = false; 85 for (int i = 0; i < ids.length; ++i) { 86 TimeZone zone = TimeZone.getTimeZone(ids[i]); 87 GregorianCalendar cal = new GregorianCalendar(zone); 88 cal.clear(); 89 cal.set(1900, 15, 5, 5, 8, 13); 90 if (cal.get(HOUR) != 5) { 91 logln(zone.getID() + " " 92 + //zone.useDaylightTime() + " " 93 + cal.get(DST_OFFSET) / (60 * 60 * 1000) + " " 94 + zone.getRawOffset() / (60 * 60 * 1000) 95 + ": HOUR = " + cal.get(HOUR)); 96 bad = true; 97 } 98 } 99 if (bad) { 100 errln("TimeZone problems with GC"); 101 } 102 } 103 104 public void Test4035301() { 105 GregorianCalendar c = new GregorianCalendar(98, 8, 7); 106 GregorianCalendar d = new GregorianCalendar(98, 8, 7); 107 if (c.after(d) 108 || c.after(c) 109 || c.before(d) 110 || c.before(c) 111 || !c.equals(c) 112 || !c.equals(d)) { 113 errln("Fail"); 114 } 115 } 116 117 public void Test4040996() { 118 String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000); 119 SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]); 120 pdt.setStartRule(APRIL, 1, SUNDAY, 2 * 60 * 60 * 1000); 121 pdt.setEndRule(OCTOBER, -1, SUNDAY, 2 * 60 * 60 * 1000); 122 Calendar calendar = new GregorianCalendar(pdt); 123 124 calendar.set(MONTH, 3); 125 calendar.set(DAY_OF_MONTH, 18); 126 calendar.set(SECOND, 30); 127 128 logln("MONTH: " + calendar.get(MONTH)); 129 logln("DAY_OF_MONTH: " 130 + calendar.get(DAY_OF_MONTH)); 131 logln("MINUTE: " + calendar.get(MINUTE)); 132 logln("SECOND: " + calendar.get(SECOND)); 133 134 calendar.add(SECOND, 6); 135 //This will print out todays date for MONTH and DAY_OF_MONTH 136 //instead of the date it was set to. 137 //This happens when adding MILLISECOND or MINUTE also 138 logln("MONTH: " + calendar.get(MONTH)); 139 logln("DAY_OF_MONTH: " 140 + calendar.get(DAY_OF_MONTH)); 141 logln("MINUTE: " + calendar.get(MINUTE)); 142 logln("SECOND: " + calendar.get(SECOND)); 143 if (calendar.get(MONTH) != 3 144 || calendar.get(DAY_OF_MONTH) != 18 145 || calendar.get(SECOND) != 36) { 146 errln("Fail: Calendar.add misbehaves"); 147 } 148 } 149 150 public void Test4051765() { 151 Calendar cal = Calendar.getInstance(); 152 cal.setLenient(false); 153 cal.set(DAY_OF_WEEK, 0); 154 try { 155 cal.getTime(); 156 errln("Fail: DAY_OF_WEEK 0 should be disallowed"); 157 } catch (IllegalArgumentException e) { 158 return; 159 } 160 } 161 162 /* User error - no bug here 163 public void Test4059524() { 164 // Create calendar for April 10, 1997 165 GregorianCalendar calendar = new GregorianCalendar(); 166 // print out a bunch of interesting things 167 logln("ERA: " + calendar.get(calendar.ERA)); 168 logln("YEAR: " + calendar.get(calendar.YEAR)); 169 logln("MONTH: " + calendar.get(calendar.MONTH)); 170 logln("WEEK_OF_YEAR: " + 171 calendar.get(calendar.WEEK_OF_YEAR)); 172 logln("WEEK_OF_MONTH: " + 173 calendar.get(calendar.WEEK_OF_MONTH)); 174 logln("DATE: " + calendar.get(calendar.DATE)); 175 logln("DAY_OF_MONTH: " + 176 calendar.get(calendar.DAY_OF_MONTH)); 177 logln("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR)); 178 logln("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK)); 179 logln("DAY_OF_WEEK_IN_MONTH: " + 180 calendar.get(calendar.DAY_OF_WEEK_IN_MONTH)); 181 logln("AM_PM: " + calendar.get(calendar.AM_PM)); 182 logln("HOUR: " + calendar.get(calendar.HOUR)); 183 logln("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY)); 184 logln("MINUTE: " + calendar.get(calendar.MINUTE)); 185 logln("SECOND: " + calendar.get(calendar.SECOND)); 186 logln("MILLISECOND: " + calendar.get(calendar.MILLISECOND)); 187 logln("ZONE_OFFSET: " 188 + (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); 189 logln("DST_OFFSET: " 190 + (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); 191 calendar = new GregorianCalendar(1997,3,10); 192 calendar.getTime(); 193 logln("April 10, 1997"); 194 logln("ERA: " + calendar.get(calendar.ERA)); 195 logln("YEAR: " + calendar.get(calendar.YEAR)); 196 logln("MONTH: " + calendar.get(calendar.MONTH)); 197 logln("WEEK_OF_YEAR: " + 198 calendar.get(calendar.WEEK_OF_YEAR)); 199 logln("WEEK_OF_MONTH: " + 200 calendar.get(calendar.WEEK_OF_MONTH)); 201 logln("DATE: " + calendar.get(calendar.DATE)); 202 logln("DAY_OF_MONTH: " + 203 calendar.get(calendar.DAY_OF_MONTH)); 204 logln("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR)); 205 logln("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK)); 206 logln("DAY_OF_WEEK_IN_MONTH: " + calendar.get(calendar.DAY_OF_WEEK_IN_MONTH)); 207 logln("AM_PM: " + calendar.get(calendar.AM_PM)); 208 logln("HOUR: " + calendar.get(calendar.HOUR)); 209 logln("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY)); 210 logln("MINUTE: " + calendar.get(calendar.MINUTE)); 211 logln("SECOND: " + calendar.get(calendar.SECOND)); 212 logln("MILLISECOND: " + calendar.get(calendar.MILLISECOND)); 213 logln("ZONE_OFFSET: " 214 + (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); // in hours 215 logln("DST_OFFSET: " 216 + (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); // in hours 217 } 218 */ 219 public void Test4059654() { 220 GregorianCalendar gc = new GregorianCalendar(); 221 222 gc.set(1997, 3, 1, 15, 16, 17); // April 1, 1997 223 224 gc.set(HOUR, 0); 225 gc.set(AM_PM, AM); 226 gc.set(MINUTE, 0); 227 gc.set(SECOND, 0); 228 gc.set(MILLISECOND, 0); 229 230 Date cd = gc.getTime(); 231 @SuppressWarnings("deprecation") 232 Date exp = new Date(97, 3, 1, 0, 0, 0); 233 if (!cd.equals(exp)) { 234 errln("Fail: Calendar.set broken. Got " + cd + " Want " + exp); 235 } 236 } 237 238 public void Test4061476() { 239 SimpleDateFormat fmt = new SimpleDateFormat("ddMMMyy", Locale.UK); 240 Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"), 241 Locale.UK); 242 fmt.setCalendar(cal); 243 try { 244 Date date = fmt.parse("29MAY97"); 245 cal.setTime(date); 246 } catch (Exception e) { 247 } 248 cal.set(HOUR_OF_DAY, 13); 249 logln("Hour: " + cal.get(HOUR_OF_DAY)); 250 cal.add(HOUR_OF_DAY, 6); 251 logln("Hour: " + cal.get(HOUR_OF_DAY)); 252 if (cal.get(HOUR_OF_DAY) != 19) { 253 errln("Fail: Want 19 Got " + cal.get(HOUR_OF_DAY)); 254 } 255 } 256 257 public void Test4070502() { 258 @SuppressWarnings("deprecation") 259 Date d = getAssociatedDate(new Date(98, 0, 30)); 260 Calendar cal = new GregorianCalendar(); 261 cal.setTime(d); 262 if (cal.get(DAY_OF_WEEK) == SATURDAY 263 || cal.get(DAY_OF_WEEK) == SUNDAY) { 264 errln("Fail: Want weekday Got " + d); 265 } 266 } 267 268 /** 269 * Get the associated date starting from a specified date 270 * NOTE: the unnecessary "getTime()'s" below are a work-around for a 271 * bug in jdk 1.1.3 (and probably earlier versions also) 272 * <p> 273 * @param date The date to start from 274 */ 275 public static Date getAssociatedDate(Date d) { 276 GregorianCalendar cal = new GregorianCalendar(); 277 cal.setTime(d); 278 //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH 279 // cal.getTime(); // <--- REMOVE THIS TO SEE BUG 280 while (true) { 281 int wd = cal.get(DAY_OF_WEEK); 282 if (wd == SATURDAY || wd == SUNDAY) { 283 cal.add(DATE, 1); 284 // cal.getTime(); 285 } else { 286 break; 287 } 288 } 289 return cal.getTime(); 290 } 291 292 public void Test4071197() { 293 dowTest(false); 294 dowTest(true); 295 } 296 297 void dowTest(boolean lenient) { 298 GregorianCalendar cal = new GregorianCalendar(); 299 cal.set(1997, AUGUST, 12); // Wednesday 300 // cal.getTime(); // Force update 301 cal.setLenient(lenient); 302 cal.set(1996, DECEMBER, 1); // Set the date to be December 1, 1996 303 int dow = cal.get(DAY_OF_WEEK); 304 int min = cal.getMinimum(DAY_OF_WEEK); 305 int max = cal.getMaximum(DAY_OF_WEEK); 306 logln(cal.getTime().toString()); 307 if (min != SUNDAY || max != SATURDAY) { 308 errln("FAIL: Min/max bad"); 309 } 310 if (dow < min || dow > max) { 311 errln("FAIL: Day of week " + dow + " out of range"); 312 } 313 if (dow != SUNDAY) { 314 errln("FAIL: Day of week should be SUNDAY Got " + dow); 315 } 316 } 317 318 @SuppressWarnings("deprecation") 319 public void Test4071385() { 320 Calendar cal = Calendar.getInstance(); 321 cal.setTime(new Date(98, JUNE, 24)); 322 cal.set(MONTH, NOVEMBER); // change a field 323 logln(cal.getTime().toString()); 324 if (!cal.getTime().equals(new Date(98, NOVEMBER, 24))) { 325 errln("Fail"); 326 } 327 } 328 329 public void Test4073929() { 330 GregorianCalendar foo1 = new GregorianCalendar(1997, 8, 27); 331 foo1.add(DAY_OF_MONTH, +1); 332 int testyear = foo1.get(YEAR); 333 int testmonth = foo1.get(MONTH); 334 int testday = foo1.get(DAY_OF_MONTH); 335 if (testyear != 1997 336 || testmonth != 8 337 || testday != 28) { 338 errln("Fail: Calendar not initialized"); 339 } 340 } 341 342 public void Test4083167() { 343 TimeZone saveZone = TimeZone.getDefault(); 344 try { 345 TimeZone.setDefault(TimeZone.getTimeZone("UTC")); 346 Date firstDate = new Date(); 347 Calendar cal = new GregorianCalendar(); 348 cal.setTime(firstDate); 349 long firstMillisInDay = cal.get(HOUR_OF_DAY) * 3600000L 350 + cal.get(MINUTE) * 60000L 351 + cal.get(SECOND) * 1000L 352 + cal.get(MILLISECOND); 353 354 logln("Current time: " + firstDate.toString()); 355 356 for (int validity = 0; validity < 30; validity++) { 357 Date lastDate = new Date(firstDate.getTime() 358 + (long) validity * 1000 * 24 * 60 * 60); 359 cal.setTime(lastDate); 360 long millisInDay = cal.get(HOUR_OF_DAY) * 3600000L 361 + cal.get(MINUTE) * 60000L 362 + cal.get(SECOND) * 1000L 363 + cal.get(MILLISECOND); 364 if (firstMillisInDay != millisInDay) { 365 errln("Day has shifted " + lastDate); 366 } 367 } 368 } finally { 369 TimeZone.setDefault(saveZone); 370 } 371 } 372 373 public void Test4086724() { 374 SimpleDateFormat date; 375 TimeZone saveZone = TimeZone.getDefault(); 376 Locale saveLocale = Locale.getDefault(); 377 378 String summerTime = "British Summer Time"; 379 String standardTime = "Greenwich Mean Time"; 380 try { 381 Locale.setDefault(Locale.UK); 382 TimeZone.setDefault(TimeZone.getTimeZone("Europe/London")); 383 date = new SimpleDateFormat("zzzz"); 384 385 Calendar cal = Calendar.getInstance(); 386 cal.set(1997, SEPTEMBER, 30); 387 Date now = cal.getTime(); 388 String formattedDate = date.format(now); 389 if (!formattedDate.equals(summerTime)) { 390 errln("Wrong display name \"" + formattedDate 391 + "\" for <" + now + ">"); 392 } 393 int weekOfYear = cal.get(WEEK_OF_YEAR); 394 if (weekOfYear != 40) { 395 errln("Wrong week-of-year " + weekOfYear 396 + " for <" + now + ">"); 397 } 398 399 cal.set(1996, DECEMBER, 31); 400 now = cal.getTime(); 401 formattedDate = date.format(now); 402 if (!formattedDate.equals(standardTime)) { 403 errln("Wrong display name \"" + formattedDate 404 + "\" for <" + now + ">"); 405 } 406 weekOfYear = cal.get(WEEK_OF_YEAR); 407 if (weekOfYear != 1) { 408 errln("Wrong week-of-year " + weekOfYear 409 + " for <" + now + ">"); 410 } 411 412 cal.set(1997, JANUARY, 1); 413 now = cal.getTime(); 414 formattedDate = date.format(now); 415 if (!formattedDate.equals(standardTime)) { 416 errln("Wrong display name \"" + formattedDate 417 + "\" for <" + now + ">"); 418 } 419 weekOfYear = cal.get(WEEK_OF_YEAR); 420 if (weekOfYear != 1) { 421 errln("Wrong week-of-year " + weekOfYear 422 + " for <" + now + ">"); 423 } 424 425 cal.set(1997, JANUARY, 8); 426 now = cal.getTime(); 427 formattedDate = date.format(now); 428 if (!formattedDate.equals(standardTime)) { 429 errln("Wrong display name \"" + formattedDate 430 + "\" for <" + now + ">"); 431 } 432 weekOfYear = cal.get(WEEK_OF_YEAR); 433 if (weekOfYear != 2) { 434 errln("Wrong week-of-year " + weekOfYear 435 + " for <" + now + ">"); 436 } 437 438 } finally { 439 Locale.setDefault(saveLocale); 440 TimeZone.setDefault(saveZone); 441 } 442 } 443 444 public void Test4092362() { 445 GregorianCalendar cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40); 446 /*cal1.set( Calendar.YEAR, 1997 ); 447 cal1.set( Calendar.MONTH, 10 ); 448 cal1.set( Calendar.DATE, 11 ); 449 cal1.set( Calendar.HOUR, 10 ); 450 cal1.set( Calendar.MINUTE, 20 ); 451 cal1.set( Calendar.SECOND, 40 ); */ 452 453 logln(" Cal1 = " + cal1.getTime().getTime()); 454 logln(" Cal1 time in ms = " + cal1.get(MILLISECOND)); 455 for (int k = 0; k < 100; k++); 456 457 GregorianCalendar cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40); 458 /*cal2.set( Calendar.YEAR, 1997 ); 459 cal2.set( Calendar.MONTH, 10 ); 460 cal2.set( Calendar.DATE, 11 ); 461 cal2.set( Calendar.HOUR, 10 ); 462 cal2.set( Calendar.MINUTE, 20 ); 463 cal2.set( Calendar.SECOND, 40 ); */ 464 465 logln(" Cal2 = " + cal2.getTime().getTime()); 466 logln(" Cal2 time in ms = " + cal2.get(MILLISECOND)); 467 if (!cal1.equals(cal2)) { 468 errln("Fail: Milliseconds randomized"); 469 } 470 } 471 472 public void Test4095407() { 473 GregorianCalendar a = new GregorianCalendar(1997, NOVEMBER, 13); 474 int dow = a.get(DAY_OF_WEEK); 475 if (dow != THURSDAY) { 476 errln("Fail: Want THURSDAY Got " + dow); 477 } 478 } 479 480 public void Test4096231() { 481 TimeZone GMT = TimeZone.getTimeZone("GMT"); 482 TimeZone PST = TimeZone.getTimeZone("PST"); 483 int sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997; 484 485 Calendar cal1 = new GregorianCalendar(PST); 486 cal1.setTime(new Date(880698639000L)); 487 int p; 488 logln("PST 1 is: " + (p = cal1.get(HOUR_OF_DAY))); 489 cal1.setTimeZone(GMT); 490 // Issue 1: Changing the timezone doesn't change the 491 // represented time. 492 int h1, h2; 493 logln("GMT 1 is: " + (h1 = cal1.get(HOUR_OF_DAY))); 494 cal1.setTime(new Date(880698639000L)); 495 logln("GMT 2 is: " + (h2 = cal1.get(HOUR_OF_DAY))); 496 // Note: This test had a bug in it. It wanted h1!=h2, when 497 // what was meant was h1!=p. Fixed this concurrent with fix 498 // to 4177484. 499 if (p == h1 || h1 != h2) { 500 errln("Fail: Hour same in different zones"); 501 } 502 503 Calendar cal2 = new GregorianCalendar(GMT); 504 Calendar cal3 = new GregorianCalendar(PST); 505 cal2.set(MILLISECOND, 0); 506 cal3.set(MILLISECOND, 0); 507 508 cal2.set(cal1.get(YEAR), 509 cal1.get(MONTH), 510 cal1.get(DAY_OF_MONTH), 511 cal1.get(HOUR_OF_DAY), 512 cal1.get(MINUTE), 513 cal1.get(SECOND)); 514 515 long t1, t2, t3, t4; 516 logln("RGMT 1 is: " + (t1 = cal2.getTime().getTime())); 517 cal3.set(year, month, day, hr, min, sec); 518 logln("RPST 1 is: " + (t2 = cal3.getTime().getTime())); 519 cal3.setTimeZone(GMT); 520 logln("RGMT 2 is: " + (t3 = cal3.getTime().getTime())); 521 cal3.set(cal1.get(YEAR), 522 cal1.get(MONTH), 523 cal1.get(DAY_OF_MONTH), 524 cal1.get(HOUR_OF_DAY), 525 cal1.get(MINUTE), 526 cal1.get(SECOND)); 527 // Issue 2: Calendar continues to use the timezone in its 528 // constructor for set() conversions, regardless 529 // of calls to setTimeZone() 530 logln("RGMT 3 is: " + (t4 = cal3.getTime().getTime())); 531 if (t1 == t2 532 || t1 != t4 533 || t2 != t3) { 534 errln("Fail: Calendar zone behavior faulty"); 535 } 536 } 537 538 public void Test4096539() { 539 int[] y = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 540 541 for (int x = 0; x < 12; x++) { 542 GregorianCalendar gc = new GregorianCalendar(1997, x, y[x]); 543 int m1, m2; 544 log((m1 = gc.get(MONTH) + 1) + "/" 545 + gc.get(DATE) + "/" + gc.get(YEAR) 546 + " + 1mo = "); 547 548 gc.add(MONTH, 1); 549 logln((m2 = gc.get(MONTH) + 1) + "/" 550 + gc.get(DATE) + "/" + gc.get(YEAR) 551 ); 552 int m = (m1 % 12) + 1; 553 if (m2 != m) { 554 errln("Fail: Want " + m + " Got " + m2); 555 } 556 } 557 558 } 559 560 public void Test4100311() { 561 Locale locale = Locale.getDefault(); 562 if (!TestUtils.usesGregorianCalendar(locale)) { 563 logln("Skipping this test because locale is " + locale); 564 return; 565 } 566 567 GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance(); 568 cal.set(YEAR, 1997); 569 cal.set(DAY_OF_YEAR, 1); 570 Date d = cal.getTime(); // Should be Jan 1 571 logln(d.toString()); 572 if (cal.get(DAY_OF_YEAR) != 1) { 573 errln("Fail: DAY_OF_YEAR not set"); 574 } 575 } 576 577 public void Test4103271() { 578 Locale locale = Locale.getDefault(); 579 if (!TestUtils.usesGregorianCalendar(locale)) { 580 logln("Skipping this test because locale is " + locale); 581 return; 582 } 583 584 SimpleDateFormat sdf = new SimpleDateFormat(); 585 int numYears = 40, startYear = 1997, numDays = 15; 586 String output, testDesc; 587 GregorianCalendar testCal = (GregorianCalendar) Calendar.getInstance(); 588 testCal.clear(); 589 sdf.setCalendar(testCal); 590 sdf.applyPattern("d MMM yyyy"); 591 boolean fail = false; 592 for (int firstDay = 1; firstDay <= 2; firstDay++) { 593 for (int minDays = 1; minDays <= 7; minDays++) { 594 testCal.setMinimalDaysInFirstWeek(minDays); 595 testCal.setFirstDayOfWeek(firstDay); 596 testDesc = ("Test" + String.valueOf(firstDay) + String.valueOf(minDays)); 597 logln(testDesc + " => 1st day of week=" 598 + String.valueOf(firstDay) 599 + ", minimum days in first week=" 600 + String.valueOf(minDays)); 601 for (int j = startYear; j <= startYear + numYears; j++) { 602 testCal.set(j, 11, 25); 603 for (int i = 0; i < numDays; i++) { 604 testCal.add(DATE, 1); 605 String calWOY; 606 int actWOY = testCal.get(WEEK_OF_YEAR); 607 if (actWOY < 1 || actWOY > 53) { 608 Date d = testCal.getTime(); 609 calWOY = String.valueOf(actWOY); 610 output = testDesc + " - " + sdf.format(d) + "\t"; 611 output = output + "\t" + calWOY; 612 logln(output); 613 fail = true; 614 } 615 } 616 } 617 } 618 } 619 620 int[] DATA = { 621 3, 52, 52, 52, 52, 52, 52, 52, 622 1, 1, 1, 1, 1, 1, 1, 623 2, 2, 2, 2, 2, 2, 2, 624 4, 52, 52, 52, 52, 52, 52, 52, 625 53, 53, 53, 53, 53, 53, 53, 626 1, 1, 1, 1, 1, 1, 1}; 627 testCal.setFirstDayOfWeek(SUNDAY); 628 for (int j = 0; j < DATA.length; j += 22) { 629 logln("Minimal days in first week = " + DATA[j] 630 + " Week starts on Sunday"); 631 testCal.setMinimalDaysInFirstWeek(DATA[j]); 632 testCal.set(1997, DECEMBER, 21); 633 for (int i = 0; i < 21; ++i) { 634 int woy = testCal.get(WEEK_OF_YEAR); 635 log("\t" + testCal.getTime() + " " + woy); 636 if (woy != DATA[j + 1 + i]) { 637 log(" ERROR"); 638 fail = true; 639 } else { 640 logln(" OK"); 641 } 642 643 // Now compute the time from the fields, and make sure we 644 // get the same answer back. This is a round-trip test. 645 Date save = testCal.getTime(); 646 testCal.clear(); 647 testCal.set(YEAR, DATA[j + 1 + i] < 25 ? 1998 : 1997); 648 testCal.set(WEEK_OF_YEAR, DATA[j + 1 + i]); 649 testCal.set(DAY_OF_WEEK, (i % 7) + SUNDAY); 650 if (!testCal.getTime().equals(save)) { 651 logln(" Parse failed: " + testCal.getTime()); 652 fail = true; 653 } else { 654 logln(" Passed"); 655 } 656 657 testCal.setTime(save); 658 testCal.add(DAY_OF_MONTH, 1); 659 } 660 } 661 662 // Test field disambiguation with a few special hard-coded cases. 663 // This shouldn't fail if the above cases aren't failing. 664 @SuppressWarnings("deprecation") 665 Object[] DISAM = { 666 1998, 1, SUNDAY, 667 new Date(97, DECEMBER, 28), 668 1998, 2, SATURDAY, 669 new Date(98, JANUARY, 10), 670 1998, 53, THURSDAY, 671 new Date(98, DECEMBER, 31), 672 1998, 53, FRIDAY, 673 new Date(99, JANUARY, 1)}; 674 testCal.setMinimalDaysInFirstWeek(3); 675 testCal.setFirstDayOfWeek(SUNDAY); 676 for (int i = 0; i < DISAM.length; i += 4) { 677 int y = (Integer) DISAM[i]; 678 int woy = (Integer) DISAM[i + 1]; 679 int dow = (Integer) DISAM[i + 2]; 680 Date exp = (Date) DISAM[i + 3]; 681 testCal.clear(); 682 testCal.set(YEAR, y); 683 testCal.set(WEEK_OF_YEAR, woy); 684 testCal.set(DAY_OF_WEEK, dow); 685 log(y + "-W" + woy + "-DOW" + dow); 686 if (!testCal.getTime().equals(exp)) { 687 logln(" FAILED expect: " + exp + "\n got: " + testCal.getTime()); 688 fail = true; 689 } else { 690 logln(" OK"); 691 } 692 } 693 694 // Now try adding and rolling 695 Object ADD = new Object(); 696 Object ROLL = new Object(); 697 @SuppressWarnings("deprecation") 698 Object[] ADDROLL = { 699 ADD, 1, new Date(98, DECEMBER, 25), new Date(99, JANUARY, 1), 700 ADD, 1, new Date(97, DECEMBER, 28), new Date(98, JANUARY, 4), 701 ROLL, 1, new Date(98, DECEMBER, 27), new Date(98, JANUARY, 4), 702 ROLL, 1, new Date(99, DECEMBER, 24), new Date(99, DECEMBER, 31), 703 ROLL, 1, new Date(99, DECEMBER, 25), new Date(99, JANUARY, 9)}; 704 testCal.setMinimalDaysInFirstWeek(3); 705 testCal.setFirstDayOfWeek(SUNDAY); 706 for (int i = 0; i < ADDROLL.length; i += 4) { 707 int amount = (Integer) ADDROLL[i + 1]; 708 Date before = (Date) ADDROLL[i + 2]; 709 Date after = (Date) ADDROLL[i + 3]; 710 711 testCal.setTime(before); 712 if (ADDROLL[i] == ADD) { 713 testCal.add(WEEK_OF_YEAR, amount); 714 } else { 715 testCal.roll(WEEK_OF_YEAR, amount); 716 } 717 log((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,") 718 + amount + ")\t " + before 719 + "\n\t\t => " + testCal.getTime()); 720 if (!after.equals(testCal.getTime())) { 721 logln("\tFAIL\n\t\texp: " + after); 722 fail = true; 723 } else { 724 logln(" OK"); 725 } 726 727 testCal.setTime(after); 728 if (ADDROLL[i] == ADD) { 729 testCal.add(WEEK_OF_YEAR, -amount); 730 } else { 731 testCal.roll(WEEK_OF_YEAR, -amount); 732 } 733 log((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,") 734 + (-amount) + ") " + after 735 + "\n\t\t => " + testCal.getTime()); 736 if (!before.equals(testCal.getTime())) { 737 logln("\tFAIL\n\t\texp: " + before); 738 fail = true; 739 } else { 740 logln("\tOK"); 741 } 742 } 743 744 if (fail) { 745 errln("Fail: Week of year misbehaving"); 746 } 747 } 748 749 public void Test4106136() { 750 Locale saveLocale = Locale.getDefault(); 751 try { 752 Locale[] locales = {Locale.CHINESE, Locale.CHINA}; 753 for (int i = 0; i < locales.length; ++i) { 754 Locale.setDefault(locales[i]); 755 int[] n = { 756 getAvailableLocales().length, 757 DateFormat.getAvailableLocales().length, 758 NumberFormat.getAvailableLocales().length}; 759 for (int j = 0; j < n.length; ++j) { 760 if (n[j] == 0) { 761 errln("Fail: No locales for " + locales[i]); 762 } 763 } 764 } 765 } finally { 766 Locale.setDefault(saveLocale); 767 } 768 } 769 770 @SuppressWarnings("deprecation") 771 public void Test4108764() { 772 Date d00 = new Date(97, MARCH, 15, 12, 00, 00); 773 Date d01 = new Date(97, MARCH, 15, 12, 00, 56); 774 Date d10 = new Date(97, MARCH, 15, 12, 34, 00); 775 Date d11 = new Date(97, MARCH, 15, 12, 34, 56); 776 Date epoch = new Date(70, JANUARY, 1); 777 778 Calendar cal = Calendar.getInstance(); 779 cal.setTime(d11); 780 781 cal.clear(MINUTE); 782 logln(cal.getTime().toString()); 783 if (!cal.getTime().equals(d01)) { 784 errln("Fail: clear(MINUTE) broken"); 785 } 786 787 cal.set(SECOND, 0); 788 logln(cal.getTime().toString()); 789 if (!cal.getTime().equals(d00)) { 790 errln("Fail: set(SECOND, 0) broken"); 791 } 792 793 cal.setTime(d11); 794 cal.set(SECOND, 0); 795 logln(cal.getTime().toString()); 796 if (!cal.getTime().equals(d10)) { 797 errln("Fail: set(SECOND, 0) broken #2"); 798 } 799 800 cal.clear(MINUTE); 801 logln(cal.getTime().toString()); 802 if (!cal.getTime().equals(d00)) { 803 errln("Fail: clear(MINUTE) broken #2"); 804 } 805 806 cal.clear(); 807 logln(cal.getTime().toString()); 808 if (!cal.getTime().equals(epoch)) { 809 errln("Fail: clear() broken Want " + epoch); 810 } 811 } 812 813 @SuppressWarnings("deprecation") 814 public void Test4114578() { 815 Locale locale = Locale.getDefault(); 816 if (!TestUtils.usesGregorianCalendar(locale)) { 817 logln("Skipping this test because locale is " + locale); 818 return; 819 } 820 821 int ONE_HOUR = 60 * 60 * 1000; 822 TimeZone saveZone = TimeZone.getDefault(); 823 boolean fail = false; 824 try { 825 TimeZone.setDefault(TimeZone.getTimeZone("PST")); 826 Calendar cal = Calendar.getInstance(); 827 long onset = new Date(98, APRIL, 5, 1, 0).getTime() + ONE_HOUR; 828 long cease = new Date(98, OCTOBER, 25, 0, 0).getTime() + 2 * ONE_HOUR; 829 830 final int ADD = 1; 831 final int ROLL = 2; 832 833 long[] DATA = { 834 // Start Action Amt Expected_change 835 onset - ONE_HOUR, ADD, 1, ONE_HOUR, 836 onset, ADD, -1, -ONE_HOUR, 837 onset - ONE_HOUR, ROLL, 1, ONE_HOUR, 838 onset, ROLL, -1, -ONE_HOUR, 839 cease - ONE_HOUR, ADD, 1, ONE_HOUR, 840 cease, ADD, -1, -ONE_HOUR, 841 // roll() was changed to support wall-clock-based roll (JDK-8152077). The 842 // time value may jump 2 hours by skipping non-existent wall-clock time. 843 // Note that JDK-4114578 was a problem of add(), not roll(). 844 cease - ONE_HOUR, ROLL, 1, ONE_HOUR * 2, 845 cease, ROLL, -1, -ONE_HOUR * 2}; 846 847 for (int i = 0; i < DATA.length; i += 4) { 848 Date date = new Date(DATA[i]); 849 int amt = (int) DATA[i + 2]; 850 long expectedChange = DATA[i + 3]; 851 852 log(date.toString()); 853 cal.setTime(date); 854 855 switch ((int) DATA[i + 1]) { 856 case ADD: 857 log(" add (HOUR," + (amt < 0 ? "" : "+") + amt + ")= "); 858 cal.add(HOUR, amt); 859 break; 860 case ROLL: 861 log(" roll(HOUR," + (amt < 0 ? "" : "+") + amt + ")= "); 862 cal.roll(HOUR, amt); 863 break; 864 } 865 866 log(cal.getTime().toString()); 867 868 long change = cal.getTime().getTime() - date.getTime(); 869 if (change != expectedChange) { 870 fail = true; 871 logln(" FAIL"); 872 } else { 873 logln(" OK"); 874 } 875 } 876 } finally { 877 TimeZone.setDefault(saveZone); 878 } 879 880 if (fail) { 881 errln("Fail: roll/add misbehaves around DST onset/cease"); 882 } 883 } 884 885 /** 886 * Make sure maximum for HOUR field is 11, not 12. 887 */ 888 public void Test4118384() { 889 Calendar cal = Calendar.getInstance(); 890 if (cal.getMaximum(HOUR) != 11 891 || cal.getLeastMaximum(HOUR) != 11 892 || cal.getActualMaximum(HOUR) != 11) { 893 errln("Fail: maximum of HOUR field should be 11"); 894 } 895 } 896 897 /** 898 * Check isLeapYear for BC years. 899 */ 900 public void Test4125881() { 901 Locale locale = Locale.getDefault(); 902 if (!TestUtils.usesGregorianCalendar(locale)) { 903 logln("Skipping this test because locale is " + locale); 904 return; 905 } 906 907 GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance(); 908 DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G"); 909 cal.clear(); 910 for (int y = -20; y <= 10; ++y) { 911 cal.set(ERA, y < 1 ? GregorianCalendar.BC : GregorianCalendar.AD); 912 cal.set(YEAR, y < 1 ? 1 - y : y); 913 logln(y + " = " + fmt.format(cal.getTime()) + " " 914 + cal.isLeapYear(y)); 915 if (cal.isLeapYear(y) != ((y + 40) % 4 == 0)) { 916 errln("Leap years broken"); 917 } 918 } 919 } 920 921 /** 922 * Prove that GregorianCalendar is proleptic (it used to cut off 923 * at 45 BC, and not have leap years before then). 924 */ 925 public void Test4125892() { 926 Locale locale = Locale.getDefault(); 927 if (!TestUtils.usesGregorianCalendar(locale)) { 928 logln("Skipping this test because locale is " + locale); 929 return; 930 } 931 932 GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance(); 933 DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G"); 934 cal.clear(); 935 cal.set(ERA, GregorianCalendar.BC); 936 cal.set(YEAR, 81); // 81 BC is a leap year (proleptically) 937 cal.set(MONTH, FEBRUARY); 938 cal.set(DATE, 28); 939 cal.add(DATE, 1); 940 if (cal.get(DATE) != 29 941 || !cal.isLeapYear(-80)) { // -80 == 81 BC 942 errln("Calendar not proleptic"); 943 } 944 } 945 946 /** 947 * Calendar and GregorianCalendar hashCode() methods need improvement. 948 * Calendar needs a good implementation that subclasses can override, 949 * and GregorianCalendar should use that implementation. 950 */ 951 public void Test4136399() { 952 /* Note: This test is actually more strict than it has to be. 953 * Technically, there is no requirement that unequal objects have 954 * unequal hashes. We only require equal objects to have equal hashes. 955 * It is desirable for unequal objects to have distributed hashes, but 956 * there is no hard requirement here. 957 * 958 * In this test we make assumptions about certain attributes of calendar 959 * objects getting represented in the hash, which need not always be the 960 * case (although it does work currently with the given test). */ 961 Calendar a = Calendar.getInstance(); 962 Calendar b = (Calendar) a.clone(); 963 if (a.hashCode() != b.hashCode()) { 964 errln("Calendar hash code unequal for cloned objects"); 965 } 966 967 b.setMinimalDaysInFirstWeek(7 - a.getMinimalDaysInFirstWeek()); 968 if (a.hashCode() == b.hashCode()) { 969 errln("Calendar hash code ignores minimal days in first week"); 970 } 971 b.setMinimalDaysInFirstWeek(a.getMinimalDaysInFirstWeek()); 972 973 b.setFirstDayOfWeek((a.getFirstDayOfWeek() % 7) + 1); // Next day 974 if (a.hashCode() == b.hashCode()) { 975 errln("Calendar hash code ignores first day of week"); 976 } 977 b.setFirstDayOfWeek(a.getFirstDayOfWeek()); 978 979 b.setLenient(!a.isLenient()); 980 if (a.hashCode() == b.hashCode()) { 981 errln("Calendar hash code ignores lenient setting"); 982 } 983 b.setLenient(a.isLenient()); 984 985 // Assume getTimeZone() returns a reference, not a clone 986 // of a reference -- this is true as of this writing 987 b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset() + 60 * 60 * 1000); 988 if (a.hashCode() == b.hashCode()) { 989 errln("Calendar hash code ignores zone"); 990 } 991 b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset()); 992 993 GregorianCalendar c = new GregorianCalendar(); 994 GregorianCalendar d = (GregorianCalendar) c.clone(); 995 if (c.hashCode() != d.hashCode()) { 996 errln("GregorianCalendar hash code unequal for clones objects"); 997 } 998 Date cutover = c.getGregorianChange(); 999 d.setGregorianChange(new Date(cutover.getTime() + 24 * 60 * 60 * 1000)); 1000 if (c.hashCode() == d.hashCode()) { 1001 errln("GregorianCalendar hash code ignores cutover"); 1002 } 1003 } 1004 1005 /** 1006 * GregorianCalendar.equals() ignores cutover date 1007 */ 1008 public void Test4141665() { 1009 GregorianCalendar cal = new GregorianCalendar(); 1010 GregorianCalendar cal2 = (GregorianCalendar) cal.clone(); 1011 Date cut = cal.getGregorianChange(); 1012 Date cut2 = new Date(cut.getTime() + 100 * 24 * 60 * 60 * 1000L); // 100 days later 1013 if (!cal.equals(cal2)) { 1014 errln("Cloned GregorianCalendars not equal"); 1015 } 1016 cal2.setGregorianChange(cut2); 1017 if (cal.equals(cal2)) { 1018 errln("GregorianCalendar.equals() ignores cutover"); 1019 } 1020 } 1021 1022 /** 1023 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar.roll() 1024 * when IllegalArgumentException should be. 1025 */ 1026 public void Test4142933() { 1027 GregorianCalendar calendar = new GregorianCalendar(); 1028 try { 1029 calendar.roll(-1, true); 1030 errln("Test failed, no exception trown"); 1031 } catch (IllegalArgumentException e) { 1032 // OK: Do nothing 1033 // logln("Test passed"); 1034 } catch (Exception e) { 1035 errln("Test failed. Unexpected exception is thrown: " + e); 1036 e.printStackTrace(); 1037 } 1038 } 1039 1040 /** 1041 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is 1042 * confusing; unless the time zone has a raw offset of zero, one or the 1043 * other of these will wrap. We've modified the test given in the bug 1044 * report to therefore only check the behavior of a calendar with a zero raw 1045 * offset zone. 1046 */ 1047 public void Test4145158() { 1048 GregorianCalendar calendar = new GregorianCalendar(); 1049 1050 calendar.setTimeZone(TimeZone.getTimeZone("GMT")); 1051 1052 calendar.setTime(new Date(Long.MIN_VALUE)); 1053 int year1 = calendar.get(YEAR); 1054 int era1 = calendar.get(ERA); 1055 1056 calendar.setTime(new Date(Long.MAX_VALUE)); 1057 int year2 = calendar.get(YEAR); 1058 int era2 = calendar.get(ERA); 1059 1060 if (year1 == year2 && era1 == era2) { 1061 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around"); 1062 } 1063 } 1064 1065 /** 1066 * Maximum value for YEAR field wrong. 1067 */ 1068 public void Test4145983() { 1069 GregorianCalendar calendar = new GregorianCalendar(); 1070 calendar.setTimeZone(TimeZone.getTimeZone("GMT")); 1071 Date[] DATES = {new Date(Long.MAX_VALUE), new Date(Long.MIN_VALUE)}; 1072 for (int i = 0; i < DATES.length; ++i) { 1073 calendar.setTime(DATES[i]); 1074 int year = calendar.get(YEAR); 1075 int maxYear = calendar.getMaximum(YEAR); 1076 if (year > maxYear) { 1077 errln("Failed for " + DATES[i].getTime() + " ms: year=" 1078 + year + ", maxYear=" + maxYear); 1079 } 1080 } 1081 } 1082 1083 /** 1084 * This is a bug in the validation code of GregorianCalendar. As reported, 1085 * the bug seems worse than it really is, due to a bug in the way the bug 1086 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR 1087 * field. - liu 6/29/98 1088 */ 1089 public void Test4147269() { 1090 final String[] fieldName = { 1091 "ERA", 1092 "YEAR", 1093 "MONTH", 1094 "WEEK_OF_YEAR", 1095 "WEEK_OF_MONTH", 1096 "DAY_OF_MONTH", 1097 "DAY_OF_YEAR", 1098 "DAY_OF_WEEK", 1099 "DAY_OF_WEEK_IN_MONTH", 1100 "AM_PM", 1101 "HOUR", 1102 "HOUR_OF_DAY", 1103 "MINUTE", 1104 "SECOND", 1105 "MILLISECOND", 1106 "ZONE_OFFSET", 1107 "DST_OFFSET"}; 1108 GregorianCalendar calendar = new GregorianCalendar(); 1109 calendar.setLenient(false); 1110 @SuppressWarnings("deprecation") 1111 Date date = new Date(1996 - 1900, JANUARY, 3); // Arbitrary date 1112 for (int field = 0; field < FIELD_COUNT; field++) { 1113 calendar.setTime(date); 1114 // Note: In the bug report, getActualMaximum() was called instead 1115 // of getMaximum() -- this was an error. The validation code doesn't 1116 // use getActualMaximum(), since that's too costly. 1117 int max = calendar.getMaximum(field); 1118 int value = max + 1; 1119 calendar.set(field, value); 1120 try { 1121 calendar.getTime(); // Force time computation 1122 // We expect an exception to be thrown. If we fall through 1123 // to the next line, then we have a bug. 1124 errln("Test failed with field " + fieldName[field] 1125 + ", date before: " + date 1126 + ", date after: " + calendar.getTime() 1127 + ", value: " + value + " (max = " + max + ")"); 1128 } catch (IllegalArgumentException e) { 1129 } 1130 } 1131 } 1132 1133 /** 1134 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE) 1135 * doesn't behave as a pure Julian calendar. 1136 * CANNOT REPRODUCE THIS BUG 1137 */ 1138 public void Test4149677() { 1139 TimeZone[] zones = {TimeZone.getTimeZone("GMT"), 1140 TimeZone.getTimeZone("PST"), 1141 TimeZone.getTimeZone("EAT")}; 1142 for (int i = 0; i < zones.length; ++i) { 1143 GregorianCalendar calendar = new GregorianCalendar(zones[i]); 1144 1145 // Make sure extreme values don't wrap around 1146 calendar.setTime(new Date(Long.MIN_VALUE)); 1147 if (calendar.get(ERA) != GregorianCalendar.BC) { 1148 errln("Fail: Date(Long.MIN_VALUE) has an AD year in " + zones[i]); 1149 } 1150 calendar.setTime(new Date(Long.MAX_VALUE)); 1151 if (calendar.get(ERA) != GregorianCalendar.AD) { 1152 errln("Fail: Date(Long.MAX_VALUE) has a BC year in " + zones[i]); 1153 } 1154 1155 calendar.setGregorianChange(new Date(Long.MAX_VALUE)); 1156 // to obtain a pure Julian calendar 1157 1158 boolean is100Leap = calendar.isLeapYear(100); 1159 if (!is100Leap) { 1160 errln("test failed with zone " + zones[i].getID()); 1161 errln(" cutover date is Date(Long.MAX_VALUE)"); 1162 errln(" isLeapYear(100) returns: " + is100Leap); 1163 } 1164 } 1165 } 1166 1167 /** 1168 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar 1169 * and Date classes will misbehave. 1170 */ 1171 public void Test4162587() { 1172 TimeZone savedTz = TimeZone.getDefault(); 1173 TimeZone tz = TimeZone.getTimeZone("PST"); 1174 TimeZone.setDefault(tz); 1175 GregorianCalendar cal = new GregorianCalendar(tz); 1176 Date d; 1177 1178 try { 1179 for (int i = 0; i < 5; ++i) { 1180 if (i > 0) { 1181 logln("---"); 1182 } 1183 1184 cal.clear(); 1185 cal.set(1998, APRIL, 5, i, 0); 1186 d = cal.getTime(); 1187 String s0 = d.toString(); 1188 logln("0 " + i + ": " + s0); 1189 1190 cal.clear(); 1191 cal.set(1998, APRIL, 4, i + 24, 0); 1192 d = cal.getTime(); 1193 String sPlus = d.toString(); 1194 logln("+ " + i + ": " + sPlus); 1195 1196 cal.clear(); 1197 cal.set(1998, APRIL, 6, i - 24, 0); 1198 d = cal.getTime(); 1199 String sMinus = d.toString(); 1200 logln("- " + i + ": " + sMinus); 1201 1202 if (!s0.equals(sPlus) || !s0.equals(sMinus)) { 1203 errln("Fail: All three lines must match"); 1204 } 1205 } 1206 } finally { 1207 TimeZone.setDefault(savedTz); 1208 } 1209 } 1210 1211 /** 1212 * Adding 12 months behaves differently from adding 1 year 1213 */ 1214 public void Test4165343() { 1215 GregorianCalendar calendar = new GregorianCalendar(1996, FEBRUARY, 29); 1216 Date start = calendar.getTime(); 1217 logln("init date: " + start); 1218 calendar.add(MONTH, 12); 1219 Date date1 = calendar.getTime(); 1220 logln("after adding 12 months: " + date1); 1221 calendar.setTime(start); 1222 calendar.add(YEAR, 1); 1223 Date date2 = calendar.getTime(); 1224 logln("after adding one year : " + date2); 1225 if (date1.equals(date2)) { 1226 logln("Test passed"); 1227 } else { 1228 errln("Test failed"); 1229 } 1230 } 1231 1232 /** 1233 * GregorianCalendar.getActualMaximum() does not account for first day of week. 1234 */ 1235 public void Test4166109() { 1236 /* Test month: 1237 * 1238 * March 1998 1239 * Su Mo Tu We Th Fr Sa 1240 * 1 2 3 4 5 6 7 1241 * 8 9 10 11 12 13 14 1242 * 15 16 17 18 19 20 21 1243 * 22 23 24 25 26 27 28 1244 * 29 30 31 1245 */ 1246 boolean passed = true; 1247 int field = WEEK_OF_MONTH; 1248 1249 GregorianCalendar calendar = new GregorianCalendar(Locale.US); 1250 calendar.set(1998, MARCH, 1); 1251 calendar.setMinimalDaysInFirstWeek(1); 1252 logln("Date: " + calendar.getTime()); 1253 1254 int firstInMonth = calendar.get(DAY_OF_MONTH); 1255 1256 for (int firstInWeek = SUNDAY; firstInWeek <= SATURDAY; firstInWeek++) { 1257 calendar.setFirstDayOfWeek(firstInWeek); 1258 int returned = calendar.getActualMaximum(field); 1259 int expected = (31 + ((firstInMonth - firstInWeek + 7) % 7) + 6) / 7; 1260 1261 logln("First day of week = " + firstInWeek 1262 + " getActualMaximum(WEEK_OF_MONTH) = " + returned 1263 + " expected = " + expected 1264 + ((returned == expected) ? " ok" : " FAIL")); 1265 1266 if (returned != expected) { 1267 passed = false; 1268 } 1269 } 1270 if (!passed) { 1271 errln("Test failed"); 1272 } 1273 } 1274 1275 /** 1276 * Calendar.getActualMaximum(YEAR) works wrong. 1277 * 1278 * Note: Before 1.5, this test case assumed that 1279 * setGregorianChange didn't change object's date. But it was 1280 * changed. See 4928615. 1281 */ 1282 public void Test4167060() { 1283 int field = YEAR; 1284 DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy G", 1285 Locale.US); 1286 1287 int[][] dates = { 1288 // year, month, day of month 1289 {100, NOVEMBER, 1}, 1290 {-99 /*100BC*/, JANUARY, 1}, 1291 {1996, FEBRUARY, 29}}; 1292 1293 String[] id = {"Hybrid", "Gregorian", "Julian"}; 1294 1295 for (int k = 0; k < 3; ++k) { 1296 logln("--- " + id[k] + " ---"); 1297 1298 for (int j = 0; j < dates.length; ++j) { 1299 GregorianCalendar calendar = new GregorianCalendar(); 1300 if (k == 1) { 1301 calendar.setGregorianChange(new Date(Long.MIN_VALUE)); 1302 } else if (k == 2) { 1303 calendar.setGregorianChange(new Date(Long.MAX_VALUE)); 1304 } 1305 calendar.set(dates[j][0], dates[j][1], dates[j][2]); 1306 format.setCalendar((Calendar) calendar.clone()); 1307 1308 Date dateBefore = calendar.getTime(); 1309 1310 int maxYear = calendar.getActualMaximum(field); 1311 logln("maxYear: " + maxYear + " for " + format.format(calendar.getTime())); 1312 logln("date before: " + format.format(dateBefore)); 1313 1314 int[] years = {2000, maxYear - 1, maxYear, maxYear + 1}; 1315 1316 for (int i = 0; i < years.length; i++) { 1317 boolean valid = years[i] <= maxYear; 1318 calendar.set(field, years[i]); 1319 Date dateAfter = calendar.getTime(); 1320 int newYear = calendar.get(field); 1321 calendar.setTime(dateBefore); // restore calendar for next use 1322 1323 logln(" Year " + years[i] + (valid ? " ok " : " bad") 1324 + " => " + format.format(dateAfter)); 1325 if (valid && newYear != years[i]) { 1326 errln(" FAIL: " + newYear + " should be valid; date, month and time shouldn't change"); 1327 } else if (!valid && newYear == years[i]) { 1328 errln(" FAIL: " + newYear + " should be invalid"); 1329 } 1330 } 1331 } 1332 } 1333 } 1334 1335 /** 1336 * Calendar.roll broken 1337 * This bug relies on the TimeZone bug 4173604 to also be fixed. 1338 */ 1339 public void Test4173516() { 1340 Locale locale = Locale.getDefault(); 1341 if (!TestUtils.usesGregorianCalendar(locale)) { 1342 logln("Skipping this test because locale is " + locale); 1343 return; 1344 } 1345 1346 int[][] fieldsList = { 1347 {1997, FEBRUARY, 1, 10, 45, 15, 900}, 1348 {1999, DECEMBER, 22, 23, 59, 59, 999}, 1349 // test case for 4960642 with default cutover 1350 {1582, OCTOBER, 4, 23, 59, 59, 999}}; 1351 String[] fieldNames = { 1352 "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", 1353 "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", 1354 "AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", 1355 "ZONE_OFFSET", "DST_OFFSET"}; 1356 1357 Locale savedLocale = Locale.getDefault(); 1358 Locale.setDefault(Locale.US); 1359 int limit = 40; 1360 1361 try { 1362 GregorianCalendar cal = new GregorianCalendar(); 1363 1364 cal.setTime(new Date(0)); 1365 cal.roll(HOUR, 0x7F000000); 1366 cal.roll(HOUR, -0x7F000000); 1367 if (cal.getTime().getTime() != 0) { 1368 errln("Hour rolling broken. expected 0, got " + cal.getTime().getTime()); 1369 } 1370 1371 for (int op = 0; op < 2; ++op) { 1372 logln("Testing GregorianCalendar " + (op == 0 ? "add" : "roll")); 1373 1374 for (int field = 0; field < FIELD_COUNT; ++field) { 1375 if (field != ZONE_OFFSET 1376 && field != DST_OFFSET) { 1377 for (int j = 0; j < fieldsList.length; ++j) { 1378 int[] fields = fieldsList[j]; 1379 cal.clear(); 1380 cal.set(fields[0], fields[1], fields[2], 1381 fields[3], fields[4], fields[5]); 1382 cal.set(MILLISECOND, fields[6]); 1383 for (int i = 0; i < 2 * limit; i++) { 1384 if (op == 0) { 1385 cal.add(field, i < limit ? 1 : -1); 1386 } else { 1387 cal.roll(field, i < limit ? 1 : -1); 1388 } 1389 } 1390 1391 if (cal.get(YEAR) != fields[0] 1392 || cal.get(MONTH) != fields[1] 1393 || cal.get(DATE) != fields[2] 1394 || cal.get(HOUR_OF_DAY) != fields[3] 1395 || cal.get(MINUTE) != fields[4] 1396 || cal.get(SECOND) != fields[5] 1397 || cal.get(MILLISECOND) != fields[6]) { 1398 errln("Field " + field 1399 + " (" + fieldNames[field] 1400 + ") FAIL, expected " 1401 + fields[0] 1402 + "/" + (fields[1] + 1) 1403 + "/" + fields[2] 1404 + " " + fields[3] 1405 + ":" + fields[4] 1406 + ":" + fields[5] 1407 + "." + fields[6] 1408 + ", got " + cal.get(YEAR) 1409 + "/" + (cal.get(MONTH) + 1) 1410 + "/" + cal.get(DATE) 1411 + " " + cal.get(HOUR_OF_DAY) 1412 + ":" + cal.get(MINUTE) 1413 + ":" + cal.get(SECOND) 1414 + "." + cal.get(MILLISECOND)); 1415 1416 cal.clear(); 1417 cal.set(fields[0], fields[1], fields[2], 1418 fields[3], fields[4], fields[5]); 1419 cal.set(MILLISECOND, fields[6]); 1420 errln(cal.get(YEAR) 1421 + "/" + (cal.get(MONTH) + 1) 1422 + "/" + cal.get(DATE) 1423 + " " + cal.get(HOUR_OF_DAY) 1424 + ":" + cal.get(MINUTE) 1425 + ":" + cal.get(SECOND) 1426 + "." + cal.get(MILLISECOND)); 1427 1428 long prev = cal.getTime().getTime(); 1429 for (int i = 0; i < 2 * limit; i++) { 1430 if (op == 0) { 1431 cal.add(field, i < limit ? 1 : -1); 1432 } else { 1433 cal.roll(field, i < limit ? 1 : -1); 1434 } 1435 long t = cal.getTime().getTime(); 1436 long delta = t - prev; 1437 prev = t; 1438 errln((op == 0 ? "add(" : "roll(") 1439 + fieldNames[field] + ", " 1440 + (i < limit ? "+" : "-") + "1) => " 1441 + cal.get(YEAR) 1442 + "/" + (cal.get(MONTH) + 1) 1443 + "/" + cal.get(DATE) 1444 + " " + cal.get(HOUR_OF_DAY) 1445 + ":" + cal.get(MINUTE) 1446 + ":" + cal.get(SECOND) 1447 + "." + cal.get(MILLISECOND) 1448 + " d=" + delta); 1449 } 1450 } 1451 } 1452 } 1453 } 1454 } 1455 } finally { 1456 Locale.setDefault(savedLocale); 1457 } 1458 } 1459 1460 public void Test4174361() { 1461 GregorianCalendar calendar = new GregorianCalendar(1996, 1, 29); 1462 1463 calendar.add(MONTH, 10); 1464 Date date1 = calendar.getTime(); 1465 int d1 = calendar.get(DAY_OF_MONTH); 1466 1467 calendar = new GregorianCalendar(1996, 1, 29); 1468 calendar.add(MONTH, 11); 1469 Date date2 = calendar.getTime(); 1470 int d2 = calendar.get(DAY_OF_MONTH); 1471 1472 if (d1 != d2) { 1473 errln("adding months to Feb 29 broken"); 1474 } 1475 } 1476 1477 /** 1478 * Calendar does not update field values when setTimeZone is called. 1479 */ 1480 public void Test4177484() { 1481 TimeZone PST = TimeZone.getTimeZone("PST"); 1482 TimeZone EST = TimeZone.getTimeZone("EST"); 1483 1484 Calendar cal = Calendar.getInstance(PST, Locale.US); 1485 cal.clear(); 1486 cal.set(1999, 3, 21, 15, 5, 0); // Arbitrary 1487 int h1 = cal.get(HOUR_OF_DAY); 1488 cal.setTimeZone(EST); 1489 int h2 = cal.get(HOUR_OF_DAY); 1490 if (h1 == h2) { 1491 errln("FAIL: Fields not updated after setTimeZone"); 1492 } 1493 1494 // getTime() must NOT change when time zone is changed. 1495 // getTime() returns zone-independent time in ms. 1496 cal.clear(); 1497 cal.setTimeZone(PST); 1498 cal.set(HOUR_OF_DAY, 10); 1499 Date pst10 = cal.getTime(); 1500 cal.setTimeZone(EST); 1501 Date est10 = cal.getTime(); 1502 if (!pst10.equals(est10)) { 1503 errln("FAIL: setTimeZone changed time"); 1504 } 1505 } 1506 1507 /** 1508 * Week of year is wrong at the start and end of the year. 1509 */ 1510 public void Test4197699() { 1511 GregorianCalendar cal = new GregorianCalendar(); 1512 cal.setFirstDayOfWeek(MONDAY); 1513 cal.setMinimalDaysInFirstWeek(4); 1514 DateFormat fmt = new SimpleDateFormat("E dd MMM yyyy 'DOY='D 'WOY='w"); 1515 fmt.setCalendar(cal); 1516 1517 int[] DATA = { 1518 2000, JANUARY, 1, 52, 1519 2001, DECEMBER, 31, 1}; 1520 1521 for (int i = 0; i < DATA.length;) { 1522 cal.set(DATA[i++], DATA[i++], DATA[i++]); 1523 int expWOY = DATA[i++]; 1524 int actWOY = cal.get(WEEK_OF_YEAR); 1525 if (expWOY == actWOY) { 1526 logln("Ok: " + fmt.format(cal.getTime())); 1527 } else { 1528 errln("FAIL: " + fmt.format(cal.getTime()) 1529 + ", expected WOY=" + expWOY); 1530 cal.add(DATE, -8); 1531 for (int j = 0; j < 14; ++j) { 1532 cal.add(DATE, 1); 1533 logln(fmt.format(cal.getTime())); 1534 } 1535 } 1536 } 1537 } 1538 1539 /** 1540 * Calendar DAY_OF_WEEK_IN_MONTH fields->time broken. The problem 1541 * is in the field disambiguation code in GregorianCalendar. This 1542 * code is supposed to choose the most recent set of fields 1543 * among the following: 1544 * 1545 * MONTH + DAY_OF_MONTH 1546 * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK 1547 * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK 1548 * DAY_OF_YEAR 1549 * WEEK_OF_YEAR + DAY_OF_WEEK 1550 */ 1551 @SuppressWarnings("deprecation") 1552 public void Test4209071() { 1553 Calendar cal = Calendar.getInstance(Locale.US); 1554 1555 // General field setting test 1556 int Y = 1995 - 1900; 1557 1558 Object[] FIELD_DATA = { 1559 // Add new test cases as needed. 1560 1561 // 0 1562 new int[]{}, new Date(Y, JANUARY, 1), 1563 // 1 1564 new int[]{MONTH, MARCH}, 1565 new Date(Y, MARCH, 1), 1566 // 2 1567 new int[]{DAY_OF_WEEK, WEDNESDAY}, 1568 new Date(Y, JANUARY, 4), 1569 // 3 1570 new int[]{DAY_OF_WEEK, THURSDAY, 1571 DAY_OF_MONTH, 18,}, 1572 new Date(Y, JANUARY, 18), 1573 // 4 1574 new int[]{DAY_OF_MONTH, 18, 1575 DAY_OF_WEEK, THURSDAY,}, 1576 new Date(Y, JANUARY, 18), 1577 // 5 (WOM -1 is in previous month) 1578 new int[]{DAY_OF_MONTH, 18, 1579 WEEK_OF_MONTH, -1, 1580 DAY_OF_WEEK, THURSDAY,}, 1581 new Date(Y - 1, DECEMBER, 22), 1582 // 6 1583 new int[]{DAY_OF_MONTH, 18, 1584 WEEK_OF_MONTH, 4, 1585 DAY_OF_WEEK, THURSDAY,}, 1586 new Date(Y, JANUARY, 26), 1587 // 7 (DIM -1 is in same month) 1588 new int[]{DAY_OF_MONTH, 18, 1589 DAY_OF_WEEK_IN_MONTH, -1, 1590 DAY_OF_WEEK, THURSDAY,}, 1591 new Date(Y, JANUARY, 26), 1592 // 8 1593 new int[]{WEEK_OF_YEAR, 9, 1594 DAY_OF_WEEK, WEDNESDAY,}, 1595 new Date(Y, MARCH, 1), 1596 // 9 1597 new int[]{MONTH, OCTOBER, 1598 DAY_OF_WEEK_IN_MONTH, 1, 1599 DAY_OF_WEEK, FRIDAY,}, 1600 new Date(Y, OCTOBER, 6), 1601 // 10 1602 new int[]{MONTH, OCTOBER, 1603 WEEK_OF_MONTH, 2, 1604 DAY_OF_WEEK, FRIDAY,}, 1605 new Date(Y, OCTOBER, 13), 1606 // 11 1607 new int[]{MONTH, OCTOBER, 1608 DAY_OF_MONTH, 15, 1609 DAY_OF_YEAR, 222,}, 1610 new Date(Y, AUGUST, 10), 1611 // 12 1612 new int[]{DAY_OF_WEEK, THURSDAY, 1613 MONTH, DECEMBER,}, 1614 new Date(Y, DECEMBER, 7)}; 1615 1616 for (int i = 0; i < FIELD_DATA.length; i += 2) { 1617 int[] fields = (int[]) FIELD_DATA[i]; 1618 Date exp = (Date) FIELD_DATA[i + 1]; 1619 1620 cal.clear(); 1621 cal.set(YEAR, Y + 1900); 1622 for (int j = 0; j < fields.length; j += 2) { 1623 cal.set(fields[j], fields[j + 1]); 1624 } 1625 1626 Date act = cal.getTime(); 1627 if (!act.equals(exp)) { 1628 errln("FAIL: Test " + (i / 2) + " got " + act 1629 + ", want " + exp 1630 + " (see test/java/util/Calendar/CalendarRegression.java"); 1631 } 1632 } 1633 1634 // Test specific failure reported in bug 1635 @SuppressWarnings("deprecation") 1636 Object[] DATA = { 1637 1, new Date(1997 - 1900, JANUARY, 5), 1638 4, new Date(1997 - 1900, JANUARY, 26), 1639 8, new Date(1997 - 1900, FEBRUARY, 23), 1640 -1, new Date(1997 - 1900, JANUARY, 26), 1641 -4, new Date(1997 - 1900, JANUARY, 5), 1642 -8, new Date(1996 - 1900, DECEMBER, 8)}; 1643 for (int i = 0; i < DATA.length; i += 2) { 1644 cal.clear(); 1645 cal.set(DAY_OF_WEEK_IN_MONTH, 1646 ((Number) DATA[i]).intValue()); 1647 cal.set(DAY_OF_WEEK, SUNDAY); 1648 cal.set(MONTH, JANUARY); 1649 cal.set(YEAR, 1997); 1650 Date actual = cal.getTime(); 1651 if (!actual.equals(DATA[i + 1])) { 1652 errln("FAIL: Sunday " + DATA[i] 1653 + " of Jan 1997 -> " + actual 1654 + ", want " + DATA[i + 1]); 1655 } 1656 } 1657 } 1658 1659 public void Test4288792() throws Exception { 1660 TimeZone savedTZ = TimeZone.getDefault(); 1661 TimeZone.setDefault(TimeZone.getTimeZone("GMT")); 1662 GregorianCalendar cal = new GregorianCalendar(); 1663 try { 1664 for (int i = 1900; i < 2100; i++) { 1665 for (int j1 = 1; j1 <= 7; j1++) { 1666 // Loop for MinimalDaysInFirstWeek: 1..7 1667 for (int j = SUNDAY; j <= SATURDAY; j++) { 1668 // Loop for FirstDayOfWeek: SUNDAY..SATURDAY 1669 cal.clear(); 1670 cal.setMinimalDaysInFirstWeek(j1); 1671 cal.setFirstDayOfWeek(j); 1672 cal.set(YEAR, i); 1673 int maxWeek = cal.getActualMaximum(WEEK_OF_YEAR); 1674 cal.set(WEEK_OF_YEAR, maxWeek); 1675 cal.set(DAY_OF_WEEK, j); 1676 1677 for (int k = 1; k < 7; k++) { 1678 cal.add(DATE, 1); 1679 int WOY = cal.get(WEEK_OF_YEAR); 1680 if (WOY != maxWeek) { 1681 errln(cal.getTime() + ",got=" + WOY 1682 + ",expected=" + maxWeek 1683 + ",min=" + j1 + ",first=" + j); 1684 } 1685 } 1686 1687 cal.add(DATE, 1); 1688 int WOY = cal.get(WEEK_OF_YEAR); 1689 if (WOY != 1) { 1690 errln(cal.getTime() + ",got=" + WOY 1691 + ",expected=1,min=" + j1 + ",first" + j); 1692 } 1693 } 1694 } 1695 } 1696 } finally { 1697 TimeZone.setDefault(savedTZ); 1698 } 1699 } 1700 1701 public void Test4328747() throws Exception { 1702 Calendar c = Calendar.getInstance(Locale.US); 1703 c.clear(); 1704 c.set(1966, 0, 1); // 1 jan 1966 1705 1706 // serialize 1707 ByteArrayOutputStream out = new ByteArrayOutputStream(); 1708 ObjectOutputStream s = new ObjectOutputStream(out); 1709 s.writeObject(c); 1710 s.flush(); 1711 1712 // deserialize 1713 ObjectInputStream t = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); 1714 Calendar result = (Calendar) t.readObject(); 1715 1716 // let recalculate fields with the same UTC time 1717 result.setTime(result.getTime()); 1718 // Bug gives 1965 11 19 1719 if ((result.get(YEAR) != 1966) || (result.get(MONTH) != 0) 1720 || (result.get(DATE) != 1)) { 1721 errln("deserialized Calendar returned wrong date field(s): " 1722 + result.get(YEAR) + "/" + result.get(MONTH) + "/" + result.get(DATE) 1723 + ", expected 1966/0/1"); 1724 } 1725 } 1726 1727 /** 1728 * Test whether Calendar can be serialized/deserialized correctly 1729 * even if invalid/customized TimeZone is used. 1730 */ 1731 public void Test4413980() { 1732 TimeZone savedTimeZone = TimeZone.getDefault(); 1733 try { 1734 boolean pass = true; 1735 String[] IDs = new String[]{"Undefined", "PST", "US/Pacific", 1736 "GMT+3:00", "GMT-01:30"}; 1737 for (int i = 0; i < IDs.length; i++) { 1738 TimeZone tz = TimeZone.getTimeZone(IDs[i]); 1739 TimeZone.setDefault(tz); 1740 1741 Calendar c = Calendar.getInstance(); 1742 1743 // serialize 1744 ByteArrayOutputStream out = new ByteArrayOutputStream(); 1745 ObjectOutputStream s = new ObjectOutputStream(out); 1746 s.writeObject(c); 1747 s.flush(); 1748 1749 // deserialize 1750 ObjectInputStream t = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); 1751 1752 if (!c.equals(t.readObject())) { 1753 pass = false; 1754 logln("Calendar instance which uses TimeZone <" 1755 + IDs[i] + "> is incorrectly serialized/deserialized."); 1756 } else { 1757 logln("Calendar instance which uses TimeZone <" 1758 + IDs[i] + "> is correctly serialized/deserialized."); 1759 } 1760 } 1761 if (!pass) { 1762 errln("Fail: Calendar serialization/equality bug"); 1763 } 1764 } catch (IOException | ClassNotFoundException e) { 1765 errln("Fail: " + e); 1766 e.printStackTrace(); 1767 } finally { 1768 TimeZone.setDefault(savedTimeZone); 1769 } 1770 } 1771 1772 /** 1773 * 4546637: Incorrect WEEK_OF_MONTH after changing First Day Of Week 1774 */ 1775 public void Test4546637() { 1776 GregorianCalendar day = new GregorianCalendar(2001, NOVEMBER, 04); 1777 day.setMinimalDaysInFirstWeek(1); 1778 int wom = day.get(WEEK_OF_MONTH); 1779 1780 day.setFirstDayOfWeek(MONDAY); 1781 if (day.get(WEEK_OF_MONTH) != 1) { 1782 errln("Fail: 2001/11/4 must be the first week of the month."); 1783 } 1784 } 1785 1786 /** 1787 * 4623997: GregorianCalendar returns bad WEEK_OF_YEAR 1788 */ 1789 public void Test4623997() { 1790 GregorianCalendar cal = new GregorianCalendar(2000, JANUARY, 1); 1791 1792 int dow = cal.get(DAY_OF_WEEK); 1793 1794 cal.setFirstDayOfWeek(MONDAY); 1795 cal.setMinimalDaysInFirstWeek(4); 1796 1797 if (cal.get(WEEK_OF_YEAR) != 52) { 1798 errln("Fail: 2000/1/1 must be the 52nd week of the year."); 1799 } 1800 } 1801 1802 /** 1803 * 4685354: Handling of Calendar fields setting state is broken 1804 * 1805 * <p>Need to use SimpleDateFormat to test because a call to 1806 * get(int) changes internal states of a Calendar. 1807 */ 1808 public void Test4685354() { 1809 Locale locale = Locale.getDefault(); 1810 if (!TestUtils.usesAsciiDigits(locale) 1811 || !TestUtils.usesGregorianCalendar(locale)) { 1812 logln("Skipping this test because locale is " + locale); 1813 return; 1814 } 1815 1816 Calendar calendar = Calendar.getInstance(Locale.US); 1817 DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US); 1818 String expected = "1999/12/31"; 1819 Date t; 1820 String s; 1821 1822 try { 1823 calendar.setTime(df.parse(expected)); 1824 } catch (Exception e) { 1825 throw new RuntimeException("Unexpected parse exception", e); 1826 } 1827 1828 t = calendar.getTime(); 1829 calendar.set(DAY_OF_MONTH, 33); 1830 t = calendar.getTime(); 1831 calendar.set(DAY_OF_MONTH, 0); 1832 s = df.format(calendar.getTime()); 1833 if (!expected.equals(s)) { 1834 errln("DAY_OF_MONTH w/o ZONE_OFFSET: expected: " + expected + ", got: " + s); 1835 } 1836 1837 // The same thing must work with ZONE_OFFSET set 1838 try { 1839 calendar.setTime(df.parse(expected)); 1840 } catch (Exception e) { 1841 throw new RuntimeException("Unexpected parse exception", e); 1842 } 1843 t = calendar.getTime(); 1844 calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET)); 1845 calendar.set(DAY_OF_MONTH, 33); 1846 t = calendar.getTime(); 1847 calendar.set(DAY_OF_MONTH, 0); 1848 s = df.format(calendar.getTime()); 1849 if (!expected.equals(s)) { 1850 errln("DAY_OF_MONTH: expected: " + expected + ", got: " + s); 1851 } 1852 1853 expected = "1999/12/24"; // 0th week of 2000 1854 calendar.clear(); 1855 Date initialDate = null; 1856 try { 1857 initialDate = df.parse(expected); 1858 calendar.setTime(initialDate); 1859 } catch (Exception e) { 1860 throw new RuntimeException("Unexpected parse exception", e); 1861 } 1862 t = calendar.getTime(); 1863 calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET)); 1864 // jump to the next year 1865 calendar.set(WEEK_OF_YEAR, 100); 1866 t = calendar.getTime(); 1867 calendar.set(WEEK_OF_YEAR, 0); 1868 s = df.format(calendar.getTime()); 1869 if (!expected.equals(s)) { 1870 errln("WEEK_OF_YEAR: expected: " + expected + ", got: " + s); 1871 } 1872 // change the state back 1873 calendar.clear(); 1874 calendar.setTime(initialDate); 1875 calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET)); 1876 // jump to next month 1877 calendar.set(WEEK_OF_MONTH, 7); 1878 t = calendar.getTime(); 1879 calendar.set(WEEK_OF_MONTH, 0); 1880 s = df.format(calendar.getTime()); 1881 if (!expected.equals(s)) { 1882 errln("WEEK_OF_MONTH: expected: " + expected + ", got: " + s); 1883 } 1884 1885 // Make sure the time fields work correctly. 1886 calendar.clear(); 1887 df = new SimpleDateFormat("HH:mm:ss"); 1888 TimeZone tz = TimeZone.getTimeZone("GMT"); 1889 df.setTimeZone(tz); 1890 calendar.setTimeZone(tz); 1891 expected = "22:59:59"; 1892 try { 1893 calendar.setTime(df.parse(expected)); 1894 } catch (Exception e) { 1895 throw new RuntimeException("Unexpected parse exception", e); 1896 } 1897 t = calendar.getTime(); 1898 // time should be 22:59:59. 1899 calendar.set(MINUTE, 61); 1900 // time should be 23:01:59. 1901 t = calendar.getTime(); 1902 calendar.set(MINUTE, -1); 1903 // time should be back to 22:59:59. 1904 s = df.format(calendar.getTime()); 1905 if (!expected.equals(s)) { 1906 errln("MINUTE: expected: " + expected + ", got: " + s); 1907 } 1908 } 1909 1910 /** 1911 * 4655637: Calendar.set() for DAY_OF_WEEK does not return the right value 1912 * 1913 * <p>Need to use SimpleDateFormat to test because a call to 1914 * get(int) changes internal states of a Calendar. 1915 */ 1916 public void Test4655637() { 1917 Locale locale = Locale.getDefault(); 1918 if (!TestUtils.usesGregorianCalendar(locale)) { 1919 logln("Skipping this test because locale is " + locale); 1920 return; 1921 } 1922 1923 Calendar cal = Calendar.getInstance(); 1924 cal.setTime(new Date(1029814211523L)); 1925 cal.set(YEAR, 2001); 1926 Date t = cal.getTime(); 1927 cal.set(MONTH, JANUARY); 1928 t = cal.getTime(); 1929 1930 cal.set(DAY_OF_MONTH, 8); 1931 t = cal.getTime(); 1932 1933 cal.set(DAY_OF_WEEK, MONDAY); 1934 DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US); 1935 String expected = "2001/01/08"; 1936 String s = df.format(cal.getTime()); 1937 if (!expected.equals(s)) { 1938 errln("expected: " + expected + ", got: " + s); 1939 } 1940 } 1941 1942 /** 1943 * 4683492: Invalid value for MONTH in GregorianCalendar causes exception in getTime(). 1944 * 1945 * <p>Need to use SimpleDateFormat to test because a call to 1946 * get(int) changes internal states of a Calendar. 1947 * 1948 * <p>This test case throws ArrayIndexOutOfBoundsException without the fix. 1949 */ 1950 public void Test4683492() { 1951 Calendar cal = new GregorianCalendar(2002, 3, 29, 10, 0, 0); 1952 cal.set(DAY_OF_WEEK, FRIDAY); 1953 cal.set(DAY_OF_WEEK_IN_MONTH, -1); 1954 cal.set(MONTH, 12); 1955 DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US); 1956 String expected = "2003/01/31"; 1957 String s = df.format(cal.getTime()); 1958 if (!expected.equals(s)) { 1959 errln("expected: " + expected + ", got: " + s); 1960 } 1961 } 1962 1963 /** 1964 * 4080631: Calendar.hashCode is amazingly bad 1965 */ 1966 public void Test4080631() { 1967 Calendar cal = Calendar.getInstance(); 1968 int h1 = cal.hashCode(); 1969 cal.add(SECOND, +1); 1970 int h2 = cal.hashCode(); 1971 Calendar cal2 = (Calendar) cal.clone(); 1972 cal.add(MILLISECOND, +1); 1973 int h3 = cal.hashCode(); 1974 logln("hash code: h1=" + h1 + ", h2=" + h2 + ", h3=" + h3); 1975 if (h1 == h2 || h1 == h3 || h2 == h3) { 1976 errln("hash code is poor: hashCode=" + h1); 1977 } 1978 h2 = cal2.hashCode(); 1979 cal.add(MILLISECOND, -1); 1980 int h4 = cal.hashCode(); 1981 logln("hash code: h2=" + h2 + ", h4=" + h4); 1982 if (cal.equals(cal2) && h2 != h4) { 1983 errln("broken hash code: h2=" + h2 + ", h4=" + h4); 1984 } 1985 int x = cal.getFirstDayOfWeek() + 3; 1986 if (x > SATURDAY) { 1987 x -= 7; 1988 } 1989 cal.setFirstDayOfWeek(x); 1990 int h5 = cal.hashCode(); 1991 logln("hash code: h4=" + h4 + ", h5=" + h5); 1992 if (h4 == h5) { 1993 errln("has code is poor with first day of week param: hashCode=" + h4); 1994 } 1995 } 1996 1997 /** 1998 * 4125161: RFE: GregorianCalendar needs more era names (BCE and CE) 1999 */ 2000 /* 2001 public void Test4125161() throws Exception { 2002 Class gc = GregorianCalendar.class; 2003 Field f; 2004 int mod; 2005 f = gc.getDeclaredField("BCE"); 2006 mod = f.getModifiers(); 2007 if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) { 2008 errln("BCE: wrong modifiers: " + mod); 2009 } 2010 f = gc.getDeclaredField("CE"); 2011 mod = f.getModifiers(); 2012 if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) { 2013 errln("CE: wrong modifiers: " + mod); 2014 } 2015 if (GregorianCalendar.BCE != GregorianCalendar.BC 2016 || GregorianCalendar.CE != GregorianCalendar.AD) { 2017 errln("Wrong BCE and/or CE values"); 2018 } 2019 } 2020 */ 2021 /** 2022 * 4167995: GregorianCalendar.setGregorianChange() not to spec 2023 */ 2024 public void Test4167995() { 2025 Koyomi gc = new Koyomi(TimeZone.getTimeZone("GMT")); 2026 logln("Hybrid: min date"); 2027 gc.setTime(new Date(Long.MIN_VALUE)); 2028 if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY) 2029 || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) { 2030 errln(gc.getMessage()); 2031 } 2032 logln("Hybrid: max date"); 2033 gc.setTime(new Date(Long.MAX_VALUE)); 2034 if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY) 2035 || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) { 2036 errln(gc.getMessage()); 2037 } 2038 2039 gc.setGregorianChange(new Date(Long.MIN_VALUE)); 2040 logln("Gregorian: min date"); 2041 gc.setTime(new Date(Long.MIN_VALUE)); 2042 if (!gc.checkDate(292275056, MAY, 16, SUNDAY) 2043 || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) { 2044 errln(gc.getMessage()); 2045 } 2046 logln("Gregorian: max date"); 2047 gc.setTime(new Date(Long.MAX_VALUE)); 2048 if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY) 2049 || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) { 2050 errln(gc.getMessage()); 2051 } 2052 2053 gc.setGregorianChange(new Date(Long.MAX_VALUE)); 2054 logln("Julian: min date"); 2055 gc.setTime(new Date(Long.MIN_VALUE)); 2056 if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY) 2057 || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) { 2058 errln(gc.getMessage()); 2059 } 2060 logln("Julian: max date"); 2061 gc.setTime(new Date(Long.MAX_VALUE)); 2062 if (!gc.checkDate(292272993, JANUARY, 4, SUNDAY) 2063 || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) { 2064 errln(gc.getMessage()); 2065 } 2066 } 2067 2068 /** 2069 * 4340146: Calendar.equals modifies state 2070 */ 2071 public void Test4340146() { 2072 Koyomi cal = new Koyomi(); 2073 cal.clear(); 2074 cal.set(2003, OCTOBER, 32); 2075 cal.equals(new Koyomi()); 2076 if (!cal.checkInternalDate(2003, OCTOBER, 32)) { 2077 errln(cal.getMessage()); 2078 } 2079 new Koyomi().equals(cal); 2080 if (!cal.checkInternalDate(2003, OCTOBER, 32)) { 2081 errln(cal.getMessage()); 2082 } 2083 } 2084 2085 /** 2086 * 4639407: GregorianCalendar doesn't work in non-lenient due to timezone bounds checking 2087 */ 2088 public void Test4639407() { 2089 // The following operations in non-lenient mode shouldn't 2090 // throw IllegalArgumentException. 2091 Koyomi cal = new Koyomi(TimeZone.getTimeZone("Pacific/Kiritimati")); 2092 cal.setLenient(false); 2093 cal.set(2003, OCTOBER, 10); 2094 cal.getTime(); 2095 cal.setTimeZone(TimeZone.getTimeZone("Pacific/Tongatapu")); 2096 cal.set(2003, OCTOBER, 10); 2097 cal.getTime(); 2098 } 2099 2100 /** 2101 * 4652815: rolling week-of-year back hundreds of weeks changes year 2102 */ 2103 public void Test4652815() { 2104 Koyomi cal = new Koyomi(Locale.US); 2105 testRoll(cal, 2003, SEPTEMBER, 29); 2106 testRoll(cal, 2003, DECEMBER, 24); 2107 testRoll(cal, 1582, DECEMBER, 19); 2108 testRoll(cal, 1582, DECEMBER, 20); 2109 } 2110 2111 private void testRoll(Koyomi cal, int year, int month, int dayOfMonth) { 2112 cal.clear(); 2113 cal.set(year, month, dayOfMonth); 2114 cal.getTime(); // normalize fields 2115 logln("Roll backwards from " + cal.toDateString()); 2116 for (int i = 0; i < 1000; i++) { 2117 cal.roll(WEEK_OF_YEAR, -i); 2118 if (!cal.checkFieldValue(YEAR, year)) { 2119 errln(cal.getMessage()); 2120 } 2121 } 2122 logln("Roll forewards from " + cal.toDateString()); 2123 for (int i = 0; i < 1000; i++) { 2124 cal.roll(WEEK_OF_YEAR, +i); 2125 if (!cal.checkFieldValue(YEAR, year)) { 2126 errln(cal.getMessage()); 2127 } 2128 } 2129 } 2130 2131 /** 2132 * 4652830: GregorianCalendar roll behaves unexpectedly for dates in BC era 2133 */ 2134 public void Test4652830() { 2135 Koyomi cal = new Koyomi(Locale.US); 2136 cal.clear(); 2137 logln("BCE 9-2-28 (leap year) roll DAY_OF_MONTH++ twice"); 2138 cal.set(ERA, GregorianCalendar.BC); 2139 cal.set(9, FEBRUARY, 28); 2140 if (cal.getActualMaximum(DAY_OF_YEAR) != 366) { 2141 errln(" wrong actual max of DAY_OF_YEAR: got " 2142 + cal.getActualMaximum(DAY_OF_YEAR) + " expected " + 366); 2143 } 2144 cal.roll(DAY_OF_MONTH, +1); 2145 if (!cal.checkFieldValue(ERA, GregorianCalendar.BC) 2146 || !cal.checkDate(9, FEBRUARY, 29)) { 2147 errln(cal.getMessage()); 2148 } 2149 cal.roll(DAY_OF_MONTH, +1); 2150 if (!cal.checkFieldValue(ERA, GregorianCalendar.BC) 2151 || !cal.checkDate(9, FEBRUARY, 1)) { 2152 errln(cal.getMessage()); 2153 } 2154 } 2155 2156 /** 2157 * 4740554: GregorianCalendar.getActualMaximum is inconsistent with normalization 2158 */ 2159 public void Test4740554() { 2160 logln("1999/(Feb+12)/1 should be normalized to 2000/Feb/1 for getActualMaximum"); 2161 Koyomi cal = new Koyomi(Locale.US); 2162 cal.clear(); 2163 cal.set(1999, FEBRUARY + 12, 1); 2164 if (!cal.checkActualMaximum(DAY_OF_YEAR, 366)) { 2165 errln(cal.getMessage()); 2166 } 2167 if (!cal.checkActualMaximum(DAY_OF_MONTH, 29)) { 2168 errln(cal.getMessage()); 2169 } 2170 } 2171 2172 /** 2173 * 4936355: GregorianCalendar causes overflow/underflow with time of day calculation 2174 */ 2175 public void Test4936355() { 2176 Koyomi cal = new Koyomi(TimeZone.getTimeZone("GMT")); 2177 cal.clear(); 2178 cal.set(1970, JANUARY, 1); 2179 checkTimeCalculation(cal, HOUR_OF_DAY, Integer.MAX_VALUE, 2180 (long) Integer.MAX_VALUE * 60 * 60 * 1000); 2181 2182 cal.clear(); 2183 cal.set(1970, JANUARY, 1); 2184 checkTimeCalculation(cal, HOUR, Integer.MAX_VALUE, 2185 (long) Integer.MAX_VALUE * 60 * 60 * 1000); 2186 2187 cal.clear(); 2188 cal.set(1970, JANUARY, 1); 2189 checkTimeCalculation(cal, MINUTE, Integer.MAX_VALUE, 2190 (long) Integer.MAX_VALUE * 60 * 1000); 2191 2192 cal.clear(); 2193 // Make sure to use Gregorian dates (before and after the 2194 // set() call) for testing 2195 cal.set(250000, JANUARY, 1); 2196 checkTimeCalculation(cal, HOUR_OF_DAY, Integer.MIN_VALUE, 2197 (long) Integer.MIN_VALUE * 60 * 60 * 1000); 2198 2199 cal.clear(); 2200 cal.set(250000, JANUARY, 1); 2201 checkTimeCalculation(cal, HOUR, Integer.MIN_VALUE, 2202 (long) Integer.MIN_VALUE * 60 * 60 * 1000); 2203 2204 cal.clear(); 2205 cal.set(250000, JANUARY, 1); 2206 checkTimeCalculation(cal, MINUTE, Integer.MIN_VALUE, 2207 (long) Integer.MIN_VALUE * 60 * 1000); 2208 } 2209 2210 private void checkTimeCalculation(Koyomi cal, int field, int value, long expectedDelta) { 2211 long time = cal.getTimeInMillis(); 2212 cal.set(field, value); 2213 long time2 = cal.getTimeInMillis(); 2214 if ((time + expectedDelta) != time2) { 2215 String s = value == Integer.MAX_VALUE ? "Integer.MAX_VALUE" : "Integer.MIN_VALUE"; 2216 errln("set(" + Koyomi.getFieldName(field) + ", " + s + ") failed." + " got " + time2 2217 + ", expected " + (time + expectedDelta)); 2218 } 2219 } 2220 2221 /** 2222 * 4722650: Calendar.equals can throw an exception in non-lenient 2223 * (piggy-back tests for compareTo() which is new in 1.5) 2224 */ 2225 public void Test4722650() { 2226 Calendar cal1 = new GregorianCalendar(); 2227 cal1.clear(); 2228 Calendar cal2 = new GregorianCalendar(); 2229 cal2.clear(); 2230 cal2.setLenient(false); 2231 2232 cal1.set(2003, OCTOBER, 31); 2233 cal2.set(2003, OCTOBER, 31); 2234 try { 2235 if (cal1.equals(cal2)) { 2236 errln("lenient and non-lenient shouldn't be equal. (2003/10/31)"); 2237 } 2238 if (cal1.compareTo(cal2) != 0) { 2239 errln("cal1 and cal2 should represent the same time. (2003/10/31)"); 2240 } 2241 } catch (IllegalArgumentException e) { 2242 errln("equals threw IllegalArugumentException with non-lenient"); 2243 } 2244 2245 cal1.set(2003, OCTOBER, 32); 2246 cal2.set(2003, OCTOBER, 32); 2247 try { 2248 if (cal1.equals(cal2)) { 2249 errln("lenient and non-lenient shouldn't be equal. (2003/10/32)"); 2250 } 2251 if (cal1.compareTo(cal2) != 0) { 2252 errln("cal1 and cal2 should represent the same time. (2003/10/32)"); 2253 } 2254 } catch (IllegalArgumentException e) { 2255 errln("equals threw IllegalArugumentException with non-lenient"); 2256 } 2257 2258 cal1 = Calendar.getInstance(new Locale("th", "TH")); 2259 cal1.setTimeInMillis(0L); 2260 cal2 = Calendar.getInstance(Locale.US); 2261 cal2.setTimeInMillis(0L); 2262 if (cal1.equals(cal2)) { 2263 errln("Buddhist.equals(Gregorian) shouldn't be true. (millis=0)"); 2264 } 2265 if (cal1.compareTo(cal2) != 0) { 2266 errln("cal1 (Buddhist) and cal2 (Gregorian) should represent the same time. (millis=0)"); 2267 } 2268 } 2269 2270 /** 2271 * 4738710: API: Calendar comparison methods should be improved 2272 */ 2273 public void Test4738710() { 2274 Calendar cal0 = new GregorianCalendar(2003, SEPTEMBER, 30); 2275 Comparable<Calendar> cal1 = new GregorianCalendar(2003, OCTOBER, 1); 2276 Calendar cal2 = new GregorianCalendar(2003, OCTOBER, 2); 2277 if (!(cal1.compareTo(cal0) > 0)) { 2278 errln("!(cal1 > cal0)"); 2279 } 2280 if (!(cal1.compareTo(cal2) < 0)) { 2281 errln("!(cal1 < cal2)"); 2282 } 2283 if (cal1.compareTo(new GregorianCalendar(2003, OCTOBER, 1)) != 0) { 2284 errln("cal1 != new GregorianCalendar(2003, OCTOBER, 1)"); 2285 } 2286 2287 if (cal0.after(cal2)) { 2288 errln("cal0 shouldn't be after cal2"); 2289 } 2290 if (cal2.before(cal0)) { 2291 errln("cal2 shouldn't be before cal0"); 2292 } 2293 2294 if (cal0.after(0)) { 2295 errln("cal0.after() returned true with an Integer."); 2296 } 2297 if (cal0.before(0)) { 2298 errln("cal0.before() returned true with an Integer."); 2299 } 2300 if (cal0.after(null)) { 2301 errln("cal0.after() returned true with null."); 2302 } 2303 if (cal0.before(null)) { 2304 errln("cal0.before() returned true with null."); 2305 } 2306 } 2307 2308 /** 2309 * 4633646: Setting WEEK_OF_MONTH to 1 results in incorrect date 2310 */ 2311 @SuppressWarnings("deprecation") 2312 public void Test4633646() { 2313 Koyomi cal = new Koyomi(Locale.US); 2314 cal.setTime(new Date(2002 - 1900, 1 - 1, 28)); 2315 sub4633646(cal); 2316 2317 cal.setLenient(false); 2318 cal.setTime(new Date(2002 - 1900, 1 - 1, 28)); 2319 sub4633646(cal); 2320 2321 cal = new Koyomi(Locale.US); 2322 cal.clear(); 2323 cal.set(2002, JANUARY, 28); 2324 sub4633646(cal); 2325 2326 cal.clear(); 2327 cal.setLenient(false); 2328 cal.set(2002, JANUARY, 28); 2329 sub4633646(cal); 2330 } 2331 2332 void sub4633646(Koyomi cal) { 2333 cal.getTime(); 2334 cal.set(WEEK_OF_MONTH, 1); 2335 if (cal.isLenient()) { 2336 if (!cal.checkDate(2001, DECEMBER, 31)) { 2337 errln(cal.getMessage()); 2338 } 2339 if (!cal.checkFieldValue(WEEK_OF_MONTH, 6)) { 2340 errln(cal.getMessage()); 2341 } 2342 } else { 2343 try { 2344 Date d = cal.getTime(); 2345 errln("didn't throw IllegalArgumentException in non-lenient"); 2346 } catch (IllegalArgumentException e) { 2347 } 2348 } 2349 } 2350 2351 /** 2352 * 4846659: Calendar: Both set() and roll() don't work for AM_PM time field 2353 * (Partially fixed only roll as of 1.5) 2354 */ 2355 public void Test4846659() { 2356 Koyomi cal = new Koyomi(); 2357 cal.clear(); 2358 cal.set(2003, OCTOBER, 31, 10, 30, 30); 2359 cal.getTime(); 2360 // Test roll() 2361 cal.roll(AM_PM, +1); // should turn to PM 2362 if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) { 2363 errln("roll: AM_PM didn't change to PM"); 2364 } 2365 2366 cal.clear(); 2367 cal.set(2003, OCTOBER, 31, 10, 30, 30); 2368 cal.getTime(); 2369 // Test set() 2370 cal.set(AM_PM, PM); // should turn to PM 2371 if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) { 2372 errln("set: AM_PM didn't change to PM"); 2373 } 2374 2375 cal.clear(); 2376 cal.set(2003, OCTOBER, 31, 10, 30, 30); 2377 cal.getTime(); 2378 cal.set(AM_PM, PM); 2379 cal.set(HOUR, 9); 2380 if (!cal.checkFieldValue(HOUR_OF_DAY, 9 + 12)) { 2381 errln("set: both AM_PM and HOUT didn't change to PM"); 2382 } 2383 } 2384 2385 /** 2386 * 4822110: GregorianCalendar.get() returns an incorrect date after setFirstDayOfWeek() 2387 */ 2388 public void Test4822110() { 2389 Koyomi cal = new Koyomi(Locale.US); 2390 // June 2003 2391 // S M Tu W Th F S 2392 // 1 2 3 4 5 6 7 2393 // 8 9 10 11 12 13 14 2394 // 15 16 17 18 19 20 21 2395 // 22 23 24 25 26 27 28 2396 // 29 30 2397 cal.clear(); 2398 // 6/1 to 6/7 should be the 1st week of June. 2399 cal.set(2003, JUNE, 2); 2400 cal.getTime(); // Let cal calculate time. 2401 cal.setFirstDayOfWeek(MONDAY); 2402 // Now 6/2 to 6/8 should be the 2nd week of June. Sunday of 2403 // that week is 6/8. 2404 logln("1: " + cal.get(WEEK_OF_MONTH) + ", " + cal.get(DAY_OF_MONTH)); 2405 cal.set(DAY_OF_WEEK, SUNDAY); 2406 logln("1st Sunday of June 2003 with FirstDayOfWeek=MONDAY"); 2407 if (!cal.checkDate(2003, JUNE, 8)) { 2408 errln(cal.getMessage()); 2409 } 2410 } 2411 2412 /** 2413 * 4973919: Inconsistent GregorianCalendar hashCode before and after serialization 2414 */ 2415 public void Test4966499() throws Exception { 2416 GregorianCalendar date1 = new GregorianCalendar(2004, JANUARY, 7); 2417 2418 // Serialize date1 2419 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 2420 ObjectOutputStream oos = new ObjectOutputStream(baos); 2421 oos.writeObject(date1); 2422 2423 byte[] buffer = baos.toByteArray(); 2424 2425 // Deserialize it 2426 ByteArrayInputStream bais = new ByteArrayInputStream(buffer); 2427 ObjectInputStream ois = new ObjectInputStream(bais); 2428 GregorianCalendar date2 = (GregorianCalendar) ois.readObject(); 2429 2430 if (!date1.equals(date2)) { 2431 errln("date1.equals(date2) != true"); 2432 } 2433 if (date1.hashCode() != date2.hashCode()) { 2434 errln("inconsistent hashCode() value (before=0x" 2435 + Integer.toHexString(date1.hashCode()) 2436 + ", after=0x" + Integer.toHexString(date2.hashCode()) + ")"); 2437 } 2438 } 2439 2440 /** 2441 * 4980088: GregorianCalendar.getActualMaximum doesn't throw exception 2442 */ 2443 public void Test4980088() { 2444 GregorianCalendar cal = new GregorianCalendar(); 2445 try { 2446 int x = cal.getMaximum(100); 2447 errln("getMaximum(100) didn't throw an exception."); 2448 } catch (IndexOutOfBoundsException e) { 2449 logln("getMaximum: " + e.getClass().getName() + ": " + e.getMessage()); 2450 } 2451 2452 try { 2453 int x = cal.getLeastMaximum(100); 2454 errln("getLeastMaximum(100) didn't throw an exception."); 2455 } catch (IndexOutOfBoundsException e) { 2456 logln("getLeastMaximum: " + e.getClass().getName() + ": " + e.getMessage()); 2457 } 2458 2459 try { 2460 int x = cal.getActualMaximum(100); 2461 errln("getActualMaximum(100) didn't throw an exception."); 2462 } catch (IndexOutOfBoundsException e) { 2463 logln("getActualMaximum: " + e.getClass().getName() + ": " + e.getMessage()); 2464 } 2465 2466 try { 2467 int x = cal.getMinimum(100); 2468 errln("getMinimum(100) didn't throw an exception."); 2469 } catch (IndexOutOfBoundsException e) { 2470 logln("getMinimum: " + e.getClass().getName() + ": " + e.getMessage()); 2471 } 2472 2473 try { 2474 int x = cal.getGreatestMinimum(100); 2475 errln("getGreatestMinimum(100) didn't throw an exception."); 2476 } catch (IndexOutOfBoundsException e) { 2477 logln("getGreatestMinimum: " + e.getClass().getName() + ": " + e.getMessage()); 2478 } 2479 2480 try { 2481 int x = cal.getActualMinimum(100); 2482 errln("getActualMinimum(100) didn't throw an exception."); 2483 } catch (IndexOutOfBoundsException e) { 2484 logln("getActualMinimum: " + e.getClass().getName() + ": " + e.getMessage()); 2485 } 2486 } 2487 2488 /** 2489 * 4965624: GregorianCalendar.isLeapYear(1000) returns incorrect value 2490 */ 2491 public void Test4965624() { 2492 // 5013094: This test case needs to use "GMT" to specify 2493 // Gregorian cutover dates. 2494 TimeZone savedZone = TimeZone.getDefault(); 2495 TimeZone.setDefault(TimeZone.getTimeZone("GMT")); 2496 try { 2497 Map<Date, Boolean> data = new HashMap<>(); 2498 data.put(getGregorianDate(999, OCTOBER, 1), Boolean.FALSE); 2499 data.put(getGregorianDate(1000, JANUARY, 1), Boolean.FALSE); 2500 data.put(getGregorianDate(1000, FEBRUARY, 1), Boolean.FALSE); 2501 data.put(getGregorianDate(1000, FEBRUARY, 28), Boolean.FALSE); 2502 data.put(getGregorianDate(1000, MARCH, 1), Boolean.TRUE); 2503 data.put(getGregorianDate(1001, JANUARY, 1), Boolean.TRUE); 2504 data.put(getGregorianDate(1001, JANUARY, 6), Boolean.TRUE); 2505 data.put(getGregorianDate(1001, MARCH, 1), Boolean.TRUE); 2506 2507 data.keySet().forEach(d -> { 2508 boolean expected = data.get(d); 2509 GregorianCalendar cal = new GregorianCalendar(); 2510 cal.setGregorianChange(d); 2511 if (cal.isLeapYear(1000) != expected) { 2512 errln("isLeapYear(1000) returned " + cal.isLeapYear(1000) 2513 + " with cutover date (Julian) " + d); 2514 } 2515 }); 2516 } finally { 2517 TimeZone.setDefault(savedZone); 2518 } 2519 } 2520 2521 // Note that we can't use Date to produce Gregorian calendar dates 2522 // before the default cutover date. 2523 static Date getGregorianDate(int year, int month, int dayOfMonth) { 2524 GregorianCalendar g = new GregorianCalendar(); 2525 // Make g a pure Gregorian calendar 2526 g.setGregorianChange(new Date(Long.MIN_VALUE)); 2527 g.clear(); 2528 g.set(year, month, dayOfMonth); 2529 return g.getTime(); 2530 } 2531 2532 /** 2533 * 5006864: Define the minimum value of DAY_OF_WEEK_IN_MONTH as 1 2534 */ 2535 public void Test5006864() { 2536 GregorianCalendar cal = new GregorianCalendar(); 2537 int min = cal.getMinimum(DAY_OF_WEEK_IN_MONTH); 2538 if (min != 1) { 2539 errln("GregorianCalendar.getMinimum(DAY_OF_WEEK_IN_MONTH) returned " 2540 + min + ", expected 1."); 2541 } 2542 min = cal.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH); 2543 if (min != 1) { 2544 errln("GregorianCalendar.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH) returned " 2545 + min + ", expected 1."); 2546 } 2547 } 2548} 2549