1 /*
   2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 4064654 4374886 4984320 4984574 4944795
  27  * @summary test for Calendar
  28  * @library /java/text/testlib
  29  * @run main CalendarTest
  30  * @key randomness
  31  */
  32 
  33 import java.io.File;
  34 import java.io.FileInputStream;
  35 import java.io.FileOutputStream;
  36 import java.io.IOException;
  37 import java.io.ObjectInputStream;
  38 import java.io.ObjectOutput;
  39 import java.io.ObjectOutputStream;
  40 import java.util.Calendar;
  41 import java.util.Date;
  42 import java.util.GregorianCalendar;
  43 import java.util.Locale;
  44 import java.util.SimpleTimeZone;
  45 import java.util.TimeZone;
  46 
  47 import static java.util.Calendar.*;
  48 
  49 public class CalendarTest extends IntlTest {
  50 
  51     static final int ONE_DAY = 24 * 60 * 60 * 1000;
  52     static final int EPOCH_JULIAN = 2440588;
  53 
  54     public static void main(String argv[]) throws Exception {
  55         new CalendarTest().run(argv);
  56     }
  57 
  58     /**
  59      * Test the behavior of the GregorianCalendar around the changeover.
  60      */
  61     public void TestGregorianChangeover() {
  62         TimeZone savedZone = TimeZone.getDefault();
  63         /*
  64           Changeover -7 days: 1582/9/28 dow=6
  65           Changeover -6 days: 1582/9/29 dow=7
  66           Changeover -5 days: 1582/9/30 dow=1
  67           Changeover -4 days: 1582/10/1 dow=2
  68           Changeover -3 days: 1582/10/2 dow=3
  69           Changeover -2 days: 1582/10/3 dow=4
  70           Changeover -1 days: 1582/10/4 dow=5
  71           Changeover +0 days: 1582/10/15 dow=6
  72           Changeover +1 days: 1582/10/16 dow=7
  73           Changeover +2 days: 1582/10/17 dow=1
  74           Changeover +3 days: 1582/10/18 dow=2
  75           Changeover +4 days: 1582/10/19 dow=3
  76           Changeover +5 days: 1582/10/20 dow=4
  77           Changeover +6 days: 1582/10/21 dow=5
  78           Changeover +7 days: 1582/10/22 dow=6
  79           */
  80         int[] MON = {  9,  9,  9,10,10,10,10, 10, 10, 10, 10, 10, 10, 10, 10 };
  81         int[] DOM = { 28, 29, 30, 1, 2, 3, 4, 15, 16, 17, 18, 19, 20, 21, 22 };
  82         int[] DOW = {  6,  7,  1, 2, 3, 4, 5,  6,  7,  1,  2,  3,  4,  5,  6 };
  83         //                                     ^ <-Changeover Fri Oct 15 1582
  84         try {
  85             TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
  86             @SuppressWarnings("deprecation")
  87             Date co = new Date(1582 - 1900, OCTOBER, 15);
  88             GregorianCalendar cal = new GregorianCalendar();
  89             int j = 0;
  90             for (int i = -7; i <= 7; ++i, ++j) {
  91                 Date d = new Date(co.getTime() + i * ONE_DAY);
  92                 cal.setTime(d);
  93                 int y = cal.get(YEAR);
  94                 int mon = cal.get(MONTH) + 1 - JANUARY;
  95                 int dom = cal.get(DATE);
  96                 int dow = cal.get(DAY_OF_WEEK);
  97 
  98                 logln("Changeover " + (i >= 0 ? "+" : "") + i
  99                         + " days: " + y + "/" + mon + "/" + dom + " dow=" + dow);
 100                 if (y != 1582 || mon != MON[j] || dom != DOM[j] || dow != DOW[j]) {
 101                     errln(" Fail: Above line is wrong");
 102                 }
 103             }
 104         } finally {
 105             TimeZone.setDefault(savedZone);
 106         }
 107     }
 108 
 109     /**
 110      * Test the mapping between millis and fields.  For the purposes
 111      * of this test, we don't care about timezones and week data
 112      * (first day of week, minimal days in first week).
 113      */
 114     @SuppressWarnings("deprecation")
 115     public void TestMapping() {
 116         TimeZone saveZone = TimeZone.getDefault();
 117         int[] DATA = {
 118             // Julian#   Year      Month    DOM   JULIAN:Year  Month,   DOM
 119             2440588,     1970,    JANUARY,   1,    1969,     DECEMBER,  19,
 120             2415080,     1900,      MARCH,   1,    1900,     FEBRUARY,  17,
 121             2451604,     2000,   FEBRUARY,  29,    2000,     FEBRUARY,  16,
 122             2452269,     2001,   DECEMBER,  25,    2001,     DECEMBER,  12,
 123             2416526,     1904,   FEBRUARY,  15,    1904,     FEBRUARY,   2,
 124             2416656,     1904,       JUNE,  24,    1904,         JUNE,  11,
 125             1721426,        1,    JANUARY,   1,       1,      JANUARY,   3,
 126             2000000,      763,  SEPTEMBER,  18,     763,    SEPTEMBER,  14,
 127             4000000,     6239,       JULY,  12,    6239,          MAY,  28,
 128             8000000,    17191,   FEBRUARY,  26,   17190,      OCTOBER,  22,
 129            10000000,    22666,   DECEMBER,  20,   22666,         JULY,   5};
 130 
 131         try {
 132             TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
 133             Date PURE_GREGORIAN = new Date(Long.MIN_VALUE);
 134             Date PURE_JULIAN = new Date(Long.MAX_VALUE);
 135             GregorianCalendar cal = new GregorianCalendar();
 136             for (int i = 0; i < DATA.length; i += 7) {
 137                 int julian = DATA[i];
 138                 int year = DATA[i + 1];
 139                 int month = DATA[i + 2];
 140                 int dom = DATA[i + 3];
 141                 int year2, month2, dom2;
 142                 long millis = ((long) julian - EPOCH_JULIAN) * ONE_DAY;
 143                 String s;
 144 
 145                 // Test Gregorian computation
 146                 cal.setGregorianChange(PURE_GREGORIAN);
 147                 cal.clear();
 148                 cal.set(year, month, dom);
 149                 long calMillis = cal.getTime().getTime();
 150                 long delta = calMillis - millis;
 151                 cal.setTime(new Date(millis));
 152                 year2 = cal.get(YEAR);
 153                 month2 = cal.get(MONTH);
 154                 dom2 = cal.get(DAY_OF_MONTH);
 155                 s = "G " + year + "-" + (month + 1 - JANUARY) + "-" + dom
 156                         + " => " + calMillis
 157                         + " (" + ((float) delta / ONE_DAY) + " day delta) => "
 158                         + year2 + "-" + (month2 + 1 - JANUARY) + "-" + dom2;
 159                 if (delta != 0 || year != year2 || month != month2
 160                         || dom != dom2) {
 161                     errln(s + " FAIL");
 162                 } else {
 163                     logln(s);
 164                 }
 165 
 166                 // Test Julian computation
 167                 year = DATA[i + 4];
 168                 month = DATA[i + 5];
 169                 dom = DATA[i + 6];
 170                 cal.setGregorianChange(PURE_JULIAN);
 171                 cal.clear();
 172                 cal.set(year, month, dom);
 173                 calMillis = cal.getTime().getTime();
 174                 delta = calMillis - millis;
 175                 cal.setTime(new Date(millis));
 176                 year2 = cal.get(YEAR);
 177                 month2 = cal.get(MONTH);
 178                 dom2 = cal.get(DAY_OF_MONTH);
 179                 s = "J " + year + "-" + (month + 1 - JANUARY) + "-" + dom
 180                         + " => " + calMillis
 181                         + " (" + ((float) delta / ONE_DAY) + " day delta) => "
 182                         + year2 + "-" + (month2 + 1 - JANUARY) + "-" + dom2;
 183                 if (delta != 0 || year != year2 || month != month2
 184                         || dom != dom2) {
 185                     errln(s + " FAIL");
 186                 } else {
 187                     logln(s);
 188                 }
 189             }
 190 
 191             cal.setGregorianChange(new Date(1582 - 1900, OCTOBER, 15));
 192             auxMapping(cal, 1582, OCTOBER, 4);
 193             auxMapping(cal, 1582, OCTOBER, 15);
 194             auxMapping(cal, 1582, OCTOBER, 16);
 195             for (int y = 800; y < 3000; y += 1 + 100 * Math.random()) {
 196                 for (int m = JANUARY; m <= DECEMBER; ++m) {
 197                     auxMapping(cal, y, m, 15);
 198                 }
 199             }
 200         } finally {
 201             TimeZone.setDefault(saveZone);
 202         }
 203     }
 204     private void auxMapping(Calendar cal, int y, int m, int d) {
 205         cal.clear();
 206         cal.set(y, m, d);
 207         long millis = cal.getTime().getTime();
 208         cal.setTime(new Date(millis));
 209         int year2 = cal.get(YEAR);
 210         int month2 = cal.get(MONTH);
 211         int dom2 = cal.get(DAY_OF_MONTH);
 212         if (y != year2 || m != month2 || dom2 != d) {
 213             errln("Round-trip failure: " + y + "-" + (m + 1) + "-" + d + " =>ms=> "
 214                     + year2 + "-" + (month2 + 1) + "-" + dom2);
 215         }
 216     }
 217 
 218     @SuppressWarnings("deprecation")
 219     public void TestGenericAPI() {
 220         Locale locale = Locale.getDefault();
 221         if (!TestUtils.usesGregorianCalendar(locale)) {
 222             logln("Skipping this test because locale is " + locale);
 223             return;
 224         }
 225 
 226         String str;
 227         Date when = new Date(90, APRIL, 15);
 228 
 229         String tzid = "TestZone";
 230         int tzoffset = 123400;
 231 
 232         SimpleTimeZone zone = new SimpleTimeZone(tzoffset, tzid);
 233         Calendar cal = Calendar.getInstance((SimpleTimeZone) zone.clone());
 234 
 235         if (!zone.equals(cal.getTimeZone())) {
 236             errln("FAIL: Calendar.getTimeZone failed");
 237         }
 238 
 239         Calendar cal2 = Calendar.getInstance(cal.getTimeZone());
 240 
 241         cal.setTime(when);
 242         cal2.setTime(when);
 243 
 244         if (!(cal.equals(cal2))) {
 245             errln("FAIL: Calendar.operator== failed");
 246         }
 247         // if ((*cal != *cal2))  errln("FAIL: Calendar.operator!= failed");
 248         if (!cal.equals(cal2)
 249                 || cal.before(cal2)
 250                 || cal.after(cal2)) {
 251             errln("FAIL: equals/before/after failed");
 252         }
 253 
 254         cal2.setTime(new Date(when.getTime() + 1000));
 255         if (cal.equals(cal2)
 256                 || cal2.before(cal)
 257                 || cal.after(cal2)) {
 258             errln("FAIL: equals/before/after failed");
 259         }
 260 
 261         cal.roll(SECOND, true);
 262         if (!cal.equals(cal2)
 263                 || cal.before(cal2)
 264                 || cal.after(cal2)) {
 265             errln("FAIL: equals/before/after failed");
 266         }
 267 
 268         // Roll back to January
 269         cal.roll(MONTH, 1 + DECEMBER - cal.get(MONTH));
 270         if (cal.equals(cal2)
 271                 || cal2.before(cal)
 272                 || cal.after(cal2)) {
 273             errln("FAIL: equals/before/after failed");
 274         }
 275 
 276         // C++ only
 277         /* TimeZone z = cal.orphanTimeZone();
 278         if (z.getID(str) != tzid ||
 279         z.getRawOffset() != tzoffset)
 280         errln("FAIL: orphanTimeZone failed");
 281         */
 282         for (int i = 0; i < 2; ++i) {
 283             boolean lenient = (i > 0);
 284             cal.setLenient(lenient);
 285             if (lenient != cal.isLenient()) {
 286                 errln("FAIL: setLenient/isLenient failed");
 287             }
 288             // Later: Check for lenient behavior
 289         }
 290 
 291         int i;
 292         for (i = SUNDAY; i <= SATURDAY; ++i) {
 293             cal.setFirstDayOfWeek(i);
 294             if (cal.getFirstDayOfWeek() != i) {
 295                 errln("FAIL: set/getFirstDayOfWeek failed");
 296             }
 297         }
 298 
 299         for (i = 0; i <= 7; ++i) {
 300             cal.setMinimalDaysInFirstWeek(i);
 301             if (cal.getMinimalDaysInFirstWeek() != i) {
 302                 errln("FAIL: set/getFirstDayOfWeek failed");
 303             }
 304         }
 305 
 306         for (i = 0; i < FIELD_COUNT; ++i) {
 307             if (cal.getMinimum(i) != cal.getGreatestMinimum(i)) {
 308                 errln("FAIL: getMinimum doesn't match getGreatestMinimum for field " + i);
 309             }
 310             if (cal.getLeastMaximum(i) > cal.getMaximum(i)) {
 311                 errln("FAIL: getLeastMaximum larger than getMaximum for field " + i);
 312             }
 313             if (cal.getMinimum(i) >= cal.getMaximum(i)) {
 314                 errln("FAIL: getMinimum not less than getMaximum for field " + i);
 315             }
 316         }
 317 
 318         cal.setTimeZone(TimeZone.getDefault());
 319         cal.clear();
 320         cal.set(1984, 5, 24);
 321         if (cal.getTime().getTime() != new Date(84, 5, 24).getTime()) {
 322             errln("FAIL: Calendar.set(3 args) failed");
 323             logln(" Got: " + cal.getTime() + "  Expected: " + new Date(84, 5, 24));
 324         }
 325 
 326         cal.clear();
 327         cal.set(1985, 3, 2, 11, 49);
 328         if (cal.getTime().getTime() != new Date(85, 3, 2, 11, 49).getTime()) {
 329             errln("FAIL: Calendar.set(5 args) failed");
 330             logln(" Got: " + cal.getTime() + "  Expected: " + new Date(85, 3, 2, 11, 49));
 331         }
 332 
 333         cal.clear();
 334         cal.set(1995, 9, 12, 1, 39, 55);
 335         if (cal.getTime().getTime() != new Date(95, 9, 12, 1, 39, 55).getTime()) {
 336             errln("FAIL: Calendar.set(6 args) failed");
 337             logln(" Got: " + cal.getTime() + "  Expected: " + new Date(95, 9, 12, 1, 39, 55));
 338         }
 339 
 340         cal.getTime();
 341         for (i = 0; i < FIELD_COUNT; ++i) {
 342             switch (i) {
 343                 case YEAR:
 344                 case MONTH:
 345                 case DATE:
 346                 case HOUR_OF_DAY:
 347                 case MINUTE:
 348                 case SECOND:
 349                     if (!cal.isSet(i)) {
 350                         errln("FAIL: !Calendar.isSet test failed: " + calendarFieldNames[i]);
 351                     }
 352                     break;
 353                 default:
 354                     if (cal.isSet(i)) {
 355                         errln("FAIL: Calendar.isSet test failed: " + calendarFieldNames[i]);
 356                     }
 357             }
 358             cal.clear(i);
 359             if (cal.isSet(i)) {
 360                 errln("FAIL: Calendar.clear/isSet failed");
 361             }
 362         }
 363 
 364         // delete cal;
 365         // delete cal2;
 366         Locale[] loc = Calendar.getAvailableLocales();
 367         long count = loc.length;
 368         if (count < 1 || loc == null) {
 369             errln("FAIL: getAvailableLocales failed");
 370         } else {
 371             for (i = 0; i < count; ++i) {
 372                 cal = Calendar.getInstance(loc[i]);
 373                 // delete cal;
 374             }
 375         }
 376 
 377         cal = Calendar.getInstance(TimeZone.getDefault(), Locale.ENGLISH);
 378         // delete cal;
 379 
 380         cal = Calendar.getInstance(zone, Locale.ENGLISH);
 381         // delete cal;
 382 
 383         GregorianCalendar gc = new GregorianCalendar(zone);
 384         // delete gc;
 385 
 386         gc = new GregorianCalendar(Locale.ENGLISH);
 387         // delete gc;
 388 
 389         gc = new GregorianCalendar(Locale.ENGLISH);
 390         // delete gc;
 391 
 392         gc = new GregorianCalendar(zone, Locale.ENGLISH);
 393         // delete gc;
 394 
 395         gc = new GregorianCalendar(zone);
 396         // delete gc;
 397 
 398         gc = new GregorianCalendar(1998, 10, 14, 21, 43);
 399         if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43).getTime()) {
 400             errln("FAIL: new GregorianCalendar(ymdhm) failed");
 401         }
 402         // delete gc;
 403 
 404         gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55);
 405         if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43, 55).getTime()) {
 406             errln("FAIL: new GregorianCalendar(ymdhms) failed");
 407         }
 408 
 409         // C++ only:
 410         // GregorianCalendar gc2 = new GregorianCalendar(Locale.ENGLISH);
 411         // gc2 = gc;
 412         // if (gc2 != gc || !(gc2 == gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
 413         // delete gc;
 414         // delete z;
 415     }
 416 
 417     // Verify Roger Webster's bug
 418     public void TestRog() {
 419         GregorianCalendar gc = new GregorianCalendar();
 420 
 421         int year = 1997, month = APRIL, date = 1;
 422         gc.set(year, month, date); // April 1, 1997
 423 
 424         gc.set(HOUR_OF_DAY, 23);
 425         gc.set(MINUTE, 0);
 426         gc.set(SECOND, 0);
 427         gc.set(MILLISECOND, 0);
 428 
 429         for (int i = 0; i < 9; i++, gc.add(DATE, 1)) {
 430             if (gc.get(YEAR) != year
 431                     || gc.get(MONTH) != month
 432                     || gc.get(DATE) != (date + i)) {
 433                 errln("FAIL: Date " + gc.getTime() + " wrong");
 434             }
 435         }
 436     }
 437 
 438     // Verify DAY_OF_WEEK
 439     public void TestDOW943() {
 440         dowTest(false);
 441         dowTest(true);
 442     }
 443 
 444     void dowTest(boolean lenient) {
 445         GregorianCalendar cal = new GregorianCalendar();
 446         cal.set(1997, AUGUST, 12); // Wednesday
 447         cal.getTime(); // Force update
 448         cal.setLenient(lenient);
 449         cal.set(1996, DECEMBER, 1); // Set the date to be December 1, 1996
 450         int dow = cal.get(DAY_OF_WEEK);
 451         int min = cal.getMinimum(DAY_OF_WEEK);
 452         int max = cal.getMaximum(DAY_OF_WEEK);
 453         if (dow < min || dow > max) {
 454             errln("FAIL: Day of week " + dow + " out of range");
 455         }
 456         if (dow != SUNDAY) {
 457             errln("FAIL2: Day of week should be SUNDAY; is " + dow + ": " + cal.getTime());
 458         }
 459         if (min != SUNDAY || max != SATURDAY) {
 460             errln("FAIL: Min/max bad");
 461         }
 462     }
 463 
 464     // Verify that the clone method produces distinct objects with no
 465     // unintentionally shared fields.
 466     public void TestClonesUnique908() {
 467         Calendar c = Calendar.getInstance();
 468         Calendar d = (Calendar) c.clone();
 469         c.set(MILLISECOND, 123);
 470         d.set(MILLISECOND, 456);
 471         if (c.get(MILLISECOND) != 123
 472                 || d.get(MILLISECOND) != 456) {
 473             errln("FAIL: Clones share fields");
 474         }
 475     }
 476 
 477     // Verify effect of Gregorian cutoff value
 478     @SuppressWarnings("deprecation")
 479     public void TestGregorianChange768() {
 480         boolean b;
 481         GregorianCalendar c = new GregorianCalendar();
 482         logln("With cutoff " + c.getGregorianChange());
 483         logln(" isLeapYear(1800) = " + (b = c.isLeapYear(1800)));
 484         logln(" (should be FALSE)");
 485         if (b != false) {
 486             errln("FAIL");
 487         }
 488         c.setGregorianChange(new Date(0, 0, 1)); // Jan 1 1900
 489         logln("With cutoff " + c.getGregorianChange());
 490         logln(" isLeapYear(1800) = " + (b = c.isLeapYear(1800)));
 491         logln(" (should be TRUE)");
 492         if (b != true) {
 493             errln("FAIL");
 494         }
 495     }
 496 
 497     // Test the correct behavior of the disambiguation algorithm.
 498     public void TestDisambiguation765() throws Exception {
 499         Locale savedLocale = Locale.getDefault();
 500         try {
 501             Locale.setDefault(Locale.US);
 502             Calendar c = Calendar.getInstance();
 503             c.setLenient(false);
 504 
 505             c.clear();
 506             c.set(YEAR, 1997);
 507             c.set(MONTH, JUNE);
 508             c.set(DATE, 3);
 509 
 510             verify765("1997 third day of June = ", c, 1997, JUNE, 3);
 511 
 512             c.clear();
 513             c.set(YEAR, 1997);
 514             c.set(DAY_OF_WEEK, TUESDAY);
 515             c.set(MONTH, JUNE);
 516             c.set(DAY_OF_WEEK_IN_MONTH, 1);
 517             verify765("1997 first Tuesday in June = ", c, 1997, JUNE, 3);
 518 
 519             c.setLenient(true); // for 4944795
 520             c.clear();
 521             c.set(YEAR, 1997);
 522             c.set(DAY_OF_WEEK, TUESDAY);
 523             c.set(MONTH, JUNE);
 524             c.set(DAY_OF_WEEK_IN_MONTH, -1);
 525             verify765("1997 last Tuesday in June = ", c, 1997, JUNE, 24);
 526 
 527             c.setLenient(false);
 528             IllegalArgumentException e = null;
 529             try {
 530                 c.clear();
 531                 c.set(YEAR, 1997);
 532                 c.set(DAY_OF_WEEK, TUESDAY);
 533                 c.set(MONTH, JUNE);
 534                 c.set(DAY_OF_WEEK_IN_MONTH, 0);
 535                 c.getTime();
 536             } catch (IllegalArgumentException ex) {
 537                 e = ex;
 538             }
 539             verify765("1997 zero-th Tuesday in June = ", e);
 540 
 541             c.clear();
 542             c.set(YEAR, 1997);
 543             c.set(DAY_OF_WEEK, TUESDAY);
 544             c.set(MONTH, JUNE);
 545             c.set(WEEK_OF_MONTH, 1);
 546             verify765("1997 Tuesday in week 1 of June = ", c, 1997, JUNE, 3);
 547 
 548             c.clear();
 549             c.set(YEAR, 1997);
 550             c.set(DAY_OF_WEEK, TUESDAY);
 551             c.set(MONTH, JUNE);
 552             c.set(WEEK_OF_MONTH, 4);
 553             verify765("1997 Tuesday in week 4 of June = ", c, 1997, JUNE, 24);
 554 
 555             try {
 556                 c.clear();
 557                 c.set(YEAR, 1997);
 558                 c.set(DAY_OF_WEEK, TUESDAY);
 559                 c.set(MONTH, JUNE);
 560                 c.set(WEEK_OF_MONTH, 1);
 561                 verify765("1997 Tuesday in week 0 of June = ", c, 1997, JUNE, 3);
 562             } catch (IllegalArgumentException ex) {
 563                 errln("FAIL: Exception seen: " + ex.getMessage());
 564                 // ex.printStackTrace(log);
 565             }
 566 
 567             c.clear();
 568             c.set(YEAR, 1997);
 569             c.set(DAY_OF_WEEK, TUESDAY);
 570             c.set(WEEK_OF_YEAR, 2);
 571             verify765("1997 Tuesday in week 2 of year = ", c, 1997, JANUARY, 7);
 572 
 573             c.clear();
 574             c.set(YEAR, 1997);
 575             c.set(DAY_OF_WEEK, TUESDAY);
 576             c.set(WEEK_OF_YEAR, 10);
 577             verify765("1997 Tuesday in week 10 of year = ", c, 1997, MARCH, 4);
 578 
 579             try {
 580                 c.clear();
 581                 c.set(YEAR, 1997);
 582                 c.set(DAY_OF_WEEK, TUESDAY);
 583                 c.set(WEEK_OF_YEAR, 0);
 584                 verify765("1997 Tuesday in week 0 of year = ", c, 1996, DECEMBER, 24);
 585                 throw new Exception("Fail: WEEK_OF_YEAR 0 should be illegal");
 586             } catch (IllegalArgumentException ex) {
 587             }
 588         } finally {
 589             Locale.setDefault(savedLocale);
 590         }
 591     }
 592 
 593     void verify765(String msg, Calendar c, int year, int month, int day) {
 594         if (c.get(YEAR) == year
 595                 && c.get(MONTH) == month
 596                 && c.get(DATE) == day) {
 597             logln("PASS: " + msg + c.getTime());
 598         } else {
 599             errln("FAIL: " + msg + c.getTime()
 600                     + "; expected "
 601                     + year + "/" + (month + 1) + "/" + day);
 602         }
 603     }
 604 
 605     // Called when e expected to be non-null
 606     void verify765(String msg, IllegalArgumentException e) {
 607         if (e == null) {
 608             errln("FAIL: No IllegalArgumentException for " + msg);
 609         } else {
 610             logln("PASS: " + msg + "IllegalArgument as expected");
 611         }
 612     }
 613 
 614     // Test the behavior of GMT vs. local time
 615     public void TestGMTvsLocal4064654() {
 616         Locale locale = Locale.getDefault();
 617         if (!TestUtils.usesGregorianCalendar(locale)) {
 618             logln("Skipping this test because locale is " + locale);
 619             return;
 620         }
 621 
 622         // Sample output 1:
 623         // % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 1 1 12 0 0
 624         // date = Wed Jan 01 04:00:00 PST 1997
 625         // offset for Wed Jan 01 04:00:00 PST 1997= -8hr
 626         test4064654(1997, 1, 1, 12, 0, 0);
 627 
 628         // Sample output 2:
 629         // % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 4 16 18 30 0
 630         // date = Wed Apr 16 10:30:00 PDT 1997
 631         // offset for Wed Apr 16 10:30:00 PDT 1997= -7hr
 632 
 633         // Note that in sample output 2 according to the offset, the gmt time
 634         // of the result would be 1997 4 16 17 30 0 which is different from the
 635         // input of 1997 4 16 18 30 0.
 636         test4064654(1997, 4, 16, 18, 30, 0);
 637     }
 638     void test4064654(int yr, int mo, int dt, int hr, int mn, int sc) {
 639         Date date;
 640         Calendar gmtcal = Calendar.getInstance();
 641         gmtcal.setTimeZone(TimeZone.getTimeZone("Africa/Casablanca"));
 642         gmtcal.set(yr, mo - 1, dt, hr, mn, sc);
 643         gmtcal.set(MILLISECOND, 0);
 644 
 645         date = gmtcal.getTime();
 646         logln("date = " + date);
 647 
 648         Calendar cal = Calendar.getInstance();
 649         cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
 650         cal.setTime(date);
 651 
 652         int offset = cal.getTimeZone().getOffset(cal.get(ERA),
 653                 cal.get(YEAR),
 654                 cal.get(MONTH),
 655                 cal.get(DATE),
 656                 cal.get(DAY_OF_WEEK),
 657                 cal.get(MILLISECOND));
 658 
 659         logln("offset for " + date + "= " + (offset / 1000 / 60 / 60.0) + "hr");
 660 
 661         int utc = ((cal.get(HOUR_OF_DAY) * 60
 662                 + cal.get(MINUTE)) * 60
 663                 + cal.get(SECOND)) * 1000
 664                 + cal.get(MILLISECOND) - offset;
 665 
 666         int expected = ((hr * 60 + mn) * 60 + sc) * 1000;
 667 
 668         if (utc != expected) {
 669             errln("FAIL: Discrepancy of "
 670                     + (utc - expected) + " millis = "
 671                     + ((utc - expected) / 1000 / 60 / 60.0) + " hr");
 672         }
 673     }
 674 
 675     // Verify that add and set work regardless of the order in which
 676     // they are called.
 677     public void TestAddSetOrder621() {
 678         @SuppressWarnings("deprecation")
 679         Date d = new Date(97, 4, 14, 13, 23, 45);
 680 
 681         Calendar cal = Calendar.getInstance();
 682         cal.setTime(d);
 683         cal.add(DATE, -5);
 684         cal.set(HOUR_OF_DAY, 0);
 685         cal.set(MINUTE, 0);
 686         cal.set(SECOND, 0);
 687         // ma feb 03 00:00:00 GMT+00:00 1997
 688         String s = cal.getTime().toString();
 689 
 690         cal = Calendar.getInstance();
 691         cal.setTime(d);
 692         cal.set(HOUR_OF_DAY, 0);
 693         cal.set(MINUTE, 0);
 694         cal.set(SECOND, 0);
 695         cal.add(DATE, -5);
 696         // ma feb 03 13:11:06 GMT+00:00 1997
 697         String s2 = cal.getTime().toString();
 698 
 699         if (s.equals(s2)) {
 700             logln("Pass: " + s + " == " + s2);
 701         } else {
 702             errln("FAIL: " + s + " != " + s2);
 703         }
 704     }
 705 
 706     // Verify that add works.
 707     public void TestAdd520() {
 708         int y = 1997, m = FEBRUARY, d = 1;
 709         GregorianCalendar temp = new GregorianCalendar(y, m, d);
 710         check520(temp, y, m, d);
 711 
 712         temp.add(YEAR, 1);
 713         y++;
 714         check520(temp, y, m, d);
 715 
 716         temp.add(MONTH, 1);
 717         m++;
 718         check520(temp, y, m, d);
 719 
 720         temp.add(DATE, 1);
 721         d++;
 722         check520(temp, y, m, d);
 723 
 724         temp.add(DATE, 2);
 725         d += 2;
 726         check520(temp, y, m, d);
 727 
 728         temp.add(DATE, 28);
 729         d = 1;
 730         ++m;
 731         check520(temp, y, m, d);
 732     }
 733 
 734     void check520(Calendar c, int y, int m, int d) {
 735         if (c.get(YEAR) != y
 736                 || c.get(MONTH) != m
 737                 || c.get(DATE) != d) {
 738             errln("FAILURE: Expected YEAR/MONTH/DATE of "
 739                     + y + "/" + (m + 1) + "/" + d
 740                     + "; got "
 741                     + c.get(YEAR) + "/"
 742                     + (c.get(MONTH) + 1) + "/"
 743                     + c.get(DATE));
 744         } else {
 745             logln("Confirmed: "
 746                     + y + "/" + (m + 1) + "/" + d);
 747         }
 748     }
 749 
 750     // Verify that setting fields works.  This test fails when an exception is thrown.
 751     public void TestFieldSet4781() {
 752         try {
 753             GregorianCalendar g = new GregorianCalendar();
 754             GregorianCalendar g2 = new GregorianCalendar();
 755             // At this point UTC value is set, various fields are not.
 756             // Now set to noon.
 757             g2.set(HOUR, 12);
 758             g2.set(MINUTE, 0);
 759             g2.set(SECOND, 0);
 760             // At this point the object thinks UTC is NOT set, but fields are set.
 761             // The following line will result in IllegalArgumentException because
 762             // it thinks the YEAR is set and it is NOT.
 763             if (g2.equals(g)) {
 764                 logln("Same");
 765             } else {
 766                 logln("Different");
 767             }
 768         } catch (IllegalArgumentException e) {
 769             errln("Unexpected exception seen: " + e);
 770         }
 771     }
 772 
 773     // Test serialization of a Calendar object
 774     public void TestSerialize337() {
 775         Calendar cal = Calendar.getInstance();
 776 
 777         boolean ok = false;
 778 
 779         try {
 780             FileOutputStream f = new FileOutputStream(FILENAME);
 781             ObjectOutput s = new ObjectOutputStream(f);
 782             s.writeObject(PREFIX);
 783             s.writeObject(cal);
 784             s.writeObject(POSTFIX);
 785             f.close();
 786 
 787             FileInputStream in = new FileInputStream(FILENAME);
 788             ObjectInputStream t = new ObjectInputStream(in);
 789             String pre = (String) t.readObject();
 790             Calendar c = (Calendar) t.readObject();
 791             String post = (String) t.readObject();
 792             in.close();
 793 
 794             ok = pre.equals(PREFIX)
 795                     && post.equals(POSTFIX)
 796                     && cal.equals(c);
 797 
 798             File fl = new File(FILENAME);
 799             fl.delete();
 800         } catch (IOException e) {
 801             errln("FAIL: Exception received:");
 802             // e.printStackTrace(log);
 803         } catch (ClassNotFoundException e) {
 804             errln("FAIL: Exception received:");
 805             // e.printStackTrace(log);
 806         }
 807 
 808         if (!ok) {
 809             errln("Serialization of Calendar object failed.");
 810         }
 811     }
 812     static final String PREFIX = "abc";
 813     static final String POSTFIX = "def";
 814     static final String FILENAME = "tmp337.bin";
 815 
 816     // Try to zero out the seconds field
 817     public void TestSecondsZero121() {
 818         Calendar cal = new GregorianCalendar();
 819         // Initialize with current date/time
 820         cal.setTime(new Date());
 821         // Round down to minute
 822         cal.set(SECOND, 0);
 823         Date d = cal.getTime();
 824         String s = d.toString();
 825         if (s.indexOf(":00 ") < 0) {
 826             errln("Expected to see :00 in " + s);
 827         }
 828     }
 829 
 830     // Try various sequences of add, set, and get method calls.
 831     public void TestAddSetGet0610() {
 832         //
 833         // Error case 1:
 834         // - Upon initialization calendar fields, millis = System.currentTime
 835         // - After set is called fields are initialized, time is not
 836         // - Addition uses millis which are still *now*
 837         //
 838         {
 839             Calendar calendar = new GregorianCalendar();
 840             calendar.set(1993, JANUARY, 4);
 841             logln("1A) " + value(calendar));
 842             calendar.add(DATE, 1);
 843             String v = value(calendar);
 844             logln("1B) " + v);
 845             logln("--) 1993/0/5");
 846             if (!v.equals(EXPECTED_0610)) {
 847                 errln("Expected " + EXPECTED_0610
 848                         + "; saw " + v);
 849             }
 850         }
 851 
 852         //
 853         // Error case 2:
 854         // - Upon initialization calendar fields set, millis = 0
 855         // - Addition uses millis which are still 1970, 0, 1
 856         //
 857         {
 858             Calendar calendar = new GregorianCalendar(1993, JANUARY, 4);
 859             logln("2A) " + value(calendar));
 860             calendar.add(DATE, 1);
 861             String v = value(calendar);
 862             logln("2B) " + v);
 863             logln("--) 1993/0/5");
 864             if (!v.equals(EXPECTED_0610)) {
 865                 errln("Expected " + EXPECTED_0610
 866                         + "; saw " + v);
 867             }
 868         }
 869 
 870         //
 871         // Error case 3:
 872         // - Upon initialization calendar fields, millis = 0
 873         // - getTime( ) is called which forces the millis to be set
 874         // - Addition uses millis which are correct
 875         //
 876         {
 877             Calendar calendar = new GregorianCalendar(1993, JANUARY, 4);
 878             logln("3A) " + value(calendar));
 879             calendar.getTime();
 880             calendar.add(DATE, 1);
 881             String v = value(calendar);
 882             logln("3B) " + v);
 883             logln("--) 1993/0/5");
 884             if (!v.equals(EXPECTED_0610)) {
 885                 errln("Expected " + EXPECTED_0610
 886                         + "; saw " + v);
 887             }
 888         }
 889     }
 890     static String value(Calendar calendar) {
 891         return (calendar.get(YEAR) + "/"
 892                 + calendar.get(MONTH) + "/"
 893                 + calendar.get(DATE));
 894     }
 895     static String EXPECTED_0610 = "1993/0/5";
 896 
 897     // Test that certain fields on a certain date are as expected.
 898     public void TestFields060() {
 899         int year = 1997;
 900         int month = OCTOBER;  //october
 901         int dDate = 22;   //DAYOFWEEK should return 3 for Wednesday
 902         GregorianCalendar calendar = null;
 903 
 904         calendar = new GregorianCalendar(year, month, dDate);
 905         for (int i = 0; i < EXPECTED_FIELDS.length;) {
 906             int field = EXPECTED_FIELDS[i++];
 907             int expected = EXPECTED_FIELDS[i++];
 908             if (calendar.get(field) != expected) {
 909                 errln("Expected field " + field + " to have value " + expected
 910                         + "; received " + calendar.get(field) + " instead");
 911             }
 912         }
 913     }
 914     static int[] EXPECTED_FIELDS = {
 915         YEAR, 1997,
 916         MONTH, OCTOBER,
 917         DAY_OF_MONTH, 22,
 918         DAY_OF_WEEK, WEDNESDAY,
 919         DAY_OF_WEEK_IN_MONTH, 4,
 920         DAY_OF_YEAR, 295};
 921 
 922     static final String[] calendarFieldNames = {
 923         /*  0 */ "ERA",
 924         /*  1 */ "YEAR",
 925         /*  2 */ "MONTH",
 926         /*  3 */ "WEEK_OF_YEAR",
 927         /*  4 */ "WEEK_OF_MONTH",
 928         /*  5 */ "DAY_OF_MONTH",
 929         /*  6 */ "DAY_OF_YEAR",
 930         /*  7 */ "DAY_OF_WEEK",
 931         /*  8 */ "DAY_OF_WEEK_IN_MONTH",
 932         /*  9 */ "AM_PM",
 933         /* 10 */ "HOUR",
 934         /* 11 */ "HOUR_OF_DAY",
 935         /* 12 */ "MINUTE",
 936         /* 13 */ "SECOND",
 937         /* 14 */ "MILLISECOND",
 938         /* 15 */ "ZONE_OFFSET",
 939         /* 16 */ "DST_OFFSET"};
 940 
 941     // Verify that the fields are as expected (mostly zero) at the epoch start.
 942     // Note that we adjust for the default timezone to get most things to zero.
 943     public void TestEpochStartFields() {
 944         String[][] lt = {
 945             {"en", "US", "US/Pacific"},        /* First day = 1, Minimum day = 1 */
 946             {"en", "US", "America/Anchorage"}, /* First day = 1, Minimum day = 1 */
 947             {"en", "TO", "Pacific/Tongatapu"}, /* First day = 1, Minimum day = 1 */
 948             {"en", "MH", "Pacific/Majuro"},    /* First day = 1, Minimum day = 1 */
 949             {"ja", "JP", "Asia/Tokyo"},        /* First day = 1, Minimum day = 1 */
 950             {"iw", "IL", "Asia/Jerusalem"},    /* First day = 1, Minimum day = 1 */
 951             {"hi", "IN", "Asia/Jakarta"},      /* First day = 1, Minimum day = 1 */
 952             {"en", "GB", "Europe/London"},     /* First day = 2, Minimum day = 1 */
 953             {"en", "GB", "GMT"},               /* First day = 2, Minimum day = 1 */
 954             {"de", "DE", "Europe/Berlin"},     /* First day = 2, Minimum day = 4 */
 955             {"ar", "EG", "Africa/Cairo"}};     /* First day = 7, Minimum day = 1 */
 956 
 957         int[][] goldenData = {
 958             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, -28800000, 0},
 959             {1, 1969, 11, 1, 5, 31, 365, 4, 5, 1, 11, 23, 0, 0, 0, -36000000, 0},
 960             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 46800000, 0},
 961             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 43200000, 0},
 962             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 32400000, 0},
 963             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 7200000, 0},
 964             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 25200000, 0},
 965             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 1, 1, 0, 0, 0, 3600000, 0},
 966             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0},
 967             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 3600000, 0},
 968             {1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 7200000, 0}};
 969 
 970         Locale savedLocale = Locale.getDefault();
 971         TimeZone savedTimeZone = TimeZone.getDefault();
 972 
 973         try {
 974             for (int j = 0; j < lt.length; j++) {
 975                 Locale l = new Locale(lt[j][0], lt[j][1]);
 976                 TimeZone z = TimeZone.getTimeZone(lt[j][2]);
 977                 Locale.setDefault(l);
 978                 TimeZone.setDefault(z);
 979                 Calendar c = Calendar.getInstance();
 980                 Date d = new Date(-z.getRawOffset());
 981 
 982                 int val;
 983                 int[] EPOCH_FIELDS = goldenData[j];
 984                 c.setTime(d);
 985 
 986                 boolean err = false;
 987                 for (int i = 0; i < calendarFieldNames.length; ++i) {
 988                     if ((val = c.get(i)) != EPOCH_FIELDS[i]) {
 989                         errln("Wrong value: " + val
 990                                 + " for field(" + calendarFieldNames[i]
 991                                 + "), expected: " + EPOCH_FIELDS[i]);
 992                         err = true;
 993                     }
 994                 }
 995                 if (err) {
 996                     errln("Failed: \n\tDate=" + d + "\n\tTimeZone=" + z
 997                             + "\n\tLocale=" + l + "\n\tCalendar=" + c);
 998                 }
 999             }
1000         } finally {
1001             Locale.setDefault(savedLocale);
1002             TimeZone.setDefault(savedTimeZone);
1003         }
1004     }
1005 
1006     // Verify that as you add days to the calendar (e.g., 24 day periods),
1007     // the day of the week shifts in the expected pattern.
1008     public void TestDOWProgression() {
1009         Calendar cal
1010                 = new GregorianCalendar(1972, OCTOBER, 26);
1011         marchByDelta(cal, 24); // Last parameter must be != 0 modulo 7
1012     }
1013 
1014     // Supply a delta which is not a multiple of 7.
1015     void marchByDelta(Calendar cal, int delta) {
1016         Calendar cur = (Calendar) cal.clone();
1017         int initialDOW = cur.get(DAY_OF_WEEK);
1018         int DOW, newDOW = initialDOW;
1019         do {
1020             DOW = newDOW;
1021             logln("DOW = " + DOW + "  " + cur.getTime());
1022 
1023             cur.add(DAY_OF_WEEK, delta);
1024             newDOW = cur.get(DAY_OF_WEEK);
1025             int expectedDOW = 1 + (DOW + delta - 1) % 7;
1026             if (newDOW != expectedDOW) {
1027                 errln("Day of week should be " + expectedDOW
1028                         + " instead of " + newDOW + " on " + cur.getTime());
1029                 return;
1030             }
1031         } while (newDOW != initialDOW);
1032     }
1033 
1034     public void TestActualMinMax() {
1035         Calendar cal = new GregorianCalendar(1967, MARCH, 10);
1036         cal.setFirstDayOfWeek(SUNDAY);
1037         cal.setMinimalDaysInFirstWeek(3);
1038 
1039         if (cal.getActualMinimum(DAY_OF_MONTH) != 1) {
1040             errln("Actual minimum date for 3/10/1967 should have been 1; got "
1041                     + cal.getActualMinimum(DAY_OF_MONTH));
1042         }
1043         if (cal.getActualMaximum(DAY_OF_MONTH) != 31) {
1044             errln("Actual maximum date for 3/10/1967 should have been 31; got "
1045                     + cal.getActualMaximum(DAY_OF_MONTH));
1046         }
1047 
1048         cal.set(MONTH, FEBRUARY);
1049         if (cal.getActualMaximum(DAY_OF_MONTH) != 28) {
1050             errln("Actual maximum date for 2/10/1967 should have been 28; got "
1051                     + cal.getActualMaximum(DAY_OF_MONTH));
1052         }
1053         if (cal.getActualMaximum(DAY_OF_YEAR) != 365) {
1054             errln("Number of days in 1967 should have been 365; got "
1055                     + cal.getActualMaximum(DAY_OF_YEAR));
1056         }
1057 
1058         cal.set(YEAR, 1968);
1059         if (cal.getActualMaximum(DAY_OF_MONTH) != 29) {
1060             errln("Actual maximum date for 2/10/1968 should have been 29; got "
1061                     + cal.getActualMaximum(DAY_OF_MONTH));
1062         }
1063         if (cal.getActualMaximum(DAY_OF_YEAR) != 366) {
1064             errln("Number of days in 1968 should have been 366; got "
1065                     + cal.getActualMaximum(DAY_OF_YEAR));
1066         }
1067         // Using week settings of SUNDAY/3 (see above)
1068         if (cal.getActualMaximum(WEEK_OF_YEAR) != 52) {
1069             errln("Number of weeks in 1968 should have been 52; got "
1070                     + cal.getActualMaximum(WEEK_OF_YEAR));
1071         }
1072 
1073         cal.set(YEAR, 1976);
1074         // Using week settings of SUNDAY/3 (see above)
1075         if (cal.getActualMaximum(WEEK_OF_YEAR) != 53) {
1076             errln("Number of weeks in 1976 should have been 53; got "
1077                     + cal.getActualMaximum(WEEK_OF_YEAR));
1078         }
1079     }
1080 
1081     public void TestRoll() {
1082         Calendar cal = new GregorianCalendar(1997, JANUARY, 31);
1083 
1084         int[] dayValues = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31};
1085 
1086         for (int i = 0; i < dayValues.length; i++) {
1087             Calendar cal2 = (Calendar) cal.clone();
1088             cal2.roll(MONTH, i);
1089             if (cal2.get(DAY_OF_MONTH) != dayValues[i]) {
1090                 errln("Rolling the month in 1/31/1997 up by " + i + " should have yielded "
1091                         + ((i + 1) % 12) + "/" + dayValues[i] + "/1997, but actually yielded "
1092                         + ((i + 1) % 12) + "/" + cal2.get(DAY_OF_MONTH) + "/1997.");
1093             }
1094         }
1095 
1096         cal.set(1996, FEBRUARY, 29);
1097 
1098         int[] monthValues = {1, 2, 2, 2, 1, 2, 2, 2, 1, 2};
1099         int[] dayValues2 = {29, 1, 1, 1, 29, 1, 1, 1, 29, 1};
1100 
1101         for (int i = 0; i < dayValues2.length; i++) {
1102             Calendar cal2 = (Calendar) cal.clone();
1103             cal2.roll(YEAR, i);
1104             if (cal2.get(DAY_OF_MONTH) != dayValues2[i] || cal2.get(MONTH)
1105                     != monthValues[i]) {
1106                 errln("Rolling the year in 2/29/1996 up by " + i + " should have yielded "
1107                         + (monthValues[i] + 1) + "/" + dayValues2[i] + "/"
1108                         + (1996 + i) + ", but actually yielded "
1109                         + (cal2.get(MONTH) + 1) + "/"
1110                         + cal2.get(DAY_OF_MONTH) + "/" + (1996 + i) + ".");
1111             }
1112         }
1113 
1114         // Test rolling hour of day
1115         cal.set(HOUR_OF_DAY, 0);
1116         cal.roll(HOUR_OF_DAY, -2);
1117         int f = cal.get(HOUR_OF_DAY);
1118         if (f != 22) {
1119             errln("Rolling HOUR_OF_DAY=0 delta=-2 gave " + f + " Wanted 22");
1120         }
1121         cal.roll(HOUR_OF_DAY, 5);
1122         f = cal.get(HOUR_OF_DAY);
1123         if (f != 3) {
1124             errln("Rolling HOUR_OF_DAY=22 delta=5 gave " + f + " Wanted 3");
1125         }
1126         cal.roll(HOUR_OF_DAY, 21);
1127         f = cal.get(HOUR_OF_DAY);
1128         if (f != 0) {
1129             errln("Rolling HOUR_OF_DAY=3 delta=21 gave " + f + " Wanted 0");
1130         }
1131 
1132         // Test rolling hour
1133         cal.set(HOUR_OF_DAY, 0);
1134         cal.roll(HOUR, -2);
1135         f = cal.get(HOUR);
1136         if (f != 10) {
1137             errln("Rolling HOUR=0 delta=-2 gave " + f + " Wanted 10");
1138         }
1139         cal.roll(HOUR, 5);
1140         f = cal.get(HOUR);
1141         if (f != 3) {
1142             errln("Rolling HOUR=10 delta=5 gave " + f + " Wanted 3");
1143         }
1144         cal.roll(HOUR, 9);
1145         f = cal.get(HOUR);
1146         if (f != 0) {
1147             errln("Rolling HOUR=3 delta=9 gave " + f + " Wanted 0");
1148         }
1149     }
1150 
1151     /*
1152      * Confirm that multiple calls to Calendar.set() works correctly.
1153      */
1154     public void Test4374886() {
1155         Locale savedLocale = Locale.getDefault();
1156         TimeZone savedTimeZone = TimeZone.getDefault();
1157 
1158         try {
1159             Locale.setDefault(Locale.US);
1160             TimeZone.setDefault(TimeZone.getTimeZone("PST"));
1161 
1162             Calendar cal = Calendar.getInstance();
1163             cal.set(YEAR, 2001);
1164             cal.set(MONTH, OCTOBER);
1165             cal.set(WEEK_OF_YEAR, 4);
1166             cal.set(DAY_OF_WEEK, 2);
1167 
1168             if (cal.get(YEAR) != 2001
1169                     || cal.get(MONTH) != JANUARY
1170                     || cal.get(DATE) != 22
1171                     || cal.get(DAY_OF_WEEK) != MONDAY) {
1172                 errln("Failed : got " + cal.getTime() + ", expected Mon Jan 22, 2001");
1173             }
1174         } finally {
1175             Locale.setDefault(savedLocale);
1176             TimeZone.setDefault(savedTimeZone);
1177         }
1178     }
1179 }
1180 
1181 //eof