< prev index next >

test/jdk/java/util/Calendar/CalendarRegression.java

Print this page

   1 /*
   2  * Copyright (c) 1998, 2022, 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  */
  37 import java.io.ByteArrayInputStream;
  38 import java.io.ByteArrayOutputStream;
  39 import java.io.IOException;
  40 import java.io.ObjectInputStream;
  41 import java.io.ObjectOutputStream;
  42 import java.text.DateFormat;
  43 import java.text.NumberFormat;
  44 import java.text.SimpleDateFormat;
  45 import java.util.Calendar;
  46 import java.util.Date;
  47 import java.util.GregorianCalendar;
  48 import java.util.HashMap;
  49 import java.util.Locale;
  50 import java.util.Map;
  51 import java.util.SimpleTimeZone;
  52 import java.util.TimeZone;
  53 
  54 import static java.util.Calendar.*;
  55 
  56 public 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,},

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

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(Locale.of("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 }

   1 /*
   2  * Copyright (c) 1998, 2023, 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 junit CalendarRegression
  36  */
  37 import java.io.ByteArrayInputStream;
  38 import java.io.ByteArrayOutputStream;
  39 import java.io.IOException;
  40 import java.io.ObjectInputStream;
  41 import java.io.ObjectOutputStream;
  42 import java.text.DateFormat;
  43 import java.text.NumberFormat;
  44 import java.text.SimpleDateFormat;
  45 import java.util.Calendar;
  46 import java.util.Date;
  47 import java.util.GregorianCalendar;
  48 import java.util.HashMap;
  49 import java.util.Locale;
  50 import java.util.Map;
  51 import java.util.SimpleTimeZone;
  52 import java.util.TimeZone;
  53 
  54 import static java.util.Calendar.*;
  55 
  56 import org.junit.jupiter.api.Test;
  57 
  58 import static org.junit.jupiter.api.Assertions.fail;
  59 
  60 public class CalendarRegression {
  61 
  62     /*
  63     Synopsis: java.sql.Timestamp constructor works wrong on Windows 95
  64 
  65     ==== Here is the test ====






  66     ==== Here is the output of the test on Solaris or NT ====
  67     expected=1901-04-05 05:08:13.1234567
  68     result=1901-04-05 05:08:13.1234567
  69 
  70     ==== Here is the output of the test on Windows95 ====
  71     expected=1901-04-05 05:08:13.1234567
  72     result=1901-04-05 06:08:13.1234567
  73      */
  74     @Test
  75     public void Test4031502() {
  76         // This bug actually occurs on Windows NT as well, and doesn't
  77         // require the host zone to be set; it can be set in Java.
  78         String[] ids = TimeZone.getAvailableIDs();
  79         boolean bad = false;
  80         for (int i = 0; i < ids.length; ++i) {
  81             TimeZone zone = TimeZone.getTimeZone(ids[i]);
  82             GregorianCalendar cal = new GregorianCalendar(zone);
  83             cal.clear();
  84             cal.set(1900, 15, 5, 5, 8, 13);
  85             if (cal.get(HOUR) != 5) {
  86                 System.out.println(zone.getID() + " "
  87                         + //zone.useDaylightTime() + " "
  88                         + cal.get(DST_OFFSET) / (60 * 60 * 1000) + " "
  89                         + zone.getRawOffset() / (60 * 60 * 1000)
  90                         + ": HOUR = " + cal.get(HOUR));
  91                 bad = true;
  92             }
  93         }
  94         if (bad) {
  95             fail("TimeZone problems with GC");
  96         }
  97     }
  98 
  99     @Test
 100     public void Test4035301() {
 101         GregorianCalendar c = new GregorianCalendar(98, 8, 7);
 102         GregorianCalendar d = new GregorianCalendar(98, 8, 7);
 103         if (c.after(d)
 104                 || c.after(c)
 105                 || c.before(d)
 106                 || c.before(c)
 107                 || !c.equals(c)
 108                 || !c.equals(d)) {
 109             fail("Fail");
 110         }
 111     }
 112 
 113     @Test
 114     public void Test4040996() {
 115         String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
 116         SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
 117         pdt.setStartRule(APRIL, 1, SUNDAY, 2 * 60 * 60 * 1000);
 118         pdt.setEndRule(OCTOBER, -1, SUNDAY, 2 * 60 * 60 * 1000);
 119         Calendar calendar = new GregorianCalendar(pdt);
 120 
 121         calendar.set(MONTH, 3);
 122         calendar.set(DAY_OF_MONTH, 18);
 123         calendar.set(SECOND, 30);
 124 
 125         System.out.println("MONTH: " + calendar.get(MONTH));
 126         System.out.println("DAY_OF_MONTH: "
 127                 + calendar.get(DAY_OF_MONTH));
 128         System.out.println("MINUTE: " + calendar.get(MINUTE));
 129         System.out.println("SECOND: " + calendar.get(SECOND));
 130 
 131         calendar.add(SECOND, 6);
 132         //This will print out todays date for MONTH and DAY_OF_MONTH
 133         //instead of the date it was set to.
 134         //This happens when adding MILLISECOND or MINUTE also
 135         System.out.println("MONTH: " + calendar.get(MONTH));
 136         System.out.println("DAY_OF_MONTH: "
 137                 + calendar.get(DAY_OF_MONTH));
 138         System.out.println("MINUTE: " + calendar.get(MINUTE));
 139         System.out.println("SECOND: " + calendar.get(SECOND));
 140         if (calendar.get(MONTH) != 3
 141                 || calendar.get(DAY_OF_MONTH) != 18
 142                 || calendar.get(SECOND) != 36) {
 143             fail("Fail: Calendar.add misbehaves");
 144         }
 145     }
 146 
 147     @Test
 148     public void Test4051765() {
 149         Calendar cal = Calendar.getInstance();
 150         cal.setLenient(false);
 151         cal.set(DAY_OF_WEEK, 0);
 152         try {
 153             cal.getTime();
 154             fail("Fail: DAY_OF_WEEK 0 should be disallowed");
 155         } catch (IllegalArgumentException e) {
 156             return;
 157         }
 158     }
 159 
 160     /* User error - no bug here
 161     @Test
 162     public void Test4059524() {
 163         // Create calendar for April 10, 1997
 164         GregorianCalendar calendar  = new GregorianCalendar();
 165         // print out a bunch of interesting things
 166         System.out.println("ERA: " + calendar.get(calendar.ERA));
 167         System.out.println("YEAR: " + calendar.get(calendar.YEAR));
 168         System.out.println("MONTH: " + calendar.get(calendar.MONTH));
 169         System.out.println("WEEK_OF_YEAR: " +
 170                            calendar.get(calendar.WEEK_OF_YEAR));
 171         System.out.println("WEEK_OF_MONTH: " +
 172                            calendar.get(calendar.WEEK_OF_MONTH));
 173         System.out.println("DATE: " + calendar.get(calendar.DATE));
 174         System.out.println("DAY_OF_MONTH: " +
 175                            calendar.get(calendar.DAY_OF_MONTH));
 176         System.out.println("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR));
 177         System.out.println("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK));
 178         System.out.println("DAY_OF_WEEK_IN_MONTH: " +
 179                            calendar.get(calendar.DAY_OF_WEEK_IN_MONTH));
 180         System.out.println("AM_PM: " + calendar.get(calendar.AM_PM));
 181         System.out.println("HOUR: " + calendar.get(calendar.HOUR));
 182         System.out.println("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY));
 183         System.out.println("MINUTE: " + calendar.get(calendar.MINUTE));
 184         System.out.println("SECOND: " + calendar.get(calendar.SECOND));
 185         System.out.println("MILLISECOND: " + calendar.get(calendar.MILLISECOND));
 186         System.out.println("ZONE_OFFSET: "
 187                            + (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000)));
 188         System.out.println("DST_OFFSET: "
 189                            + (calendar.get(calendar.DST_OFFSET)/(60*60*1000)));
 190         calendar  = new GregorianCalendar(1997,3,10);
 191         calendar.getTime();
 192         System.out.println("April 10, 1997");
 193         System.out.println("ERA: " + calendar.get(calendar.ERA));
 194         System.out.println("YEAR: " + calendar.get(calendar.YEAR));
 195         System.out.println("MONTH: " + calendar.get(calendar.MONTH));
 196         System.out.println("WEEK_OF_YEAR: " +
 197                            calendar.get(calendar.WEEK_OF_YEAR));
 198         System.out.println("WEEK_OF_MONTH: " +
 199                            calendar.get(calendar.WEEK_OF_MONTH));
 200         System.out.println("DATE: " + calendar.get(calendar.DATE));
 201         System.out.println("DAY_OF_MONTH: " +
 202                            calendar.get(calendar.DAY_OF_MONTH));
 203         System.out.println("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR));
 204         System.out.println("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK));
 205         System.out.println("DAY_OF_WEEK_IN_MONTH: " + calendar.get(calendar.DAY_OF_WEEK_IN_MONTH));
 206         System.out.println("AM_PM: " + calendar.get(calendar.AM_PM));
 207         System.out.println("HOUR: " + calendar.get(calendar.HOUR));
 208         System.out.println("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY));
 209         System.out.println("MINUTE: " + calendar.get(calendar.MINUTE));
 210         System.out.println("SECOND: " + calendar.get(calendar.SECOND));
 211         System.out.println("MILLISECOND: " + calendar.get(calendar.MILLISECOND));
 212         System.out.println("ZONE_OFFSET: "
 213                            + (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); // in hours
 214         System.out.println("DST_OFFSET: "
 215                            + (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); // in hours
 216     }
 217      */
 218     @Test
 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             fail("Fail: Calendar.set broken. Got " + cd + " Want " + exp);
 235         }
 236     }
 237 
 238     @Test
 239     public void Test4061476() {
 240         SimpleDateFormat fmt = new SimpleDateFormat("ddMMMyy", Locale.UK);
 241         Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"),
 242                 Locale.UK);
 243         fmt.setCalendar(cal);
 244         try {
 245             Date date = fmt.parse("29MAY97");
 246             cal.setTime(date);
 247         } catch (Exception e) {
 248         }
 249         cal.set(HOUR_OF_DAY, 13);
 250         System.out.println("Hour: " + cal.get(HOUR_OF_DAY));
 251         cal.add(HOUR_OF_DAY, 6);
 252         System.out.println("Hour: " + cal.get(HOUR_OF_DAY));
 253         if (cal.get(HOUR_OF_DAY) != 19) {
 254             fail("Fail: Want 19 Got " + cal.get(HOUR_OF_DAY));
 255         }
 256     }
 257 
 258     @Test
 259     public void Test4070502() {
 260         @SuppressWarnings("deprecation")
 261         Date d = getAssociatedDate(new Date(98, 0, 30));
 262         Calendar cal = new GregorianCalendar();
 263         cal.setTime(d);
 264         if (cal.get(DAY_OF_WEEK) == SATURDAY
 265                 || cal.get(DAY_OF_WEEK) == SUNDAY) {
 266             fail("Fail: Want weekday Got " + d);
 267         }
 268     }
 269 
 270     /**
 271      * Get the associated date starting from a specified date
 272      * NOTE: the unnecessary "getTime()'s" below are a work-around for a
 273      * bug in jdk 1.1.3 (and probably earlier versions also)
 274      * <p>
 275      * @param date The date to start from
 276      */
 277     public static Date getAssociatedDate(Date d) {
 278         GregorianCalendar cal = new GregorianCalendar();
 279         cal.setTime(d);
 280         //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
 281         // cal.getTime();  // <--- REMOVE THIS TO SEE BUG
 282         while (true) {
 283             int wd = cal.get(DAY_OF_WEEK);
 284             if (wd == SATURDAY || wd == SUNDAY) {
 285                 cal.add(DATE, 1);
 286                 // cal.getTime();
 287             } else {
 288                 break;
 289             }
 290         }
 291         return cal.getTime();
 292     }
 293 
 294     @Test
 295     public void Test4071197() {
 296         dowTest(false);
 297         dowTest(true);
 298     }
 299 
 300     void dowTest(boolean lenient) {
 301         GregorianCalendar cal = new GregorianCalendar();
 302         cal.set(1997, AUGUST, 12); // Wednesday
 303         // cal.getTime(); // Force update
 304         cal.setLenient(lenient);
 305         cal.set(1996, DECEMBER, 1); // Set the date to be December 1, 1996
 306         int dow = cal.get(DAY_OF_WEEK);
 307         int min = cal.getMinimum(DAY_OF_WEEK);
 308         int max = cal.getMaximum(DAY_OF_WEEK);
 309         System.out.println(cal.getTime().toString());
 310         if (min != SUNDAY || max != SATURDAY) {
 311             fail("FAIL: Min/max bad");
 312         }
 313         if (dow < min || dow > max) {
 314             fail("FAIL: Day of week " + dow + " out of range");
 315         }
 316         if (dow != SUNDAY) {
 317             fail("FAIL: Day of week should be SUNDAY Got " + dow);
 318         }
 319     }
 320 
 321     @SuppressWarnings("deprecation")
 322     @Test
 323     public void Test4071385() {
 324         Calendar cal = Calendar.getInstance();
 325         cal.setTime(new Date(98, JUNE, 24));
 326         cal.set(MONTH, NOVEMBER); // change a field
 327         System.out.println(cal.getTime().toString());
 328         if (!cal.getTime().equals(new Date(98, NOVEMBER, 24))) {
 329             fail("Fail");
 330         }
 331     }
 332 
 333     @Test
 334     public void Test4073929() {
 335         GregorianCalendar foo1 = new GregorianCalendar(1997, 8, 27);
 336         foo1.add(DAY_OF_MONTH, +1);
 337         int testyear = foo1.get(YEAR);
 338         int testmonth = foo1.get(MONTH);
 339         int testday = foo1.get(DAY_OF_MONTH);
 340         if (testyear != 1997
 341                 || testmonth != 8
 342                 || testday != 28) {
 343             fail("Fail: Calendar not initialized");
 344         }
 345     }
 346 
 347     @Test
 348     public void Test4083167() {
 349         TimeZone saveZone = TimeZone.getDefault();
 350         try {
 351             TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
 352             Date firstDate = new Date();
 353             Calendar cal = new GregorianCalendar();
 354             cal.setTime(firstDate);
 355             long firstMillisInDay = cal.get(HOUR_OF_DAY) * 3600000L
 356                     + cal.get(MINUTE) * 60000L
 357                     + cal.get(SECOND) * 1000L
 358                     + cal.get(MILLISECOND);
 359 
 360             System.out.println("Current time: " + firstDate.toString());
 361 
 362             for (int validity = 0; validity < 30; validity++) {
 363                 Date lastDate = new Date(firstDate.getTime()
 364                         + (long) validity * 1000 * 24 * 60 * 60);
 365                 cal.setTime(lastDate);
 366                 long millisInDay = cal.get(HOUR_OF_DAY) * 3600000L
 367                         + cal.get(MINUTE) * 60000L
 368                         + cal.get(SECOND) * 1000L
 369                         + cal.get(MILLISECOND);
 370                 if (firstMillisInDay != millisInDay) {
 371                     fail("Day has shifted " + lastDate);
 372                 }
 373             }
 374         } finally {
 375             TimeZone.setDefault(saveZone);
 376         }
 377     }
 378 
 379     @Test
 380     public void Test4086724() {
 381         SimpleDateFormat date;
 382         TimeZone saveZone = TimeZone.getDefault();
 383         Locale saveLocale = Locale.getDefault();
 384 
 385         String summerTime = "British Summer Time";
 386         String standardTime = "Greenwich Mean Time";
 387         try {
 388             Locale.setDefault(Locale.UK);
 389             TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
 390             date = new SimpleDateFormat("zzzz");
 391 
 392             Calendar cal = Calendar.getInstance();
 393             cal.set(1997, SEPTEMBER, 30);
 394             Date now = cal.getTime();
 395             String formattedDate = date.format(now);
 396             if (!formattedDate.equals(summerTime)) {
 397                 fail("Wrong display name \"" + formattedDate
 398                         + "\" for <" + now + ">");
 399             }
 400             int weekOfYear = cal.get(WEEK_OF_YEAR);
 401             if (weekOfYear != 40) {
 402                 fail("Wrong week-of-year " + weekOfYear
 403                         + " for <" + now + ">");
 404             }
 405 
 406             cal.set(1996, DECEMBER, 31);
 407             now = cal.getTime();
 408             formattedDate = date.format(now);
 409             if (!formattedDate.equals(standardTime)) {
 410                 fail("Wrong display name \"" + formattedDate
 411                         + "\" for <" + now + ">");
 412             }
 413             weekOfYear = cal.get(WEEK_OF_YEAR);
 414             if (weekOfYear != 1) {
 415                 fail("Wrong week-of-year " + weekOfYear
 416                         + " for <" + now + ">");
 417             }
 418 
 419             cal.set(1997, JANUARY, 1);
 420             now = cal.getTime();
 421             formattedDate = date.format(now);
 422             if (!formattedDate.equals(standardTime)) {
 423                 fail("Wrong display name \"" + formattedDate
 424                         + "\" for <" + now + ">");
 425             }
 426             weekOfYear = cal.get(WEEK_OF_YEAR);
 427             if (weekOfYear != 1) {
 428                 fail("Wrong week-of-year " + weekOfYear
 429                         + " for <" + now + ">");
 430             }
 431 
 432             cal.set(1997, JANUARY, 8);
 433             now = cal.getTime();
 434             formattedDate = date.format(now);
 435             if (!formattedDate.equals(standardTime)) {
 436                 fail("Wrong display name \"" + formattedDate
 437                         + "\" for <" + now + ">");
 438             }
 439             weekOfYear = cal.get(WEEK_OF_YEAR);
 440             if (weekOfYear != 2) {
 441                 fail("Wrong week-of-year " + weekOfYear
 442                         + " for <" + now + ">");
 443             }
 444 
 445         } finally {
 446             Locale.setDefault(saveLocale);
 447             TimeZone.setDefault(saveZone);
 448         }
 449     }
 450 
 451     @Test
 452     public void Test4092362() {
 453         GregorianCalendar cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40);
 454         /*cal1.set( Calendar.YEAR, 1997 );
 455         cal1.set( Calendar.MONTH, 10 );
 456         cal1.set( Calendar.DATE, 11 );
 457         cal1.set( Calendar.HOUR, 10 );
 458         cal1.set( Calendar.MINUTE, 20 );
 459         cal1.set( Calendar.SECOND, 40 ); */
 460 
 461         System.out.println(" Cal1 = " + cal1.getTime().getTime());
 462         System.out.println(" Cal1 time in ms = " + cal1.get(MILLISECOND));
 463         for (int k = 0; k < 100; k++);
 464 
 465         GregorianCalendar cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40);
 466         /*cal2.set( Calendar.YEAR, 1997 );
 467         cal2.set( Calendar.MONTH, 10 );
 468         cal2.set( Calendar.DATE, 11 );
 469         cal2.set( Calendar.HOUR, 10 );
 470         cal2.set( Calendar.MINUTE, 20 );
 471         cal2.set( Calendar.SECOND, 40 ); */
 472 
 473         System.out.println(" Cal2 = " + cal2.getTime().getTime());
 474         System.out.println(" Cal2 time in ms = " + cal2.get(MILLISECOND));
 475         if (!cal1.equals(cal2)) {
 476             fail("Fail: Milliseconds randomized");
 477         }
 478     }
 479 
 480     @Test
 481     public void Test4095407() {
 482         GregorianCalendar a = new GregorianCalendar(1997, NOVEMBER, 13);
 483         int dow = a.get(DAY_OF_WEEK);
 484         if (dow != THURSDAY) {
 485             fail("Fail: Want THURSDAY Got " + dow);
 486         }
 487     }
 488 
 489     @Test
 490     public void Test4096231() {
 491         TimeZone GMT = TimeZone.getTimeZone("GMT");
 492         TimeZone PST = TimeZone.getTimeZone("PST");
 493         int sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997;
 494 
 495         Calendar cal1 = new GregorianCalendar(PST);
 496         cal1.setTime(new Date(880698639000L));
 497         int p;
 498         System.out.println("PST 1 is: " + (p = cal1.get(HOUR_OF_DAY)));
 499         cal1.setTimeZone(GMT);
 500         // Issue 1: Changing the timezone doesn't change the
 501         //          represented time.
 502         int h1, h2;
 503         System.out.println("GMT 1 is: " + (h1 = cal1.get(HOUR_OF_DAY)));
 504         cal1.setTime(new Date(880698639000L));
 505         System.out.println("GMT 2 is: " + (h2 = cal1.get(HOUR_OF_DAY)));
 506         // Note: This test had a bug in it.  It wanted h1!=h2, when
 507         // what was meant was h1!=p.  Fixed this concurrent with fix
 508         // to 4177484.
 509         if (p == h1 || h1 != h2) {
 510             fail("Fail: Hour same in different zones");
 511         }
 512 
 513         Calendar cal2 = new GregorianCalendar(GMT);
 514         Calendar cal3 = new GregorianCalendar(PST);
 515         cal2.set(MILLISECOND, 0);
 516         cal3.set(MILLISECOND, 0);
 517 
 518         cal2.set(cal1.get(YEAR),
 519                 cal1.get(MONTH),
 520                 cal1.get(DAY_OF_MONTH),
 521                 cal1.get(HOUR_OF_DAY),
 522                 cal1.get(MINUTE),
 523                 cal1.get(SECOND));
 524 
 525         long t1, t2, t3, t4;
 526         System.out.println("RGMT 1 is: " + (t1 = cal2.getTime().getTime()));
 527         cal3.set(year, month, day, hr, min, sec);
 528         System.out.println("RPST 1 is: " + (t2 = cal3.getTime().getTime()));
 529         cal3.setTimeZone(GMT);
 530         System.out.println("RGMT 2 is: " + (t3 = cal3.getTime().getTime()));
 531         cal3.set(cal1.get(YEAR),
 532                 cal1.get(MONTH),
 533                 cal1.get(DAY_OF_MONTH),
 534                 cal1.get(HOUR_OF_DAY),
 535                 cal1.get(MINUTE),
 536                 cal1.get(SECOND));
 537         // Issue 2: Calendar continues to use the timezone in its
 538         //          constructor for set() conversions, regardless
 539         //          of calls to setTimeZone()
 540         System.out.println("RGMT 3 is: " + (t4 = cal3.getTime().getTime()));
 541         if (t1 == t2
 542                 || t1 != t4
 543                 || t2 != t3) {
 544             fail("Fail: Calendar zone behavior faulty");
 545         }
 546     }
 547 
 548     @Test
 549     public void Test4096539() {
 550         int[] y = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 551 
 552         for (int x = 0; x < 12; x++) {
 553             GregorianCalendar gc = new GregorianCalendar(1997, x, y[x]);
 554             int m1, m2;
 555             System.out.println((m1 = gc.get(MONTH) + 1) + "/"
 556                     + gc.get(DATE) + "/" + gc.get(YEAR)
 557                     + " + 1mo = ");
 558 
 559             gc.add(MONTH, 1);
 560             System.out.println((m2 = gc.get(MONTH) + 1) + "/"
 561                     + gc.get(DATE) + "/" + gc.get(YEAR)
 562             );
 563             int m = (m1 % 12) + 1;
 564             if (m2 != m) {
 565                 fail("Fail: Want " + m + " Got " + m2);
 566             }
 567         }
 568 
 569     }
 570 
 571     @Test
 572     public void Test4100311() {
 573         Locale locale = Locale.getDefault();
 574         if (!TestUtils.usesGregorianCalendar(locale)) {
 575             System.out.println("Skipping this test because locale is " + locale);
 576             return;
 577         }
 578 
 579         GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
 580         cal.set(YEAR, 1997);
 581         cal.set(DAY_OF_YEAR, 1);
 582         Date d = cal.getTime();             // Should be Jan 1
 583         System.out.println(d.toString());
 584         if (cal.get(DAY_OF_YEAR) != 1) {
 585             fail("Fail: DAY_OF_YEAR not set");
 586         }
 587     }
 588 
 589     @Test
 590     public void Test4103271() {
 591         Locale locale = Locale.getDefault();
 592         if (!TestUtils.usesGregorianCalendar(locale)) {
 593             System.out.println("Skipping this test because locale is " + locale);
 594             return;
 595         }
 596 
 597         SimpleDateFormat sdf = new SimpleDateFormat();
 598         int numYears = 40, startYear = 1997, numDays = 15;
 599         String output, testDesc;
 600         GregorianCalendar testCal = (GregorianCalendar) Calendar.getInstance();
 601         testCal.clear();
 602         sdf.setCalendar(testCal);
 603         sdf.applyPattern("d MMM yyyy");
 604         boolean fail = false;
 605         for (int firstDay = 1; firstDay <= 2; firstDay++) {
 606             for (int minDays = 1; minDays <= 7; minDays++) {
 607                 testCal.setMinimalDaysInFirstWeek(minDays);
 608                 testCal.setFirstDayOfWeek(firstDay);
 609                 testDesc = ("Test" + String.valueOf(firstDay) + String.valueOf(minDays));
 610                 System.out.println(testDesc + " => 1st day of week="
 611                         + String.valueOf(firstDay)
 612                         + ", minimum days in first week="
 613                         + String.valueOf(minDays));
 614                 for (int j = startYear; j <= startYear + numYears; j++) {
 615                     testCal.set(j, 11, 25);
 616                     for (int i = 0; i < numDays; i++) {
 617                         testCal.add(DATE, 1);
 618                         String calWOY;
 619                         int actWOY = testCal.get(WEEK_OF_YEAR);
 620                         if (actWOY < 1 || actWOY > 53) {
 621                             Date d = testCal.getTime();
 622                             calWOY = String.valueOf(actWOY);
 623                             output = testDesc + " - " + sdf.format(d) + "\t";
 624                             output = output + "\t" + calWOY;
 625                             System.out.println(output);
 626                             fail = true;
 627                         }
 628                     }
 629                 }
 630             }
 631         }
 632 
 633         int[] DATA = {
 634             3, 52, 52, 52, 52, 52, 52, 52,
 635             1, 1, 1, 1, 1, 1, 1,
 636             2, 2, 2, 2, 2, 2, 2,
 637             4, 52, 52, 52, 52, 52, 52, 52,
 638             53, 53, 53, 53, 53, 53, 53,
 639             1, 1, 1, 1, 1, 1, 1};
 640         testCal.setFirstDayOfWeek(SUNDAY);
 641         for (int j = 0; j < DATA.length; j += 22) {
 642             System.out.println("Minimal days in first week = " + DATA[j]
 643                     + "  Week starts on Sunday");
 644             testCal.setMinimalDaysInFirstWeek(DATA[j]);
 645             testCal.set(1997, DECEMBER, 21);
 646             for (int i = 0; i < 21; ++i) {
 647                 int woy = testCal.get(WEEK_OF_YEAR);
 648                 System.out.println("\t" + testCal.getTime() + " " + woy);
 649                 if (woy != DATA[j + 1 + i]) {
 650                     System.out.println(" ERROR");
 651                     fail = true;
 652                 } else {
 653                     System.out.println(" OK");
 654                 }
 655 
 656                 // Now compute the time from the fields, and make sure we
 657                 // get the same answer back.  This is a round-trip test.
 658                 Date save = testCal.getTime();
 659                 testCal.clear();
 660                 testCal.set(YEAR, DATA[j + 1 + i] < 25 ? 1998 : 1997);
 661                 testCal.set(WEEK_OF_YEAR, DATA[j + 1 + i]);
 662                 testCal.set(DAY_OF_WEEK, (i % 7) + SUNDAY);
 663                 if (!testCal.getTime().equals(save)) {
 664                     System.out.println("  Parse failed: " + testCal.getTime());
 665                     fail = true;
 666                 } else {
 667                     System.out.println("  Passed");
 668                 }
 669 
 670                 testCal.setTime(save);
 671                 testCal.add(DAY_OF_MONTH, 1);
 672             }
 673         }
 674 
 675         // Test field disambiguation with a few special hard-coded cases.
 676         // This shouldn't fail if the above cases aren't failing.
 677         @SuppressWarnings("deprecation")
 678         Object[] DISAM = {
 679             1998, 1, SUNDAY,
 680             new Date(97, DECEMBER, 28),
 681             1998, 2, SATURDAY,
 682             new Date(98, JANUARY, 10),
 683             1998, 53, THURSDAY,
 684             new Date(98, DECEMBER, 31),
 685             1998, 53, FRIDAY,
 686             new Date(99, JANUARY, 1)};
 687         testCal.setMinimalDaysInFirstWeek(3);
 688         testCal.setFirstDayOfWeek(SUNDAY);
 689         for (int i = 0; i < DISAM.length; i += 4) {
 690             int y = (Integer) DISAM[i];
 691             int woy = (Integer) DISAM[i + 1];
 692             int dow = (Integer) DISAM[i + 2];
 693             Date exp = (Date) DISAM[i + 3];
 694             testCal.clear();
 695             testCal.set(YEAR, y);
 696             testCal.set(WEEK_OF_YEAR, woy);
 697             testCal.set(DAY_OF_WEEK, dow);
 698             System.out.println(y + "-W" + woy + "-DOW" + dow);
 699             if (!testCal.getTime().equals(exp)) {
 700                 System.out.println("  FAILED expect: " + exp + "\n            got: " + testCal.getTime());
 701                 fail = true;
 702             } else {
 703                 System.out.println("  OK");
 704             }
 705         }
 706 
 707         // Now try adding and rolling
 708         Object ADD = new Object();
 709         Object ROLL = new Object();
 710         @SuppressWarnings("deprecation")
 711         Object[] ADDROLL = {
 712             ADD, 1, new Date(98, DECEMBER, 25), new Date(99, JANUARY, 1),
 713             ADD, 1, new Date(97, DECEMBER, 28), new Date(98, JANUARY, 4),
 714             ROLL, 1, new Date(98, DECEMBER, 27), new Date(98, JANUARY, 4),
 715             ROLL, 1, new Date(99, DECEMBER, 24), new Date(99, DECEMBER, 31),
 716             ROLL, 1, new Date(99, DECEMBER, 25), new Date(99, JANUARY, 9)};
 717         testCal.setMinimalDaysInFirstWeek(3);
 718         testCal.setFirstDayOfWeek(SUNDAY);
 719         for (int i = 0; i < ADDROLL.length; i += 4) {
 720             int amount = (Integer) ADDROLL[i + 1];
 721             Date before = (Date) ADDROLL[i + 2];
 722             Date after = (Date) ADDROLL[i + 3];
 723 
 724             testCal.setTime(before);
 725             if (ADDROLL[i] == ADD) {
 726                 testCal.add(WEEK_OF_YEAR, amount);
 727             } else {
 728                 testCal.roll(WEEK_OF_YEAR, amount);
 729             }
 730             System.out.println((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,")
 731                     + amount + ")\t     " + before
 732                     + "\n\t\t  => " + testCal.getTime());
 733             if (!after.equals(testCal.getTime())) {
 734                 System.out.println("\tFAIL\n\t\texp: " + after);
 735                 fail = true;
 736             } else {
 737                 System.out.println("  OK");
 738             }
 739 
 740             testCal.setTime(after);
 741             if (ADDROLL[i] == ADD) {
 742                 testCal.add(WEEK_OF_YEAR, -amount);
 743             } else {
 744                 testCal.roll(WEEK_OF_YEAR, -amount);
 745             }
 746             System.out.println((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,")
 747                     + (-amount) + ")     " + after
 748                     + "\n\t\t  => " + testCal.getTime());
 749             if (!before.equals(testCal.getTime())) {
 750                 System.out.println("\tFAIL\n\t\texp: " + before);
 751                 fail = true;
 752             } else {
 753                 System.out.println("\tOK");
 754             }
 755         }
 756 
 757         if (fail) {
 758             fail("Fail: Week of year misbehaving");
 759         }
 760     }
 761 
 762     @Test
 763     public void Test4106136() {
 764         Locale saveLocale = Locale.getDefault();
 765         try {
 766             Locale[] locales = {Locale.CHINESE, Locale.CHINA};
 767             for (int i = 0; i < locales.length; ++i) {
 768                 Locale.setDefault(locales[i]);
 769                 int[] n = {
 770                     getAvailableLocales().length,
 771                     DateFormat.getAvailableLocales().length,
 772                     NumberFormat.getAvailableLocales().length};
 773                 for (int j = 0; j < n.length; ++j) {
 774                     if (n[j] == 0) {
 775                         fail("Fail: No locales for " + locales[i]);
 776                     }
 777                 }
 778             }
 779         } finally {
 780             Locale.setDefault(saveLocale);
 781         }
 782     }
 783 
 784     @SuppressWarnings("deprecation")
 785     @Test
 786     public void Test4108764() {
 787         Date d00 = new Date(97, MARCH, 15, 12, 00, 00);
 788         Date d01 = new Date(97, MARCH, 15, 12, 00, 56);
 789         Date d10 = new Date(97, MARCH, 15, 12, 34, 00);
 790         Date d11 = new Date(97, MARCH, 15, 12, 34, 56);
 791         Date epoch = new Date(70, JANUARY, 1);
 792 
 793         Calendar cal = Calendar.getInstance();
 794         cal.setTime(d11);
 795 
 796         cal.clear(MINUTE);
 797         System.out.println(cal.getTime().toString());
 798         if (!cal.getTime().equals(d01)) {
 799             fail("Fail: clear(MINUTE) broken");
 800         }
 801 
 802         cal.set(SECOND, 0);
 803         System.out.println(cal.getTime().toString());
 804         if (!cal.getTime().equals(d00)) {
 805             fail("Fail: set(SECOND, 0) broken");
 806         }
 807 
 808         cal.setTime(d11);
 809         cal.set(SECOND, 0);
 810         System.out.println(cal.getTime().toString());
 811         if (!cal.getTime().equals(d10)) {
 812             fail("Fail: set(SECOND, 0) broken #2");
 813         }
 814 
 815         cal.clear(MINUTE);
 816         System.out.println(cal.getTime().toString());
 817         if (!cal.getTime().equals(d00)) {
 818             fail("Fail: clear(MINUTE) broken #2");
 819         }
 820 
 821         cal.clear();
 822         System.out.println(cal.getTime().toString());
 823         if (!cal.getTime().equals(epoch)) {
 824             fail("Fail: clear() broken Want " + epoch);
 825         }
 826     }
 827 
 828     @SuppressWarnings("deprecation")
 829     @Test
 830     public void Test4114578() {
 831         Locale locale = Locale.getDefault();
 832         if (!TestUtils.usesGregorianCalendar(locale)) {
 833             System.out.println("Skipping this test because locale is " + locale);
 834             return;
 835         }
 836 
 837         int ONE_HOUR = 60 * 60 * 1000;
 838         TimeZone saveZone = TimeZone.getDefault();
 839         boolean fail = false;
 840         try {
 841             TimeZone.setDefault(TimeZone.getTimeZone("PST"));
 842             Calendar cal = Calendar.getInstance();
 843             long onset = new Date(98, APRIL, 5, 1, 0).getTime() + ONE_HOUR;
 844             long cease = new Date(98, OCTOBER, 25, 0, 0).getTime() + 2 * ONE_HOUR;
 845 
 846             final int ADD = 1;
 847             final int ROLL = 2;
 848 
 849             long[] DATA = {
 850                 // Start            Action   Amt    Expected_change
 851                 onset - ONE_HOUR,   ADD,      1,     ONE_HOUR,
 852                 onset,              ADD,     -1,    -ONE_HOUR,
 853                 onset - ONE_HOUR,   ROLL,     1,     ONE_HOUR,
 854                 onset,              ROLL,    -1,    -ONE_HOUR,
 855                 cease - ONE_HOUR,   ADD,      1,     ONE_HOUR,
 856                 cease,              ADD,     -1,    -ONE_HOUR,
 857                 // roll() was changed to support wall-clock-based roll (JDK-8152077). The
 858                 // time value may jump 2 hours by skipping non-existent wall-clock time.
 859                 // Note that JDK-4114578 was a problem of add(), not roll().
 860                 cease - ONE_HOUR,   ROLL,     1,     ONE_HOUR * 2,
 861                 cease,              ROLL,    -1,    -ONE_HOUR * 2};
 862 
 863             for (int i = 0; i < DATA.length; i += 4) {
 864                 Date date = new Date(DATA[i]);
 865                 int amt = (int) DATA[i + 2];
 866                 long expectedChange = DATA[i + 3];
 867 
 868                 System.out.println(date.toString());
 869                 cal.setTime(date);
 870 
 871                 switch ((int) DATA[i + 1]) {
 872                     case ADD:
 873                         System.out.println(" add (HOUR," + (amt < 0 ? "" : "+") + amt + ")= ");
 874                         cal.add(HOUR, amt);
 875                         break;
 876                     case ROLL:
 877                         System.out.println(" roll(HOUR," + (amt < 0 ? "" : "+") + amt + ")= ");
 878                         cal.roll(HOUR, amt);
 879                         break;
 880                 }
 881 
 882                 System.out.println(cal.getTime().toString());
 883 
 884                 long change = cal.getTime().getTime() - date.getTime();
 885                 if (change != expectedChange) {
 886                     fail = true;
 887                     System.out.println(" FAIL");
 888                 } else {
 889                     System.out.println(" OK");
 890                 }
 891             }
 892         } finally {
 893             TimeZone.setDefault(saveZone);
 894         }
 895 
 896         if (fail) {
 897             fail("Fail: roll/add misbehaves around DST onset/cease");
 898         }
 899     }
 900 
 901     /**
 902      * Make sure maximum for HOUR field is 11, not 12.
 903      */
 904     @Test
 905     public void Test4118384() {
 906         Calendar cal = Calendar.getInstance();
 907         if (cal.getMaximum(HOUR) != 11
 908                 || cal.getLeastMaximum(HOUR) != 11
 909                 || cal.getActualMaximum(HOUR) != 11) {
 910             fail("Fail: maximum of HOUR field should be 11");
 911         }
 912     }
 913 
 914     /**
 915      * Check isLeapYear for BC years.
 916      */
 917     @Test
 918     public void Test4125881() {
 919         Locale locale = Locale.getDefault();
 920         if (!TestUtils.usesGregorianCalendar(locale)) {
 921             System.out.println("Skipping this test because locale is " + locale);
 922             return;
 923         }
 924 
 925         GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
 926         DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
 927         cal.clear();
 928         for (int y = -20; y <= 10; ++y) {
 929             cal.set(ERA, y < 1 ? GregorianCalendar.BC : GregorianCalendar.AD);
 930             cal.set(YEAR, y < 1 ? 1 - y : y);
 931             System.out.println(y + " = " + fmt.format(cal.getTime()) + " "
 932                     + cal.isLeapYear(y));
 933             if (cal.isLeapYear(y) != ((y + 40) % 4 == 0)) {
 934                 fail("Leap years broken");
 935             }
 936         }
 937     }
 938 
 939     /**
 940      * Prove that GregorianCalendar is proleptic (it used to cut off
 941      * at 45 BC, and not have leap years before then).
 942      */
 943     @Test
 944     public void Test4125892() {
 945         Locale locale = Locale.getDefault();
 946         if (!TestUtils.usesGregorianCalendar(locale)) {
 947             System.out.println("Skipping this test because locale is " + locale);
 948             return;
 949         }
 950 
 951         GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
 952         DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
 953         cal.clear();
 954         cal.set(ERA, GregorianCalendar.BC);
 955         cal.set(YEAR, 81); // 81 BC is a leap year (proleptically)
 956         cal.set(MONTH, FEBRUARY);
 957         cal.set(DATE, 28);
 958         cal.add(DATE, 1);
 959         if (cal.get(DATE) != 29
 960                 || !cal.isLeapYear(-80)) { // -80 == 81 BC
 961             fail("Calendar not proleptic");
 962         }
 963     }
 964 
 965     /**
 966      * Calendar and GregorianCalendar hashCode() methods need improvement.
 967      * Calendar needs a good implementation that subclasses can override,
 968      * and GregorianCalendar should use that implementation.
 969      */
 970     @Test
 971     public void Test4136399() {
 972         /* Note: This test is actually more strict than it has to be.
 973         * Technically, there is no requirement that unequal objects have
 974         * unequal hashes.  We only require equal objects to have equal hashes.
 975         * It is desirable for unequal objects to have distributed hashes, but
 976         * there is no hard requirement here.
 977         *
 978         * In this test we make assumptions about certain attributes of calendar
 979         * objects getting represented in the hash, which need not always be the
 980         * case (although it does work currently with the given test). */
 981         Calendar a = Calendar.getInstance();
 982         Calendar b = (Calendar) a.clone();
 983         if (a.hashCode() != b.hashCode()) {
 984             fail("Calendar hash code unequal for cloned objects");
 985         }
 986 
 987         b.setMinimalDaysInFirstWeek(7 - a.getMinimalDaysInFirstWeek());
 988         if (a.hashCode() == b.hashCode()) {
 989             fail("Calendar hash code ignores minimal days in first week");
 990         }
 991         b.setMinimalDaysInFirstWeek(a.getMinimalDaysInFirstWeek());
 992 
 993         b.setFirstDayOfWeek((a.getFirstDayOfWeek() % 7) + 1); // Next day
 994         if (a.hashCode() == b.hashCode()) {
 995             fail("Calendar hash code ignores first day of week");
 996         }
 997         b.setFirstDayOfWeek(a.getFirstDayOfWeek());
 998 
 999         b.setLenient(!a.isLenient());
1000         if (a.hashCode() == b.hashCode()) {
1001             fail("Calendar hash code ignores lenient setting");
1002         }
1003         b.setLenient(a.isLenient());
1004 
1005         // Assume getTimeZone() returns a reference, not a clone
1006         // of a reference -- this is true as of this writing
1007         b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset() + 60 * 60 * 1000);
1008         if (a.hashCode() == b.hashCode()) {
1009             fail("Calendar hash code ignores zone");
1010         }
1011         b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset());
1012 
1013         GregorianCalendar c = new GregorianCalendar();
1014         GregorianCalendar d = (GregorianCalendar) c.clone();
1015         if (c.hashCode() != d.hashCode()) {
1016             fail("GregorianCalendar hash code unequal for clones objects");
1017         }
1018         Date cutover = c.getGregorianChange();
1019         d.setGregorianChange(new Date(cutover.getTime() + 24 * 60 * 60 * 1000));
1020         if (c.hashCode() == d.hashCode()) {
1021             fail("GregorianCalendar hash code ignores cutover");
1022         }
1023     }
1024 
1025     /**
1026      * GregorianCalendar.equals() ignores cutover date
1027      */
1028     @Test
1029     public void Test4141665() {
1030         GregorianCalendar cal = new GregorianCalendar();
1031         GregorianCalendar cal2 = (GregorianCalendar) cal.clone();
1032         Date cut = cal.getGregorianChange();
1033         Date cut2 = new Date(cut.getTime() + 100 * 24 * 60 * 60 * 1000L); // 100 days later
1034         if (!cal.equals(cal2)) {
1035             fail("Cloned GregorianCalendars not equal");
1036         }
1037         cal2.setGregorianChange(cut2);
1038         if (cal.equals(cal2)) {
1039             fail("GregorianCalendar.equals() ignores cutover");
1040         }
1041     }
1042 
1043     /**
1044      * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar.roll()
1045      * when IllegalArgumentException should be.
1046      */
1047     @Test
1048     public void Test4142933() {
1049         GregorianCalendar calendar = new GregorianCalendar();
1050         try {
1051             calendar.roll(-1, true);
1052             fail("Test failed, no exception trown");
1053         } catch (IllegalArgumentException e) {
1054             // OK: Do nothing
1055             // logln("Test passed");
1056         } catch (Exception e) {
1057             fail("Test failed. Unexpected exception is thrown: " + e);
1058             e.printStackTrace();
1059         }
1060     }
1061 
1062     /**
1063      * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1064      * confusing; unless the time zone has a raw offset of zero, one or the
1065      * other of these will wrap.  We've modified the test given in the bug
1066      * report to therefore only check the behavior of a calendar with a zero raw
1067      * offset zone.
1068      */
1069     @Test
1070     public void Test4145158() {
1071         GregorianCalendar calendar = new GregorianCalendar();
1072 
1073         calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
1074 
1075         calendar.setTime(new Date(Long.MIN_VALUE));
1076         int year1 = calendar.get(YEAR);
1077         int era1 = calendar.get(ERA);
1078 
1079         calendar.setTime(new Date(Long.MAX_VALUE));
1080         int year2 = calendar.get(YEAR);
1081         int era2 = calendar.get(ERA);
1082 
1083         if (year1 == year2 && era1 == era2) {
1084             fail("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1085         }
1086     }
1087 
1088     /**
1089      * Maximum value for YEAR field wrong.
1090      */
1091     @Test
1092     public void Test4145983() {
1093         GregorianCalendar calendar = new GregorianCalendar();
1094         calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
1095         Date[] DATES = {new Date(Long.MAX_VALUE), new Date(Long.MIN_VALUE)};
1096         for (int i = 0; i < DATES.length; ++i) {
1097             calendar.setTime(DATES[i]);
1098             int year = calendar.get(YEAR);
1099             int maxYear = calendar.getMaximum(YEAR);
1100             if (year > maxYear) {
1101                 fail("Failed for " + DATES[i].getTime() + " ms: year="
1102                         + year + ", maxYear=" + maxYear);
1103             }
1104         }
1105     }
1106 
1107     /**
1108      * This is a bug in the validation code of GregorianCalendar.  As reported,
1109      * the bug seems worse than it really is, due to a bug in the way the bug
1110      * report test was written.  In reality the bug is restricted to the DAY_OF_YEAR
1111      * field. - liu 6/29/98
1112      */
1113     @Test
1114     public void Test4147269() {
1115         final String[] fieldName = {
1116             "ERA",
1117             "YEAR",
1118             "MONTH",
1119             "WEEK_OF_YEAR",
1120             "WEEK_OF_MONTH",
1121             "DAY_OF_MONTH",
1122             "DAY_OF_YEAR",
1123             "DAY_OF_WEEK",
1124             "DAY_OF_WEEK_IN_MONTH",
1125             "AM_PM",
1126             "HOUR",
1127             "HOUR_OF_DAY",
1128             "MINUTE",
1129             "SECOND",
1130             "MILLISECOND",
1131             "ZONE_OFFSET",
1132             "DST_OFFSET"};
1133         GregorianCalendar calendar = new GregorianCalendar();
1134         calendar.setLenient(false);
1135         @SuppressWarnings("deprecation")
1136         Date date = new Date(1996 - 1900, JANUARY, 3); // Arbitrary date
1137         for (int field = 0; field < FIELD_COUNT; field++) {
1138             calendar.setTime(date);
1139             // Note: In the bug report, getActualMaximum() was called instead
1140             // of getMaximum() -- this was an error.  The validation code doesn't
1141             // use getActualMaximum(), since that's too costly.
1142             int max = calendar.getMaximum(field);
1143             int value = max + 1;
1144             calendar.set(field, value);
1145             try {
1146                 calendar.getTime(); // Force time computation
1147                 // We expect an exception to be thrown. If we fall through
1148                 // to the next line, then we have a bug.
1149                 fail("Test failed with field " + fieldName[field]
1150                         + ", date before: " + date
1151                         + ", date after: " + calendar.getTime()
1152                         + ", value: " + value + " (max = " + max + ")");
1153             } catch (IllegalArgumentException e) {
1154             }
1155         }
1156     }
1157 
1158     /**
1159      * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
1160      * doesn't behave as a pure Julian calendar.
1161      * CANNOT REPRODUCE THIS BUG
1162      */
1163     @Test
1164     public void Test4149677() {
1165         TimeZone[] zones = {TimeZone.getTimeZone("GMT"),
1166             TimeZone.getTimeZone("PST"),
1167             TimeZone.getTimeZone("EAT")};
1168         for (int i = 0; i < zones.length; ++i) {
1169             GregorianCalendar calendar = new GregorianCalendar(zones[i]);
1170 
1171             // Make sure extreme values don't wrap around
1172             calendar.setTime(new Date(Long.MIN_VALUE));
1173             if (calendar.get(ERA) != GregorianCalendar.BC) {
1174                 fail("Fail: Date(Long.MIN_VALUE) has an AD year in " + zones[i]);
1175             }
1176             calendar.setTime(new Date(Long.MAX_VALUE));
1177             if (calendar.get(ERA) != GregorianCalendar.AD) {
1178                 fail("Fail: Date(Long.MAX_VALUE) has a BC year in " + zones[i]);
1179             }
1180 
1181             calendar.setGregorianChange(new Date(Long.MAX_VALUE));
1182             // to obtain a pure Julian calendar
1183 
1184             boolean is100Leap = calendar.isLeapYear(100);
1185             if (!is100Leap) {
1186                 fail("test failed with zone " + zones[i].getID()
1187                 + "\n cutover date is Date(Long.MAX_VALUE)"
1188                 + "\n isLeapYear(100) returns: " + is100Leap);
1189             }
1190         }
1191     }
1192 
1193     /**
1194      * Calendar and Date HOUR broken.  If HOUR is out-of-range, Calendar
1195      * and Date classes will misbehave.
1196      */
1197     @Test
1198     public void Test4162587() {
1199         TimeZone savedTz = TimeZone.getDefault();
1200         TimeZone tz = TimeZone.getTimeZone("PST");
1201         TimeZone.setDefault(tz);
1202         GregorianCalendar cal = new GregorianCalendar(tz);
1203         Date d;
1204 
1205         try {
1206             for (int i = 0; i < 5; ++i) {
1207                 if (i > 0) {
1208                     System.out.println("---");
1209                 }
1210 
1211                 cal.clear();
1212                 cal.set(1998, APRIL, 5, i, 0);
1213                 d = cal.getTime();
1214                 String s0 = d.toString();
1215                 System.out.println("0 " + i + ": " + s0);
1216 
1217                 cal.clear();
1218                 cal.set(1998, APRIL, 4, i + 24, 0);
1219                 d = cal.getTime();
1220                 String sPlus = d.toString();
1221                 System.out.println("+ " + i + ": " + sPlus);
1222 
1223                 cal.clear();
1224                 cal.set(1998, APRIL, 6, i - 24, 0);
1225                 d = cal.getTime();
1226                 String sMinus = d.toString();
1227                 System.out.println("- " + i + ": " + sMinus);
1228 
1229                 if (!s0.equals(sPlus) || !s0.equals(sMinus)) {
1230                     fail("Fail: All three lines must match");
1231                 }
1232             }
1233         } finally {
1234             TimeZone.setDefault(savedTz);
1235         }
1236     }
1237 
1238     /**
1239      * Adding 12 months behaves differently from adding 1 year
1240      */
1241     @Test
1242     public void Test4165343() {
1243         GregorianCalendar calendar = new GregorianCalendar(1996, FEBRUARY, 29);
1244         Date start = calendar.getTime();
1245         System.out.println("init date: " + start);
1246         calendar.add(MONTH, 12);
1247         Date date1 = calendar.getTime();
1248         System.out.println("after adding 12 months: " + date1);
1249         calendar.setTime(start);
1250         calendar.add(YEAR, 1);
1251         Date date2 = calendar.getTime();
1252         System.out.println("after adding one year : " + date2);
1253         if (date1.equals(date2)) {
1254             System.out.println("Test passed");
1255         } else {
1256             fail("Test failed");
1257         }
1258     }
1259 
1260     /**
1261      * GregorianCalendar.getActualMaximum() does not account for first day of week.
1262      */
1263     @Test
1264     public void Test4166109() {
1265         /* Test month:
1266         *
1267         *      March 1998
1268         * Su Mo Tu We Th Fr Sa
1269         *  1  2  3  4  5  6  7
1270         *  8  9 10 11 12 13 14
1271         * 15 16 17 18 19 20 21
1272         * 22 23 24 25 26 27 28
1273         * 29 30 31
1274          */
1275         boolean passed = true;
1276         int field = WEEK_OF_MONTH;
1277 
1278         GregorianCalendar calendar = new GregorianCalendar(Locale.US);
1279         calendar.set(1998, MARCH, 1);
1280         calendar.setMinimalDaysInFirstWeek(1);
1281         System.out.println("Date:  " + calendar.getTime());
1282 
1283         int firstInMonth = calendar.get(DAY_OF_MONTH);
1284 
1285         for (int firstInWeek = SUNDAY; firstInWeek <= SATURDAY; firstInWeek++) {
1286             calendar.setFirstDayOfWeek(firstInWeek);
1287             int returned = calendar.getActualMaximum(field);
1288             int expected = (31 + ((firstInMonth - firstInWeek + 7) % 7) + 6) / 7;
1289 
1290             System.out.println("First day of week = " + firstInWeek
1291                     + "  getActualMaximum(WEEK_OF_MONTH) = " + returned
1292                     + "  expected = " + expected
1293                     + ((returned == expected) ? "  ok" : "  FAIL"));
1294 
1295             if (returned != expected) {
1296                 passed = false;
1297             }
1298         }
1299         if (!passed) {
1300             fail("Test failed");
1301         }
1302     }
1303 
1304     /**
1305      * Calendar.getActualMaximum(YEAR) works wrong.
1306      *
1307      * Note: Before 1.5, this test case assumed that
1308      * setGregorianChange didn't change object's date. But it was
1309      * changed. See 4928615.
1310      */
1311     @Test
1312     public void Test4167060() {
1313         int field = YEAR;
1314         DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy G",
1315                 Locale.US);
1316 
1317         int[][] dates = {
1318             // year, month, day of month
1319             {100, NOVEMBER, 1},
1320             {-99 /*100BC*/, JANUARY, 1},
1321             {1996, FEBRUARY, 29}};
1322 
1323         String[] id = {"Hybrid", "Gregorian", "Julian"};
1324 
1325         for (int k = 0; k < 3; ++k) {
1326             System.out.println("--- " + id[k] + " ---");
1327 
1328             for (int j = 0; j < dates.length; ++j) {
1329                 GregorianCalendar calendar = new GregorianCalendar();
1330                 if (k == 1) {
1331                     calendar.setGregorianChange(new Date(Long.MIN_VALUE));
1332                 } else if (k == 2) {
1333                     calendar.setGregorianChange(new Date(Long.MAX_VALUE));
1334                 }
1335                 calendar.set(dates[j][0], dates[j][1], dates[j][2]);
1336                 format.setCalendar((Calendar) calendar.clone());
1337 
1338                 Date dateBefore = calendar.getTime();
1339 
1340                 int maxYear = calendar.getActualMaximum(field);
1341                 System.out.println("maxYear: " + maxYear + " for " + format.format(calendar.getTime()));
1342                 System.out.println("date before: " + format.format(dateBefore));
1343 
1344                 int[] years = {2000, maxYear - 1, maxYear, maxYear + 1};
1345 
1346                 for (int i = 0; i < years.length; i++) {
1347                     boolean valid = years[i] <= maxYear;
1348                     calendar.set(field, years[i]);
1349                     Date dateAfter = calendar.getTime();
1350                     int newYear = calendar.get(field);
1351                     calendar.setTime(dateBefore); // restore calendar for next use
1352 
1353                     System.out.println(" Year " + years[i] + (valid ? " ok " : " bad")
1354                             + " => " + format.format(dateAfter));
1355                     if (valid && newYear != years[i]) {
1356                         fail("  FAIL: " + newYear + " should be valid; date, month and time shouldn't change");
1357                     } else if (!valid && newYear == years[i]) {
1358                         fail("  FAIL: " + newYear + " should be invalid");
1359                     }
1360                 }
1361             }
1362         }
1363     }
1364 
1365     /**
1366      * Calendar.roll broken
1367      * This bug relies on the TimeZone bug 4173604 to also be fixed.
1368      */
1369     @Test
1370     public void Test4173516() {
1371         Locale locale = Locale.getDefault();
1372         if (!TestUtils.usesGregorianCalendar(locale)) {
1373             System.out.println("Skipping this test because locale is " + locale);
1374             return;
1375         }
1376 
1377         int[][] fieldsList = {
1378             {1997, FEBRUARY, 1, 10, 45, 15, 900},
1379             {1999, DECEMBER, 22, 23, 59, 59, 999},
1380             // test case for 4960642 with default cutover
1381             {1582, OCTOBER, 4, 23, 59, 59, 999}};
1382         String[] fieldNames = {
1383             "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",
1384             "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH",
1385             "AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND",
1386             "ZONE_OFFSET", "DST_OFFSET"};
1387 
1388         Locale savedLocale = Locale.getDefault();
1389         Locale.setDefault(Locale.US);
1390         int limit = 40;
1391 
1392         try {
1393             GregorianCalendar cal = new GregorianCalendar();
1394 
1395             cal.setTime(new Date(0));
1396             cal.roll(HOUR, 0x7F000000);
1397             cal.roll(HOUR, -0x7F000000);
1398             if (cal.getTime().getTime() != 0) {
1399                 fail("Hour rolling broken. expected 0, got " + cal.getTime().getTime());
1400             }
1401 
1402             for (int op = 0; op < 2; ++op) {
1403                 System.out.println("Testing GregorianCalendar " + (op == 0 ? "add" : "roll"));
1404 
1405                 for (int field = 0; field < FIELD_COUNT; ++field) {
1406                     if (field != ZONE_OFFSET
1407                             && field != DST_OFFSET) {
1408                         for (int j = 0; j < fieldsList.length; ++j) {
1409                             int[] fields = fieldsList[j];
1410                             cal.clear();
1411                             cal.set(fields[0], fields[1], fields[2],
1412                                     fields[3], fields[4], fields[5]);
1413                             cal.set(MILLISECOND, fields[6]);
1414                             for (int i = 0; i < 2 * limit; i++) {
1415                                 if (op == 0) {
1416                                     cal.add(field, i < limit ? 1 : -1);
1417                                 } else {
1418                                     cal.roll(field, i < limit ? 1 : -1);
1419                                 }
1420                             }
1421 
1422                             if (cal.get(YEAR) != fields[0]
1423                                     || cal.get(MONTH) != fields[1]
1424                                     || cal.get(DATE) != fields[2]
1425                                     || cal.get(HOUR_OF_DAY) != fields[3]
1426                                     || cal.get(MINUTE) != fields[4]
1427                                     || cal.get(SECOND) != fields[5]
1428                                     || cal.get(MILLISECOND) != fields[6]) {
1429                                 fail("Field " + field
1430                                         + " (" + fieldNames[field]
1431                                         + ") FAIL, expected "
1432                                         + fields[0]
1433                                         + "/" + (fields[1] + 1)
1434                                         + "/" + fields[2]
1435                                         + " " + fields[3]
1436                                         + ":" + fields[4]
1437                                         + ":" + fields[5]
1438                                         + "." + fields[6]
1439                                         + ", got " + cal.get(YEAR)
1440                                         + "/" + (cal.get(MONTH) + 1)
1441                                         + "/" + cal.get(DATE)
1442                                         + " " + cal.get(HOUR_OF_DAY)
1443                                         + ":" + cal.get(MINUTE)
1444                                         + ":" + cal.get(SECOND)
1445                                         + "." + cal.get(MILLISECOND));
1446 
1447                                 cal.clear();
1448                                 cal.set(fields[0], fields[1], fields[2],
1449                                         fields[3], fields[4], fields[5]);
1450                                 cal.set(MILLISECOND, fields[6]);
1451                                 fail(cal.get(YEAR)
1452                                         + "/" + (cal.get(MONTH) + 1)
1453                                         + "/" + cal.get(DATE)
1454                                         + " " + cal.get(HOUR_OF_DAY)
1455                                         + ":" + cal.get(MINUTE)
1456                                         + ":" + cal.get(SECOND)
1457                                         + "." + cal.get(MILLISECOND));
1458 
1459                                 long prev = cal.getTime().getTime();
1460                                 for (int i = 0; i < 2 * limit; i++) {
1461                                     if (op == 0) {
1462                                         cal.add(field, i < limit ? 1 : -1);
1463                                     } else {
1464                                         cal.roll(field, i < limit ? 1 : -1);
1465                                     }
1466                                     long t = cal.getTime().getTime();
1467                                     long delta = t - prev;
1468                                     prev = t;
1469                                     fail((op == 0 ? "add(" : "roll(")
1470                                             + fieldNames[field] + ", "
1471                                             + (i < limit ? "+" : "-") + "1) => "
1472                                             + cal.get(YEAR)
1473                                             + "/" + (cal.get(MONTH) + 1)
1474                                             + "/" + cal.get(DATE)
1475                                             + " " + cal.get(HOUR_OF_DAY)
1476                                             + ":" + cal.get(MINUTE)
1477                                             + ":" + cal.get(SECOND)
1478                                             + "." + cal.get(MILLISECOND)
1479                                             + " d=" + delta);
1480                                 }
1481                             }
1482                         }
1483                     }
1484                 }
1485             }
1486         } finally {
1487             Locale.setDefault(savedLocale);
1488         }
1489     }
1490 
1491     @Test
1492     public void Test4174361() {
1493         GregorianCalendar calendar = new GregorianCalendar(1996, 1, 29);
1494 
1495         calendar.add(MONTH, 10);
1496         Date date1 = calendar.getTime();
1497         int d1 = calendar.get(DAY_OF_MONTH);
1498 
1499         calendar = new GregorianCalendar(1996, 1, 29);
1500         calendar.add(MONTH, 11);
1501         Date date2 = calendar.getTime();
1502         int d2 = calendar.get(DAY_OF_MONTH);
1503 
1504         if (d1 != d2) {
1505             fail("adding months to Feb 29 broken");
1506         }
1507     }
1508 
1509     /**
1510      * Calendar does not update field values when setTimeZone is called.
1511      */
1512     @Test
1513     public void Test4177484() {
1514         TimeZone PST = TimeZone.getTimeZone("PST");
1515         TimeZone EST = TimeZone.getTimeZone("EST");
1516 
1517         Calendar cal = Calendar.getInstance(PST, Locale.US);
1518         cal.clear();
1519         cal.set(1999, 3, 21, 15, 5, 0); // Arbitrary
1520         int h1 = cal.get(HOUR_OF_DAY);
1521         cal.setTimeZone(EST);
1522         int h2 = cal.get(HOUR_OF_DAY);
1523         if (h1 == h2) {
1524             fail("FAIL: Fields not updated after setTimeZone");
1525         }
1526 
1527         // getTime() must NOT change when time zone is changed.
1528         // getTime() returns zone-independent time in ms.
1529         cal.clear();
1530         cal.setTimeZone(PST);
1531         cal.set(HOUR_OF_DAY, 10);
1532         Date pst10 = cal.getTime();
1533         cal.setTimeZone(EST);
1534         Date est10 = cal.getTime();
1535         if (!pst10.equals(est10)) {
1536             fail("FAIL: setTimeZone changed time");
1537         }
1538     }
1539 
1540     /**
1541      * Week of year is wrong at the start and end of the year.
1542      */
1543     @Test
1544     public void Test4197699() {
1545         GregorianCalendar cal = new GregorianCalendar();
1546         cal.setFirstDayOfWeek(MONDAY);
1547         cal.setMinimalDaysInFirstWeek(4);
1548         DateFormat fmt = new SimpleDateFormat("E dd MMM yyyy  'DOY='D 'WOY='w");
1549         fmt.setCalendar(cal);
1550 
1551         int[] DATA = {
1552             2000, JANUARY, 1, 52,
1553             2001, DECEMBER, 31, 1};
1554 
1555         for (int i = 0; i < DATA.length;) {
1556             cal.set(DATA[i++], DATA[i++], DATA[i++]);
1557             int expWOY = DATA[i++];
1558             int actWOY = cal.get(WEEK_OF_YEAR);
1559             if (expWOY == actWOY) {
1560                 System.out.println("Ok: " + fmt.format(cal.getTime()));
1561             } else {
1562                 fail("FAIL: " + fmt.format(cal.getTime())
1563                         + ", expected WOY=" + expWOY);
1564                 cal.add(DATE, -8);
1565                 for (int j = 0; j < 14; ++j) {
1566                     cal.add(DATE, 1);
1567                     System.out.println(fmt.format(cal.getTime()));
1568                 }
1569             }
1570         }
1571     }
1572 
1573     /**
1574      * Calendar DAY_OF_WEEK_IN_MONTH fields->time broken.  The problem
1575      * is in the field disambiguation code in GregorianCalendar.  This
1576      * code is supposed to choose the most recent set of fields
1577      * among the following:
1578      *
1579      *   MONTH + DAY_OF_MONTH
1580      *   MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
1581      *   MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
1582      *   DAY_OF_YEAR
1583      *   WEEK_OF_YEAR + DAY_OF_WEEK
1584      */
1585     @SuppressWarnings("deprecation")
1586     @Test
1587     public void Test4209071() {
1588         Calendar cal = Calendar.getInstance(Locale.US);
1589 
1590         // General field setting test
1591         int Y = 1995 - 1900;
1592 
1593         Object[] FIELD_DATA = {
1594             // Add new test cases as needed.
1595 
1596             // 0
1597             new int[]{}, new Date(Y, JANUARY, 1),
1598             // 1
1599             new int[]{MONTH, MARCH},
1600             new Date(Y, MARCH, 1),
1601             // 2
1602             new int[]{DAY_OF_WEEK, WEDNESDAY},
1603             new Date(Y, JANUARY, 4),
1604             // 3
1605             new int[]{DAY_OF_WEEK, THURSDAY,
1606                 DAY_OF_MONTH, 18,},

1643                 DAY_OF_MONTH, 15,
1644                 DAY_OF_YEAR, 222,},
1645             new Date(Y, AUGUST, 10),
1646             // 12
1647             new int[]{DAY_OF_WEEK, THURSDAY,
1648                 MONTH, DECEMBER,},
1649             new Date(Y, DECEMBER, 7)};
1650 
1651         for (int i = 0; i < FIELD_DATA.length; i += 2) {
1652             int[] fields = (int[]) FIELD_DATA[i];
1653             Date exp = (Date) FIELD_DATA[i + 1];
1654 
1655             cal.clear();
1656             cal.set(YEAR, Y + 1900);
1657             for (int j = 0; j < fields.length; j += 2) {
1658                 cal.set(fields[j], fields[j + 1]);
1659             }
1660 
1661             Date act = cal.getTime();
1662             if (!act.equals(exp)) {
1663                 fail("FAIL: Test " + (i / 2) + " got " + act
1664                         + ", want " + exp
1665                         + " (see test/java/util/Calendar/CalendarRegression.java");
1666             }
1667         }
1668 
1669         // Test specific failure reported in bug
1670         @SuppressWarnings("deprecation")
1671         Object[] DATA = {
1672             1, new Date(1997 - 1900, JANUARY, 5),
1673             4, new Date(1997 - 1900, JANUARY, 26),
1674             8, new Date(1997 - 1900, FEBRUARY, 23),
1675             -1, new Date(1997 - 1900, JANUARY, 26),
1676             -4, new Date(1997 - 1900, JANUARY, 5),
1677             -8, new Date(1996 - 1900, DECEMBER, 8)};
1678         for (int i = 0; i < DATA.length; i += 2) {
1679             cal.clear();
1680             cal.set(DAY_OF_WEEK_IN_MONTH,
1681                     ((Number) DATA[i]).intValue());
1682             cal.set(DAY_OF_WEEK, SUNDAY);
1683             cal.set(MONTH, JANUARY);
1684             cal.set(YEAR, 1997);
1685             Date actual = cal.getTime();
1686             if (!actual.equals(DATA[i + 1])) {
1687                 fail("FAIL: Sunday " + DATA[i]
1688                         + " of Jan 1997 -> " + actual
1689                         + ", want " + DATA[i + 1]);
1690             }
1691         }
1692     }
1693 
1694     @Test
1695     public void Test4288792() throws Exception {
1696         TimeZone savedTZ = TimeZone.getDefault();
1697         TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
1698         GregorianCalendar cal = new GregorianCalendar();
1699         try {
1700             for (int i = 1900; i < 2100; i++) {
1701                 for (int j1 = 1; j1 <= 7; j1++) {
1702                     // Loop for MinimalDaysInFirstWeek: 1..7
1703                     for (int j = SUNDAY; j <= SATURDAY; j++) {
1704                         // Loop for FirstDayOfWeek: SUNDAY..SATURDAY
1705                         cal.clear();
1706                         cal.setMinimalDaysInFirstWeek(j1);
1707                         cal.setFirstDayOfWeek(j);
1708                         cal.set(YEAR, i);
1709                         int maxWeek = cal.getActualMaximum(WEEK_OF_YEAR);
1710                         cal.set(WEEK_OF_YEAR, maxWeek);
1711                         cal.set(DAY_OF_WEEK, j);
1712 
1713                         for (int k = 1; k < 7; k++) {
1714                             cal.add(DATE, 1);
1715                             int WOY = cal.get(WEEK_OF_YEAR);
1716                             if (WOY != maxWeek) {
1717                                 fail(cal.getTime() + ",got=" + WOY
1718                                         + ",expected=" + maxWeek
1719                                         + ",min=" + j1 + ",first=" + j);
1720                             }
1721                         }
1722 
1723                         cal.add(DATE, 1);
1724                         int WOY = cal.get(WEEK_OF_YEAR);
1725                         if (WOY != 1) {
1726                             fail(cal.getTime() + ",got=" + WOY
1727                                     + ",expected=1,min=" + j1 + ",first" + j);
1728                         }
1729                     }
1730                 }
1731             }
1732         } finally {
1733             TimeZone.setDefault(savedTZ);
1734         }
1735     }
1736 
1737     @Test
1738     public void Test4328747() throws Exception {
1739         Calendar c = Calendar.getInstance(Locale.US);
1740         c.clear();
1741         c.set(1966, 0, 1); // 1 jan 1966
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         Calendar result = (Calendar) t.readObject();
1752 
1753         // let recalculate fields with the same UTC time
1754         result.setTime(result.getTime());
1755         // Bug gives 1965 11 19
1756         if ((result.get(YEAR) != 1966) || (result.get(MONTH) != 0)
1757                 || (result.get(DATE) != 1)) {
1758             fail("deserialized Calendar returned wrong date field(s): "
1759                     + result.get(YEAR) + "/" + result.get(MONTH) + "/" + result.get(DATE)
1760                     + ", expected 1966/0/1");
1761         }
1762     }
1763 
1764     /**
1765      * Test whether Calendar can be serialized/deserialized correctly
1766      * even if invalid/customized TimeZone is used.
1767      */
1768     @Test
1769     public void Test4413980() {
1770         TimeZone savedTimeZone = TimeZone.getDefault();
1771         try {
1772             boolean pass = true;
1773             String[] IDs = new String[]{"Undefined", "PST", "US/Pacific",
1774                 "GMT+3:00", "GMT-01:30"};
1775             for (int i = 0; i < IDs.length; i++) {
1776                 TimeZone tz = TimeZone.getTimeZone(IDs[i]);
1777                 TimeZone.setDefault(tz);
1778 
1779                 Calendar c = Calendar.getInstance();
1780 
1781                 // serialize
1782                 ByteArrayOutputStream out = new ByteArrayOutputStream();
1783                 ObjectOutputStream s = new ObjectOutputStream(out);
1784                 s.writeObject(c);
1785                 s.flush();
1786 
1787                 // deserialize
1788                 ObjectInputStream t = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
1789 
1790                 if (!c.equals(t.readObject())) {
1791                     pass = false;
1792                     System.out.println("Calendar instance which uses TimeZone <"
1793                             + IDs[i] + "> is incorrectly serialized/deserialized.");
1794                 } else {
1795                     System.out.println("Calendar instance which uses TimeZone <"
1796                             + IDs[i] + "> is correctly serialized/deserialized.");
1797                 }
1798             }
1799             if (!pass) {
1800                 fail("Fail: Calendar serialization/equality bug");
1801             }
1802         } catch (IOException | ClassNotFoundException e) {
1803             fail("Fail: " + e);
1804             e.printStackTrace();
1805         } finally {
1806             TimeZone.setDefault(savedTimeZone);
1807         }
1808     }
1809 
1810     /**
1811      * 4546637: Incorrect WEEK_OF_MONTH after changing First Day Of Week
1812      */
1813     @Test
1814     public void Test4546637() {
1815         GregorianCalendar day = new GregorianCalendar(2001, NOVEMBER, 04);
1816         day.setMinimalDaysInFirstWeek(1);
1817         int wom = day.get(WEEK_OF_MONTH);
1818 
1819         day.setFirstDayOfWeek(MONDAY);
1820         if (day.get(WEEK_OF_MONTH) != 1) {
1821             fail("Fail: 2001/11/4 must be the first week of the month.");
1822         }
1823     }
1824 
1825     /**
1826      * 4623997: GregorianCalendar returns bad WEEK_OF_YEAR
1827      */
1828     @Test
1829     public void Test4623997() {
1830         GregorianCalendar cal = new GregorianCalendar(2000, JANUARY, 1);
1831 
1832         int dow = cal.get(DAY_OF_WEEK);
1833 
1834         cal.setFirstDayOfWeek(MONDAY);
1835         cal.setMinimalDaysInFirstWeek(4);
1836 
1837         if (cal.get(WEEK_OF_YEAR) != 52) {
1838             fail("Fail: 2000/1/1 must be the 52nd week of the year.");
1839         }
1840     }
1841 
1842     /**
1843      * 4685354: Handling of Calendar fields setting state is broken
1844      *
1845      * <p>Need to use SimpleDateFormat to test because a call to
1846      * get(int) changes internal states of a Calendar.
1847      */
1848     @Test
1849     public void Test4685354() {
1850         Locale locale = Locale.getDefault();
1851         if (!TestUtils.usesAsciiDigits(locale)
1852                 || !TestUtils.usesGregorianCalendar(locale)) {
1853             System.out.println("Skipping this test because locale is " + locale);
1854             return;
1855         }
1856 
1857         Calendar calendar = Calendar.getInstance(Locale.US);
1858         DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);
1859         String expected = "1999/12/31";
1860         Date t;
1861         String s;
1862 
1863         try {
1864             calendar.setTime(df.parse(expected));
1865         } catch (Exception e) {
1866             throw new RuntimeException("Unexpected parse exception", e);
1867         }
1868 
1869         t = calendar.getTime();
1870         calendar.set(DAY_OF_MONTH, 33);
1871         t = calendar.getTime();
1872         calendar.set(DAY_OF_MONTH, 0);
1873         s = df.format(calendar.getTime());
1874         if (!expected.equals(s)) {
1875             fail("DAY_OF_MONTH w/o ZONE_OFFSET: expected: " + expected + ", got: " + s);
1876         }
1877 
1878         // The same thing must work with ZONE_OFFSET set
1879         try {
1880             calendar.setTime(df.parse(expected));
1881         } catch (Exception e) {
1882             throw new RuntimeException("Unexpected parse exception", e);
1883         }
1884         t = calendar.getTime();
1885         calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET));
1886         calendar.set(DAY_OF_MONTH, 33);
1887         t = calendar.getTime();
1888         calendar.set(DAY_OF_MONTH, 0);
1889         s = df.format(calendar.getTime());
1890         if (!expected.equals(s)) {
1891             fail("DAY_OF_MONTH: expected: " + expected + ", got: " + s);
1892         }
1893 
1894         expected = "1999/12/24"; // 0th week of 2000
1895         calendar.clear();
1896         Date initialDate = null;
1897         try {
1898             initialDate = df.parse(expected);
1899             calendar.setTime(initialDate);
1900         } catch (Exception e) {
1901             throw new RuntimeException("Unexpected parse exception", e);
1902         }
1903         t = calendar.getTime();
1904         calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET));
1905         // jump to the next year
1906         calendar.set(WEEK_OF_YEAR, 100);
1907         t = calendar.getTime();
1908         calendar.set(WEEK_OF_YEAR, 0);
1909         s = df.format(calendar.getTime());
1910         if (!expected.equals(s)) {
1911             fail("WEEK_OF_YEAR: expected: " + expected + ", got: " + s);
1912         }
1913         // change the state back
1914         calendar.clear();
1915         calendar.setTime(initialDate);
1916         calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET));
1917         // jump to next month
1918         calendar.set(WEEK_OF_MONTH, 7);
1919         t = calendar.getTime();
1920         calendar.set(WEEK_OF_MONTH, 0);
1921         s = df.format(calendar.getTime());
1922         if (!expected.equals(s)) {
1923             fail("WEEK_OF_MONTH: expected: " + expected + ", got: " + s);
1924         }
1925 
1926         // Make sure the time fields work correctly.
1927         calendar.clear();
1928         df = new SimpleDateFormat("HH:mm:ss");
1929         TimeZone tz = TimeZone.getTimeZone("GMT");
1930         df.setTimeZone(tz);
1931         calendar.setTimeZone(tz);
1932         expected = "22:59:59";
1933         try {
1934             calendar.setTime(df.parse(expected));
1935         } catch (Exception e) {
1936             throw new RuntimeException("Unexpected parse exception", e);
1937         }
1938         t = calendar.getTime();
1939         // time should be 22:59:59.
1940         calendar.set(MINUTE, 61);
1941         // time should be 23:01:59.
1942         t = calendar.getTime();
1943         calendar.set(MINUTE, -1);
1944         // time should be back to 22:59:59.
1945         s = df.format(calendar.getTime());
1946         if (!expected.equals(s)) {
1947             fail("MINUTE: expected: " + expected + ", got: " + s);
1948         }
1949     }
1950 
1951     /**
1952      * 4655637: Calendar.set() for DAY_OF_WEEK does not return the right value
1953      *
1954      * <p>Need to use SimpleDateFormat to test because a call to
1955      * get(int) changes internal states of a Calendar.
1956      */
1957     @Test
1958     public void Test4655637() {
1959         Locale locale = Locale.getDefault();
1960         if (!TestUtils.usesGregorianCalendar(locale)) {
1961             System.out.println("Skipping this test because locale is " + locale);
1962             return;
1963         }
1964 
1965         Calendar cal = Calendar.getInstance();
1966         cal.setTime(new Date(1029814211523L));
1967         cal.set(YEAR, 2001);
1968         Date t = cal.getTime();
1969         cal.set(MONTH, JANUARY);
1970         t = cal.getTime();
1971 
1972         cal.set(DAY_OF_MONTH, 8);
1973         t = cal.getTime();
1974 
1975         cal.set(DAY_OF_WEEK, MONDAY);
1976         DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);
1977         String expected = "2001/01/08";
1978         String s = df.format(cal.getTime());
1979         if (!expected.equals(s)) {
1980             fail("expected: " + expected + ", got: " + s);
1981         }
1982     }
1983 
1984     /**
1985      * 4683492: Invalid value for MONTH in GregorianCalendar causes exception in getTime().
1986      *
1987      * <p>Need to use SimpleDateFormat to test because a call to
1988      * get(int) changes internal states of a Calendar.
1989      *
1990      * <p>This test case throws ArrayIndexOutOfBoundsException without the fix.
1991      */
1992     @Test
1993     public void Test4683492() {
1994         Calendar cal = new GregorianCalendar(2002, 3, 29, 10, 0, 0);
1995         cal.set(DAY_OF_WEEK, FRIDAY);
1996         cal.set(DAY_OF_WEEK_IN_MONTH, -1);
1997         cal.set(MONTH, 12);
1998         DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);
1999         String expected = "2003/01/31";
2000         String s = df.format(cal.getTime());
2001         if (!expected.equals(s)) {
2002             fail("expected: " + expected + ", got: " + s);
2003         }
2004     }
2005 
2006     /**
2007      * 4080631: Calendar.hashCode is amazingly bad
2008      */
2009     @Test
2010     public void Test4080631() {
2011         Calendar cal = Calendar.getInstance();
2012         int h1 = cal.hashCode();
2013         cal.add(SECOND, +1);
2014         int h2 = cal.hashCode();
2015         Calendar cal2 = (Calendar) cal.clone();
2016         cal.add(MILLISECOND, +1);
2017         int h3 = cal.hashCode();
2018         System.out.println("hash code: h1=" + h1 + ", h2=" + h2 + ", h3=" + h3);
2019         if (h1 == h2 || h1 == h3 || h2 == h3) {
2020             fail("hash code is poor: hashCode=" + h1);
2021         }
2022         h2 = cal2.hashCode();
2023         cal.add(MILLISECOND, -1);
2024         int h4 = cal.hashCode();
2025         System.out.println("hash code: h2=" + h2 + ", h4=" + h4);
2026         if (cal.equals(cal2) && h2 != h4) {
2027             fail("broken hash code: h2=" + h2 + ", h4=" + h4);
2028         }
2029         int x = cal.getFirstDayOfWeek() + 3;
2030         if (x > SATURDAY) {
2031             x -= 7;
2032         }
2033         cal.setFirstDayOfWeek(x);
2034         int h5 = cal.hashCode();
2035         System.out.println("hash code: h4=" + h4 + ", h5=" + h5);
2036         if (h4 == h5) {
2037             fail("has code is poor with first day of week param: hashCode=" + h4);
2038         }
2039     }
2040 
2041     /**
2042      * 4125161: RFE: GregorianCalendar needs more era names (BCE and CE)
2043      */
2044     /*
2045     @Test
2046     public void Test4125161() throws Exception {
2047         Class gc = GregorianCalendar.class;
2048         Field f;
2049         int mod;
2050         f = gc.getDeclaredField("BCE");
2051         mod = f.getModifiers();
2052         if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) {
2053             fail("BCE: wrong modifiers: " + mod);
2054         }
2055         f = gc.getDeclaredField("CE");
2056         mod = f.getModifiers();
2057         if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) {
2058             fail("CE: wrong modifiers: " + mod);
2059         }
2060         if (GregorianCalendar.BCE != GregorianCalendar.BC
2061             || GregorianCalendar.CE != GregorianCalendar.AD) {
2062             fail("Wrong BCE and/or CE values");
2063         }
2064     }
2065      */
2066     /**
2067      * 4167995: GregorianCalendar.setGregorianChange() not to spec
2068      */
2069     @Test
2070     public void Test4167995() {
2071         Koyomi gc = new Koyomi(TimeZone.getTimeZone("GMT"));
2072         System.out.println("Hybrid: min date");
2073         gc.setTime(new Date(Long.MIN_VALUE));
2074         if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY)
2075                 || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) {
2076             fail(gc.getMessage());
2077         }
2078         System.out.println("Hybrid: max date");
2079         gc.setTime(new Date(Long.MAX_VALUE));
2080         if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY)
2081                 || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) {
2082             fail(gc.getMessage());
2083         }
2084 
2085         gc.setGregorianChange(new Date(Long.MIN_VALUE));
2086         System.out.println("Gregorian: min date");
2087         gc.setTime(new Date(Long.MIN_VALUE));
2088         if (!gc.checkDate(292275056, MAY, 16, SUNDAY)
2089                 || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) {
2090             fail(gc.getMessage());
2091         }
2092         System.out.println("Gregorian: max date");
2093         gc.setTime(new Date(Long.MAX_VALUE));
2094         if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY)
2095                 || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) {
2096             fail(gc.getMessage());
2097         }
2098 
2099         gc.setGregorianChange(new Date(Long.MAX_VALUE));
2100         System.out.println("Julian: min date");
2101         gc.setTime(new Date(Long.MIN_VALUE));
2102         if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY)
2103                 || !gc.checkFieldValue(ERA, GregorianCalendar.BC)) {
2104             fail(gc.getMessage());
2105         }
2106         System.out.println("Julian: max date");
2107         gc.setTime(new Date(Long.MAX_VALUE));
2108         if (!gc.checkDate(292272993, JANUARY, 4, SUNDAY)
2109                 || !gc.checkFieldValue(ERA, GregorianCalendar.AD)) {
2110             fail(gc.getMessage());
2111         }
2112     }
2113 
2114     /**
2115      * 4340146: Calendar.equals modifies state
2116      */
2117     @Test
2118     public void Test4340146() {
2119         Koyomi cal = new Koyomi();
2120         cal.clear();
2121         cal.set(2003, OCTOBER, 32);
2122         cal.equals(new Koyomi());
2123         if (!cal.checkInternalDate(2003, OCTOBER, 32)) {
2124             fail(cal.getMessage());
2125         }
2126         new Koyomi().equals(cal);
2127         if (!cal.checkInternalDate(2003, OCTOBER, 32)) {
2128             fail(cal.getMessage());
2129         }
2130     }
2131 
2132     /**
2133      * 4639407: GregorianCalendar doesn't work in non-lenient due to timezone bounds checking
2134      */
2135     @Test
2136     public void Test4639407() {
2137         // The following operations in non-lenient mode shouldn't
2138         // throw IllegalArgumentException.
2139         Koyomi cal = new Koyomi(TimeZone.getTimeZone("Pacific/Kiritimati"));
2140         cal.setLenient(false);
2141         cal.set(2003, OCTOBER, 10);
2142         cal.getTime();
2143         cal.setTimeZone(TimeZone.getTimeZone("Pacific/Tongatapu"));
2144         cal.set(2003, OCTOBER, 10);
2145         cal.getTime();
2146     }
2147 
2148     /**
2149      * 4652815: rolling week-of-year back hundreds of weeks changes year
2150      */
2151     @Test
2152     public void Test4652815() {
2153         Koyomi cal = new Koyomi(Locale.US);
2154         testRoll(cal, 2003, SEPTEMBER, 29);
2155         testRoll(cal, 2003, DECEMBER, 24);
2156         testRoll(cal, 1582, DECEMBER, 19);
2157         testRoll(cal, 1582, DECEMBER, 20);
2158     }
2159 
2160     private void testRoll(Koyomi cal, int year, int month, int dayOfMonth) {
2161         cal.clear();
2162         cal.set(year, month, dayOfMonth);
2163         cal.getTime(); // normalize fields
2164         System.out.println("Roll backwards from " + cal.toDateString());
2165         for (int i = 0; i < 1000; i++) {
2166             cal.roll(WEEK_OF_YEAR, -i);
2167             if (!cal.checkFieldValue(YEAR, year)) {
2168                 fail(cal.getMessage());
2169             }
2170         }
2171         System.out.println("Roll forewards from " + cal.toDateString());
2172         for (int i = 0; i < 1000; i++) {
2173             cal.roll(WEEK_OF_YEAR, +i);
2174             if (!cal.checkFieldValue(YEAR, year)) {
2175                 fail(cal.getMessage());
2176             }
2177         }
2178     }
2179 
2180     /**
2181      * 4652830: GregorianCalendar roll behaves unexpectedly for dates in BC era
2182      */
2183     @Test
2184     public void Test4652830() {
2185         Koyomi cal = new Koyomi(Locale.US);
2186         cal.clear();
2187         System.out.println("BCE 9-2-28 (leap year) roll DAY_OF_MONTH++ twice");
2188         cal.set(ERA, GregorianCalendar.BC);
2189         cal.set(9, FEBRUARY, 28);
2190         if (cal.getActualMaximum(DAY_OF_YEAR) != 366) {
2191             fail("    wrong actual max of DAY_OF_YEAR: got "
2192                     + cal.getActualMaximum(DAY_OF_YEAR) + " expected " + 366);
2193         }
2194         cal.roll(DAY_OF_MONTH, +1);
2195         if (!cal.checkFieldValue(ERA, GregorianCalendar.BC)
2196                 || !cal.checkDate(9, FEBRUARY, 29)) {
2197             fail(cal.getMessage());
2198         }
2199         cal.roll(DAY_OF_MONTH, +1);
2200         if (!cal.checkFieldValue(ERA, GregorianCalendar.BC)
2201                 || !cal.checkDate(9, FEBRUARY, 1)) {
2202             fail(cal.getMessage());
2203         }
2204     }
2205 
2206     /**
2207      * 4740554: GregorianCalendar.getActualMaximum is inconsistent with normalization
2208      */
2209     @Test
2210     public void Test4740554() {
2211         System.out.println("1999/(Feb+12)/1 should be normalized to 2000/Feb/1 for getActualMaximum");
2212         Koyomi cal = new Koyomi(Locale.US);
2213         cal.clear();
2214         cal.set(1999, FEBRUARY + 12, 1);
2215         if (!cal.checkActualMaximum(DAY_OF_YEAR, 366)) {
2216             fail(cal.getMessage());
2217         }
2218         if (!cal.checkActualMaximum(DAY_OF_MONTH, 29)) {
2219             fail(cal.getMessage());
2220         }
2221     }
2222 
2223     /**
2224      * 4936355: GregorianCalendar causes overflow/underflow with time of day calculation
2225      */
2226     @Test
2227     public void Test4936355() {
2228         Koyomi cal = new Koyomi(TimeZone.getTimeZone("GMT"));
2229         cal.clear();
2230         cal.set(1970, JANUARY, 1);
2231         checkTimeCalculation(cal, HOUR_OF_DAY, Integer.MAX_VALUE,
2232                 (long) Integer.MAX_VALUE * 60 * 60 * 1000);
2233 
2234         cal.clear();
2235         cal.set(1970, JANUARY, 1);
2236         checkTimeCalculation(cal, HOUR, Integer.MAX_VALUE,
2237                 (long) Integer.MAX_VALUE * 60 * 60 * 1000);
2238 
2239         cal.clear();
2240         cal.set(1970, JANUARY, 1);
2241         checkTimeCalculation(cal, MINUTE, Integer.MAX_VALUE,
2242                 (long) Integer.MAX_VALUE * 60 * 1000);
2243 
2244         cal.clear();
2245         // Make sure to use Gregorian dates (before and after the
2246         // set() call) for testing

2248         checkTimeCalculation(cal, HOUR_OF_DAY, Integer.MIN_VALUE,
2249                 (long) Integer.MIN_VALUE * 60 * 60 * 1000);
2250 
2251         cal.clear();
2252         cal.set(250000, JANUARY, 1);
2253         checkTimeCalculation(cal, HOUR, Integer.MIN_VALUE,
2254                 (long) Integer.MIN_VALUE * 60 * 60 * 1000);
2255 
2256         cal.clear();
2257         cal.set(250000, JANUARY, 1);
2258         checkTimeCalculation(cal, MINUTE, Integer.MIN_VALUE,
2259                 (long) Integer.MIN_VALUE * 60 * 1000);
2260     }
2261 
2262     private void checkTimeCalculation(Koyomi cal, int field, int value, long expectedDelta) {
2263         long time = cal.getTimeInMillis();
2264         cal.set(field, value);
2265         long time2 = cal.getTimeInMillis();
2266         if ((time + expectedDelta) != time2) {
2267             String s = value == Integer.MAX_VALUE ? "Integer.MAX_VALUE" : "Integer.MIN_VALUE";
2268             fail("set(" + Koyomi.getFieldName(field) + ", " + s + ") failed." + " got " + time2
2269                     + ", expected " + (time + expectedDelta));
2270         }
2271     }
2272 
2273     /**
2274      * 4722650: Calendar.equals can throw an exception in non-lenient
2275      * (piggy-back tests for compareTo() which is new in 1.5)
2276      */
2277     @Test
2278     public void Test4722650() {
2279         Calendar cal1 = new GregorianCalendar();
2280         cal1.clear();
2281         Calendar cal2 = new GregorianCalendar();
2282         cal2.clear();
2283         cal2.setLenient(false);
2284 
2285         cal1.set(2003, OCTOBER, 31);
2286         cal2.set(2003, OCTOBER, 31);
2287         try {
2288             if (cal1.equals(cal2)) {
2289                 fail("lenient and non-lenient shouldn't be equal. (2003/10/31)");
2290             }
2291             if (cal1.compareTo(cal2) != 0) {
2292                 fail("cal1 and cal2 should represent the same time. (2003/10/31)");
2293             }
2294         } catch (IllegalArgumentException e) {
2295             fail("equals threw IllegalArugumentException with non-lenient");
2296         }
2297 
2298         cal1.set(2003, OCTOBER, 32);
2299         cal2.set(2003, OCTOBER, 32);
2300         try {
2301             if (cal1.equals(cal2)) {
2302                 fail("lenient and non-lenient shouldn't be equal. (2003/10/32)");
2303             }
2304             if (cal1.compareTo(cal2) != 0) {
2305                 fail("cal1 and cal2 should represent the same time. (2003/10/32)");
2306             }
2307         } catch (IllegalArgumentException e) {
2308             fail("equals threw IllegalArugumentException with non-lenient");
2309         }
2310 
2311         cal1 = Calendar.getInstance(Locale.of("th", "TH"));
2312         cal1.setTimeInMillis(0L);
2313         cal2 = Calendar.getInstance(Locale.US);
2314         cal2.setTimeInMillis(0L);
2315         if (cal1.equals(cal2)) {
2316             fail("Buddhist.equals(Gregorian) shouldn't be true. (millis=0)");
2317         }
2318         if (cal1.compareTo(cal2) != 0) {
2319             fail("cal1 (Buddhist) and cal2 (Gregorian) should represent the same time. (millis=0)");
2320         }
2321     }
2322 
2323     /**
2324      * 4738710: API: Calendar comparison methods should be improved
2325      */
2326     @Test
2327     public void Test4738710() {
2328         Calendar cal0 = new GregorianCalendar(2003, SEPTEMBER, 30);
2329         Comparable<Calendar> cal1 = new GregorianCalendar(2003, OCTOBER, 1);
2330         Calendar cal2 = new GregorianCalendar(2003, OCTOBER, 2);
2331         if (!(cal1.compareTo(cal0) > 0)) {
2332             fail("!(cal1 > cal0)");
2333         }
2334         if (!(cal1.compareTo(cal2) < 0)) {
2335             fail("!(cal1 < cal2)");
2336         }
2337         if (cal1.compareTo(new GregorianCalendar(2003, OCTOBER, 1)) != 0) {
2338             fail("cal1 != new GregorianCalendar(2003, OCTOBER, 1)");
2339         }
2340 
2341         if (cal0.after(cal2)) {
2342             fail("cal0 shouldn't be after cal2");
2343         }
2344         if (cal2.before(cal0)) {
2345             fail("cal2 shouldn't be before cal0");
2346         }
2347 
2348         if (cal0.after(0)) {
2349             fail("cal0.after() returned true with an Integer.");
2350         }
2351         if (cal0.before(0)) {
2352             fail("cal0.before() returned true with an Integer.");
2353         }
2354         if (cal0.after(null)) {
2355             fail("cal0.after() returned true with null.");
2356         }
2357         if (cal0.before(null)) {
2358             fail("cal0.before() returned true with null.");
2359         }
2360     }
2361 
2362     /**
2363      * 4633646: Setting WEEK_OF_MONTH to 1 results in incorrect date
2364      */
2365     @SuppressWarnings("deprecation")
2366     @Test
2367     public void Test4633646() {
2368         Koyomi cal = new Koyomi(Locale.US);
2369         cal.setTime(new Date(2002 - 1900, 1 - 1, 28));
2370         sub4633646(cal);
2371 
2372         cal.setLenient(false);
2373         cal.setTime(new Date(2002 - 1900, 1 - 1, 28));
2374         sub4633646(cal);
2375 
2376         cal = new Koyomi(Locale.US);
2377         cal.clear();
2378         cal.set(2002, JANUARY, 28);
2379         sub4633646(cal);
2380 
2381         cal.clear();
2382         cal.setLenient(false);
2383         cal.set(2002, JANUARY, 28);
2384         sub4633646(cal);
2385     }
2386 
2387     void sub4633646(Koyomi cal) {
2388         cal.getTime();
2389         cal.set(WEEK_OF_MONTH, 1);
2390         if (cal.isLenient()) {
2391             if (!cal.checkDate(2001, DECEMBER, 31)) {
2392                 fail(cal.getMessage());
2393             }
2394             if (!cal.checkFieldValue(WEEK_OF_MONTH, 6)) {
2395                 fail(cal.getMessage());
2396             }
2397         } else {
2398             try {
2399                 Date d = cal.getTime();
2400                 fail("didn't throw IllegalArgumentException in non-lenient");
2401             } catch (IllegalArgumentException e) {
2402             }
2403         }
2404     }
2405 
2406     /**
2407      * 4846659: Calendar: Both set() and roll() don't work for AM_PM time field
2408      * (Partially fixed only roll as of 1.5)
2409      */
2410     @Test
2411     public void Test4846659() {
2412         Koyomi cal = new Koyomi();
2413         cal.clear();
2414         cal.set(2003, OCTOBER, 31, 10, 30, 30);
2415         cal.getTime();
2416         // Test roll()
2417         cal.roll(AM_PM, +1); // should turn to PM
2418         if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) {
2419             fail("roll: AM_PM didn't change to PM");
2420         }
2421 
2422         cal.clear();
2423         cal.set(2003, OCTOBER, 31, 10, 30, 30);
2424         cal.getTime();
2425         // Test set()
2426         cal.set(AM_PM, PM); // should turn to PM
2427         if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) {
2428             fail("set: AM_PM didn't change to PM");
2429         }
2430 
2431         cal.clear();
2432         cal.set(2003, OCTOBER, 31, 10, 30, 30);
2433         cal.getTime();
2434         cal.set(AM_PM, PM);
2435         cal.set(HOUR, 9);
2436         if (!cal.checkFieldValue(HOUR_OF_DAY, 9 + 12)) {
2437             fail("set: both AM_PM and HOUT didn't change to PM");
2438         }
2439     }
2440 
2441     /**
2442      * 4822110: GregorianCalendar.get() returns an incorrect date after setFirstDayOfWeek()
2443      */
2444     @Test
2445     public void Test4822110() {
2446         Koyomi cal = new Koyomi(Locale.US);
2447         //    June 2003
2448         //  S  M Tu  W Th  F  S
2449         //  1  2  3  4  5  6  7
2450         //  8  9 10 11 12 13 14
2451         // 15 16 17 18 19 20 21
2452         // 22 23 24 25 26 27 28
2453         // 29 30
2454         cal.clear();
2455         // 6/1 to 6/7 should be the 1st week of June.
2456         cal.set(2003, JUNE, 2);
2457         cal.getTime();                  // Let cal calculate time.
2458         cal.setFirstDayOfWeek(MONDAY);
2459         // Now 6/2 to 6/8 should be the 2nd week of June. Sunday of
2460         // that week is 6/8.
2461         System.out.println("1: " + cal.get(WEEK_OF_MONTH) + ", " + cal.get(DAY_OF_MONTH));
2462         cal.set(DAY_OF_WEEK, SUNDAY);
2463         System.out.println("1st Sunday of June 2003 with FirstDayOfWeek=MONDAY");
2464         if (!cal.checkDate(2003, JUNE, 8)) {
2465             fail(cal.getMessage());
2466         }
2467     }
2468 
2469     /**
2470      * 4973919: Inconsistent GregorianCalendar hashCode before and after serialization
2471      */
2472     @Test
2473     public void Test4966499() throws Exception {
2474         GregorianCalendar date1 = new GregorianCalendar(2004, JANUARY, 7);
2475 
2476         // Serialize date1
2477         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2478         ObjectOutputStream oos = new ObjectOutputStream(baos);
2479         oos.writeObject(date1);
2480 
2481         byte[] buffer = baos.toByteArray();
2482 
2483         // Deserialize it
2484         ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
2485         ObjectInputStream ois = new ObjectInputStream(bais);
2486         GregorianCalendar date2 = (GregorianCalendar) ois.readObject();
2487 
2488         if (!date1.equals(date2)) {
2489             fail("date1.equals(date2) != true");
2490         }
2491         if (date1.hashCode() != date2.hashCode()) {
2492             fail("inconsistent hashCode() value (before=0x"
2493                     + Integer.toHexString(date1.hashCode())
2494                     + ", after=0x" + Integer.toHexString(date2.hashCode()) + ")");
2495         }
2496     }
2497 
2498     /**
2499      * 4980088: GregorianCalendar.getActualMaximum doesn't throw exception
2500      */
2501     @Test
2502     public void Test4980088() {
2503         GregorianCalendar cal = new GregorianCalendar();
2504         try {
2505             int x = cal.getMaximum(100);
2506             fail("getMaximum(100) didn't throw an exception.");
2507         } catch (IndexOutOfBoundsException e) {
2508             System.out.println("getMaximum: " + e.getClass().getName() + ": " + e.getMessage());
2509         }
2510 
2511         try {
2512             int x = cal.getLeastMaximum(100);
2513             fail("getLeastMaximum(100) didn't throw an exception.");
2514         } catch (IndexOutOfBoundsException e) {
2515             System.out.println("getLeastMaximum: " + e.getClass().getName() + ": " + e.getMessage());
2516         }
2517 
2518         try {
2519             int x = cal.getActualMaximum(100);
2520             fail("getActualMaximum(100) didn't throw an exception.");
2521         } catch (IndexOutOfBoundsException e) {
2522             System.out.println("getActualMaximum: " + e.getClass().getName() + ": " + e.getMessage());
2523         }
2524 
2525         try {
2526             int x = cal.getMinimum(100);
2527             fail("getMinimum(100) didn't throw an exception.");
2528         } catch (IndexOutOfBoundsException e) {
2529             System.out.println("getMinimum: " + e.getClass().getName() + ": " + e.getMessage());
2530         }
2531 
2532         try {
2533             int x = cal.getGreatestMinimum(100);
2534             fail("getGreatestMinimum(100) didn't throw an exception.");
2535         } catch (IndexOutOfBoundsException e) {
2536             System.out.println("getGreatestMinimum: " + e.getClass().getName() + ": " + e.getMessage());
2537         }
2538 
2539         try {
2540             int x = cal.getActualMinimum(100);
2541             fail("getActualMinimum(100) didn't throw an exception.");
2542         } catch (IndexOutOfBoundsException e) {
2543             System.out.println("getActualMinimum: " + e.getClass().getName() + ": " + e.getMessage());
2544         }
2545     }
2546 
2547     /**
2548      * 4965624: GregorianCalendar.isLeapYear(1000) returns incorrect value
2549      */
2550     @Test
2551     public void Test4965624() {
2552         // 5013094: This test case needs to use "GMT" to specify
2553         // Gregorian cutover dates.
2554         TimeZone savedZone = TimeZone.getDefault();
2555         TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
2556         try {
2557             Map<Date, Boolean> data = new HashMap<>();
2558             data.put(getGregorianDate(999, OCTOBER, 1), Boolean.FALSE);
2559             data.put(getGregorianDate(1000, JANUARY, 1), Boolean.FALSE);
2560             data.put(getGregorianDate(1000, FEBRUARY, 1), Boolean.FALSE);
2561             data.put(getGregorianDate(1000, FEBRUARY, 28), Boolean.FALSE);
2562             data.put(getGregorianDate(1000, MARCH, 1), Boolean.TRUE);
2563             data.put(getGregorianDate(1001, JANUARY, 1), Boolean.TRUE);
2564             data.put(getGregorianDate(1001, JANUARY, 6), Boolean.TRUE);
2565             data.put(getGregorianDate(1001, MARCH, 1), Boolean.TRUE);
2566 
2567             data.keySet().forEach(d -> {
2568                 boolean expected = data.get(d);
2569                 GregorianCalendar cal = new GregorianCalendar();
2570                 cal.setGregorianChange(d);
2571                 if (cal.isLeapYear(1000) != expected) {
2572                     fail("isLeapYear(1000) returned " + cal.isLeapYear(1000)
2573                             + " with cutover date (Julian) " + d);
2574                 }
2575             });
2576         } finally {
2577             TimeZone.setDefault(savedZone);
2578         }
2579     }
2580 
2581     // Note that we can't use Date to produce Gregorian calendar dates
2582     // before the default cutover date.
2583     static Date getGregorianDate(int year, int month, int dayOfMonth) {
2584         GregorianCalendar g = new GregorianCalendar();
2585         // Make g a pure Gregorian calendar
2586         g.setGregorianChange(new Date(Long.MIN_VALUE));
2587         g.clear();
2588         g.set(year, month, dayOfMonth);
2589         return g.getTime();
2590     }
2591 
2592     /**
2593      * 5006864: Define the minimum value of DAY_OF_WEEK_IN_MONTH as 1
2594      */
2595     @Test
2596     public void Test5006864() {
2597         GregorianCalendar cal = new GregorianCalendar();
2598         int min = cal.getMinimum(DAY_OF_WEEK_IN_MONTH);
2599         if (min != 1) {
2600             fail("GregorianCalendar.getMinimum(DAY_OF_WEEK_IN_MONTH) returned "
2601                     + min + ", expected 1.");
2602         }
2603         min = cal.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH);
2604         if (min != 1) {
2605             fail("GregorianCalendar.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH) returned "
2606                     + min + ", expected 1.");
2607         }
2608     }
2609 }
< prev index next >