Path: blob/master/test/jdk/java/util/Calendar/CalendarRegression.java
41149 views
/*1* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 4031502 4035301 4040996 4051765 4059654 4061476 4070502 4071197 407138526* 4073929 4083167 4086724 4092362 4095407 4096231 4096539 4100311 410327127* 4106136 4108764 4114578 4118384 4125881 4125892 4136399 4141665 414293328* 4145158 4145983 4147269 4149677 4162587 4165343 4166109 4167060 417351629* 4174361 4177484 4197699 4209071 4288792 4328747 4413980 4546637 462399730* 4685354 4655637 4683492 4080631 4080631 4167995 4340146 463940731* 4652815 4652830 4740554 4936355 4738710 4633646 4846659 4822110 496064232* 4973919 4980088 4965624 5013094 5006864 815207733* @library /java/text/testlib34* @run main CalendarRegression35*/36import java.io.ByteArrayInputStream;37import java.io.ByteArrayOutputStream;38import java.io.IOException;39import java.io.ObjectInputStream;40import java.io.ObjectOutputStream;41import java.text.DateFormat;42import java.text.NumberFormat;43import java.text.SimpleDateFormat;44import java.util.Calendar;45import java.util.Date;46import java.util.GregorianCalendar;47import java.util.HashMap;48import java.util.Locale;49import java.util.Map;50import java.util.SimpleTimeZone;51import java.util.TimeZone;5253import static java.util.Calendar.*;5455public class CalendarRegression extends IntlTest {5657public static void main(String[] args) throws Exception {58new CalendarRegression().run(args);59}6061/*62Synopsis: java.sql.Timestamp constructor works wrong on Windows 956364==== Here is the test ====65public static void main (String args[]) {66java.sql.Timestamp t= new java.sql.Timestamp(0,15,5,5,8,13,123456700);67logln("expected=1901-04-05 05:08:13.1234567");68logln(" result="+t);69}7071==== Here is the output of the test on Solaris or NT ====72expected=1901-04-05 05:08:13.123456773result=1901-04-05 05:08:13.12345677475==== Here is the output of the test on Windows95 ====76expected=1901-04-05 05:08:13.123456777result=1901-04-05 06:08:13.123456778*/79public void Test4031502() {80// This bug actually occurs on Windows NT as well, and doesn't81// require the host zone to be set; it can be set in Java.82String[] ids = TimeZone.getAvailableIDs();83boolean bad = false;84for (int i = 0; i < ids.length; ++i) {85TimeZone zone = TimeZone.getTimeZone(ids[i]);86GregorianCalendar cal = new GregorianCalendar(zone);87cal.clear();88cal.set(1900, 15, 5, 5, 8, 13);89if (cal.get(HOUR) != 5) {90logln(zone.getID() + " "91+ //zone.useDaylightTime() + " "92+ cal.get(DST_OFFSET) / (60 * 60 * 1000) + " "93+ zone.getRawOffset() / (60 * 60 * 1000)94+ ": HOUR = " + cal.get(HOUR));95bad = true;96}97}98if (bad) {99errln("TimeZone problems with GC");100}101}102103public void Test4035301() {104GregorianCalendar c = new GregorianCalendar(98, 8, 7);105GregorianCalendar d = new GregorianCalendar(98, 8, 7);106if (c.after(d)107|| c.after(c)108|| c.before(d)109|| c.before(c)110|| !c.equals(c)111|| !c.equals(d)) {112errln("Fail");113}114}115116public void Test4040996() {117String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);118SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);119pdt.setStartRule(APRIL, 1, SUNDAY, 2 * 60 * 60 * 1000);120pdt.setEndRule(OCTOBER, -1, SUNDAY, 2 * 60 * 60 * 1000);121Calendar calendar = new GregorianCalendar(pdt);122123calendar.set(MONTH, 3);124calendar.set(DAY_OF_MONTH, 18);125calendar.set(SECOND, 30);126127logln("MONTH: " + calendar.get(MONTH));128logln("DAY_OF_MONTH: "129+ calendar.get(DAY_OF_MONTH));130logln("MINUTE: " + calendar.get(MINUTE));131logln("SECOND: " + calendar.get(SECOND));132133calendar.add(SECOND, 6);134//This will print out todays date for MONTH and DAY_OF_MONTH135//instead of the date it was set to.136//This happens when adding MILLISECOND or MINUTE also137logln("MONTH: " + calendar.get(MONTH));138logln("DAY_OF_MONTH: "139+ calendar.get(DAY_OF_MONTH));140logln("MINUTE: " + calendar.get(MINUTE));141logln("SECOND: " + calendar.get(SECOND));142if (calendar.get(MONTH) != 3143|| calendar.get(DAY_OF_MONTH) != 18144|| calendar.get(SECOND) != 36) {145errln("Fail: Calendar.add misbehaves");146}147}148149public void Test4051765() {150Calendar cal = Calendar.getInstance();151cal.setLenient(false);152cal.set(DAY_OF_WEEK, 0);153try {154cal.getTime();155errln("Fail: DAY_OF_WEEK 0 should be disallowed");156} catch (IllegalArgumentException e) {157return;158}159}160161/* User error - no bug here162public void Test4059524() {163// Create calendar for April 10, 1997164GregorianCalendar calendar = new GregorianCalendar();165// print out a bunch of interesting things166logln("ERA: " + calendar.get(calendar.ERA));167logln("YEAR: " + calendar.get(calendar.YEAR));168logln("MONTH: " + calendar.get(calendar.MONTH));169logln("WEEK_OF_YEAR: " +170calendar.get(calendar.WEEK_OF_YEAR));171logln("WEEK_OF_MONTH: " +172calendar.get(calendar.WEEK_OF_MONTH));173logln("DATE: " + calendar.get(calendar.DATE));174logln("DAY_OF_MONTH: " +175calendar.get(calendar.DAY_OF_MONTH));176logln("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR));177logln("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK));178logln("DAY_OF_WEEK_IN_MONTH: " +179calendar.get(calendar.DAY_OF_WEEK_IN_MONTH));180logln("AM_PM: " + calendar.get(calendar.AM_PM));181logln("HOUR: " + calendar.get(calendar.HOUR));182logln("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY));183logln("MINUTE: " + calendar.get(calendar.MINUTE));184logln("SECOND: " + calendar.get(calendar.SECOND));185logln("MILLISECOND: " + calendar.get(calendar.MILLISECOND));186logln("ZONE_OFFSET: "187+ (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000)));188logln("DST_OFFSET: "189+ (calendar.get(calendar.DST_OFFSET)/(60*60*1000)));190calendar = new GregorianCalendar(1997,3,10);191calendar.getTime();192logln("April 10, 1997");193logln("ERA: " + calendar.get(calendar.ERA));194logln("YEAR: " + calendar.get(calendar.YEAR));195logln("MONTH: " + calendar.get(calendar.MONTH));196logln("WEEK_OF_YEAR: " +197calendar.get(calendar.WEEK_OF_YEAR));198logln("WEEK_OF_MONTH: " +199calendar.get(calendar.WEEK_OF_MONTH));200logln("DATE: " + calendar.get(calendar.DATE));201logln("DAY_OF_MONTH: " +202calendar.get(calendar.DAY_OF_MONTH));203logln("DAY_OF_YEAR: " + calendar.get(calendar.DAY_OF_YEAR));204logln("DAY_OF_WEEK: " + calendar.get(calendar.DAY_OF_WEEK));205logln("DAY_OF_WEEK_IN_MONTH: " + calendar.get(calendar.DAY_OF_WEEK_IN_MONTH));206logln("AM_PM: " + calendar.get(calendar.AM_PM));207logln("HOUR: " + calendar.get(calendar.HOUR));208logln("HOUR_OF_DAY: " + calendar.get(calendar.HOUR_OF_DAY));209logln("MINUTE: " + calendar.get(calendar.MINUTE));210logln("SECOND: " + calendar.get(calendar.SECOND));211logln("MILLISECOND: " + calendar.get(calendar.MILLISECOND));212logln("ZONE_OFFSET: "213+ (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); // in hours214logln("DST_OFFSET: "215+ (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); // in hours216}217*/218public void Test4059654() {219GregorianCalendar gc = new GregorianCalendar();220221gc.set(1997, 3, 1, 15, 16, 17); // April 1, 1997222223gc.set(HOUR, 0);224gc.set(AM_PM, AM);225gc.set(MINUTE, 0);226gc.set(SECOND, 0);227gc.set(MILLISECOND, 0);228229Date cd = gc.getTime();230@SuppressWarnings("deprecation")231Date exp = new Date(97, 3, 1, 0, 0, 0);232if (!cd.equals(exp)) {233errln("Fail: Calendar.set broken. Got " + cd + " Want " + exp);234}235}236237public void Test4061476() {238SimpleDateFormat fmt = new SimpleDateFormat("ddMMMyy", Locale.UK);239Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"),240Locale.UK);241fmt.setCalendar(cal);242try {243Date date = fmt.parse("29MAY97");244cal.setTime(date);245} catch (Exception e) {246}247cal.set(HOUR_OF_DAY, 13);248logln("Hour: " + cal.get(HOUR_OF_DAY));249cal.add(HOUR_OF_DAY, 6);250logln("Hour: " + cal.get(HOUR_OF_DAY));251if (cal.get(HOUR_OF_DAY) != 19) {252errln("Fail: Want 19 Got " + cal.get(HOUR_OF_DAY));253}254}255256public void Test4070502() {257@SuppressWarnings("deprecation")258Date d = getAssociatedDate(new Date(98, 0, 30));259Calendar cal = new GregorianCalendar();260cal.setTime(d);261if (cal.get(DAY_OF_WEEK) == SATURDAY262|| cal.get(DAY_OF_WEEK) == SUNDAY) {263errln("Fail: Want weekday Got " + d);264}265}266267/**268* Get the associated date starting from a specified date269* NOTE: the unnecessary "getTime()'s" below are a work-around for a270* bug in jdk 1.1.3 (and probably earlier versions also)271* <p>272* @param date The date to start from273*/274public static Date getAssociatedDate(Date d) {275GregorianCalendar cal = new GregorianCalendar();276cal.setTime(d);277//cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH278// cal.getTime(); // <--- REMOVE THIS TO SEE BUG279while (true) {280int wd = cal.get(DAY_OF_WEEK);281if (wd == SATURDAY || wd == SUNDAY) {282cal.add(DATE, 1);283// cal.getTime();284} else {285break;286}287}288return cal.getTime();289}290291public void Test4071197() {292dowTest(false);293dowTest(true);294}295296void dowTest(boolean lenient) {297GregorianCalendar cal = new GregorianCalendar();298cal.set(1997, AUGUST, 12); // Wednesday299// cal.getTime(); // Force update300cal.setLenient(lenient);301cal.set(1996, DECEMBER, 1); // Set the date to be December 1, 1996302int dow = cal.get(DAY_OF_WEEK);303int min = cal.getMinimum(DAY_OF_WEEK);304int max = cal.getMaximum(DAY_OF_WEEK);305logln(cal.getTime().toString());306if (min != SUNDAY || max != SATURDAY) {307errln("FAIL: Min/max bad");308}309if (dow < min || dow > max) {310errln("FAIL: Day of week " + dow + " out of range");311}312if (dow != SUNDAY) {313errln("FAIL: Day of week should be SUNDAY Got " + dow);314}315}316317@SuppressWarnings("deprecation")318public void Test4071385() {319Calendar cal = Calendar.getInstance();320cal.setTime(new Date(98, JUNE, 24));321cal.set(MONTH, NOVEMBER); // change a field322logln(cal.getTime().toString());323if (!cal.getTime().equals(new Date(98, NOVEMBER, 24))) {324errln("Fail");325}326}327328public void Test4073929() {329GregorianCalendar foo1 = new GregorianCalendar(1997, 8, 27);330foo1.add(DAY_OF_MONTH, +1);331int testyear = foo1.get(YEAR);332int testmonth = foo1.get(MONTH);333int testday = foo1.get(DAY_OF_MONTH);334if (testyear != 1997335|| testmonth != 8336|| testday != 28) {337errln("Fail: Calendar not initialized");338}339}340341public void Test4083167() {342TimeZone saveZone = TimeZone.getDefault();343try {344TimeZone.setDefault(TimeZone.getTimeZone("UTC"));345Date firstDate = new Date();346Calendar cal = new GregorianCalendar();347cal.setTime(firstDate);348long firstMillisInDay = cal.get(HOUR_OF_DAY) * 3600000L349+ cal.get(MINUTE) * 60000L350+ cal.get(SECOND) * 1000L351+ cal.get(MILLISECOND);352353logln("Current time: " + firstDate.toString());354355for (int validity = 0; validity < 30; validity++) {356Date lastDate = new Date(firstDate.getTime()357+ (long) validity * 1000 * 24 * 60 * 60);358cal.setTime(lastDate);359long millisInDay = cal.get(HOUR_OF_DAY) * 3600000L360+ cal.get(MINUTE) * 60000L361+ cal.get(SECOND) * 1000L362+ cal.get(MILLISECOND);363if (firstMillisInDay != millisInDay) {364errln("Day has shifted " + lastDate);365}366}367} finally {368TimeZone.setDefault(saveZone);369}370}371372public void Test4086724() {373SimpleDateFormat date;374TimeZone saveZone = TimeZone.getDefault();375Locale saveLocale = Locale.getDefault();376377String summerTime = "British Summer Time";378String standardTime = "Greenwich Mean Time";379try {380Locale.setDefault(Locale.UK);381TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));382date = new SimpleDateFormat("zzzz");383384Calendar cal = Calendar.getInstance();385cal.set(1997, SEPTEMBER, 30);386Date now = cal.getTime();387String formattedDate = date.format(now);388if (!formattedDate.equals(summerTime)) {389errln("Wrong display name \"" + formattedDate390+ "\" for <" + now + ">");391}392int weekOfYear = cal.get(WEEK_OF_YEAR);393if (weekOfYear != 40) {394errln("Wrong week-of-year " + weekOfYear395+ " for <" + now + ">");396}397398cal.set(1996, DECEMBER, 31);399now = cal.getTime();400formattedDate = date.format(now);401if (!formattedDate.equals(standardTime)) {402errln("Wrong display name \"" + formattedDate403+ "\" for <" + now + ">");404}405weekOfYear = cal.get(WEEK_OF_YEAR);406if (weekOfYear != 1) {407errln("Wrong week-of-year " + weekOfYear408+ " for <" + now + ">");409}410411cal.set(1997, JANUARY, 1);412now = cal.getTime();413formattedDate = date.format(now);414if (!formattedDate.equals(standardTime)) {415errln("Wrong display name \"" + formattedDate416+ "\" for <" + now + ">");417}418weekOfYear = cal.get(WEEK_OF_YEAR);419if (weekOfYear != 1) {420errln("Wrong week-of-year " + weekOfYear421+ " for <" + now + ">");422}423424cal.set(1997, JANUARY, 8);425now = cal.getTime();426formattedDate = date.format(now);427if (!formattedDate.equals(standardTime)) {428errln("Wrong display name \"" + formattedDate429+ "\" for <" + now + ">");430}431weekOfYear = cal.get(WEEK_OF_YEAR);432if (weekOfYear != 2) {433errln("Wrong week-of-year " + weekOfYear434+ " for <" + now + ">");435}436437} finally {438Locale.setDefault(saveLocale);439TimeZone.setDefault(saveZone);440}441}442443public void Test4092362() {444GregorianCalendar cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40);445/*cal1.set( Calendar.YEAR, 1997 );446cal1.set( Calendar.MONTH, 10 );447cal1.set( Calendar.DATE, 11 );448cal1.set( Calendar.HOUR, 10 );449cal1.set( Calendar.MINUTE, 20 );450cal1.set( Calendar.SECOND, 40 ); */451452logln(" Cal1 = " + cal1.getTime().getTime());453logln(" Cal1 time in ms = " + cal1.get(MILLISECOND));454for (int k = 0; k < 100; k++);455456GregorianCalendar cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40);457/*cal2.set( Calendar.YEAR, 1997 );458cal2.set( Calendar.MONTH, 10 );459cal2.set( Calendar.DATE, 11 );460cal2.set( Calendar.HOUR, 10 );461cal2.set( Calendar.MINUTE, 20 );462cal2.set( Calendar.SECOND, 40 ); */463464logln(" Cal2 = " + cal2.getTime().getTime());465logln(" Cal2 time in ms = " + cal2.get(MILLISECOND));466if (!cal1.equals(cal2)) {467errln("Fail: Milliseconds randomized");468}469}470471public void Test4095407() {472GregorianCalendar a = new GregorianCalendar(1997, NOVEMBER, 13);473int dow = a.get(DAY_OF_WEEK);474if (dow != THURSDAY) {475errln("Fail: Want THURSDAY Got " + dow);476}477}478479public void Test4096231() {480TimeZone GMT = TimeZone.getTimeZone("GMT");481TimeZone PST = TimeZone.getTimeZone("PST");482int sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997;483484Calendar cal1 = new GregorianCalendar(PST);485cal1.setTime(new Date(880698639000L));486int p;487logln("PST 1 is: " + (p = cal1.get(HOUR_OF_DAY)));488cal1.setTimeZone(GMT);489// Issue 1: Changing the timezone doesn't change the490// represented time.491int h1, h2;492logln("GMT 1 is: " + (h1 = cal1.get(HOUR_OF_DAY)));493cal1.setTime(new Date(880698639000L));494logln("GMT 2 is: " + (h2 = cal1.get(HOUR_OF_DAY)));495// Note: This test had a bug in it. It wanted h1!=h2, when496// what was meant was h1!=p. Fixed this concurrent with fix497// to 4177484.498if (p == h1 || h1 != h2) {499errln("Fail: Hour same in different zones");500}501502Calendar cal2 = new GregorianCalendar(GMT);503Calendar cal3 = new GregorianCalendar(PST);504cal2.set(MILLISECOND, 0);505cal3.set(MILLISECOND, 0);506507cal2.set(cal1.get(YEAR),508cal1.get(MONTH),509cal1.get(DAY_OF_MONTH),510cal1.get(HOUR_OF_DAY),511cal1.get(MINUTE),512cal1.get(SECOND));513514long t1, t2, t3, t4;515logln("RGMT 1 is: " + (t1 = cal2.getTime().getTime()));516cal3.set(year, month, day, hr, min, sec);517logln("RPST 1 is: " + (t2 = cal3.getTime().getTime()));518cal3.setTimeZone(GMT);519logln("RGMT 2 is: " + (t3 = cal3.getTime().getTime()));520cal3.set(cal1.get(YEAR),521cal1.get(MONTH),522cal1.get(DAY_OF_MONTH),523cal1.get(HOUR_OF_DAY),524cal1.get(MINUTE),525cal1.get(SECOND));526// Issue 2: Calendar continues to use the timezone in its527// constructor for set() conversions, regardless528// of calls to setTimeZone()529logln("RGMT 3 is: " + (t4 = cal3.getTime().getTime()));530if (t1 == t2531|| t1 != t4532|| t2 != t3) {533errln("Fail: Calendar zone behavior faulty");534}535}536537public void Test4096539() {538int[] y = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};539540for (int x = 0; x < 12; x++) {541GregorianCalendar gc = new GregorianCalendar(1997, x, y[x]);542int m1, m2;543log((m1 = gc.get(MONTH) + 1) + "/"544+ gc.get(DATE) + "/" + gc.get(YEAR)545+ " + 1mo = ");546547gc.add(MONTH, 1);548logln((m2 = gc.get(MONTH) + 1) + "/"549+ gc.get(DATE) + "/" + gc.get(YEAR)550);551int m = (m1 % 12) + 1;552if (m2 != m) {553errln("Fail: Want " + m + " Got " + m2);554}555}556557}558559public void Test4100311() {560Locale locale = Locale.getDefault();561if (!TestUtils.usesGregorianCalendar(locale)) {562logln("Skipping this test because locale is " + locale);563return;564}565566GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();567cal.set(YEAR, 1997);568cal.set(DAY_OF_YEAR, 1);569Date d = cal.getTime(); // Should be Jan 1570logln(d.toString());571if (cal.get(DAY_OF_YEAR) != 1) {572errln("Fail: DAY_OF_YEAR not set");573}574}575576public void Test4103271() {577Locale locale = Locale.getDefault();578if (!TestUtils.usesGregorianCalendar(locale)) {579logln("Skipping this test because locale is " + locale);580return;581}582583SimpleDateFormat sdf = new SimpleDateFormat();584int numYears = 40, startYear = 1997, numDays = 15;585String output, testDesc;586GregorianCalendar testCal = (GregorianCalendar) Calendar.getInstance();587testCal.clear();588sdf.setCalendar(testCal);589sdf.applyPattern("d MMM yyyy");590boolean fail = false;591for (int firstDay = 1; firstDay <= 2; firstDay++) {592for (int minDays = 1; minDays <= 7; minDays++) {593testCal.setMinimalDaysInFirstWeek(minDays);594testCal.setFirstDayOfWeek(firstDay);595testDesc = ("Test" + String.valueOf(firstDay) + String.valueOf(minDays));596logln(testDesc + " => 1st day of week="597+ String.valueOf(firstDay)598+ ", minimum days in first week="599+ String.valueOf(minDays));600for (int j = startYear; j <= startYear + numYears; j++) {601testCal.set(j, 11, 25);602for (int i = 0; i < numDays; i++) {603testCal.add(DATE, 1);604String calWOY;605int actWOY = testCal.get(WEEK_OF_YEAR);606if (actWOY < 1 || actWOY > 53) {607Date d = testCal.getTime();608calWOY = String.valueOf(actWOY);609output = testDesc + " - " + sdf.format(d) + "\t";610output = output + "\t" + calWOY;611logln(output);612fail = true;613}614}615}616}617}618619int[] DATA = {6203, 52, 52, 52, 52, 52, 52, 52,6211, 1, 1, 1, 1, 1, 1,6222, 2, 2, 2, 2, 2, 2,6234, 52, 52, 52, 52, 52, 52, 52,62453, 53, 53, 53, 53, 53, 53,6251, 1, 1, 1, 1, 1, 1};626testCal.setFirstDayOfWeek(SUNDAY);627for (int j = 0; j < DATA.length; j += 22) {628logln("Minimal days in first week = " + DATA[j]629+ " Week starts on Sunday");630testCal.setMinimalDaysInFirstWeek(DATA[j]);631testCal.set(1997, DECEMBER, 21);632for (int i = 0; i < 21; ++i) {633int woy = testCal.get(WEEK_OF_YEAR);634log("\t" + testCal.getTime() + " " + woy);635if (woy != DATA[j + 1 + i]) {636log(" ERROR");637fail = true;638} else {639logln(" OK");640}641642// Now compute the time from the fields, and make sure we643// get the same answer back. This is a round-trip test.644Date save = testCal.getTime();645testCal.clear();646testCal.set(YEAR, DATA[j + 1 + i] < 25 ? 1998 : 1997);647testCal.set(WEEK_OF_YEAR, DATA[j + 1 + i]);648testCal.set(DAY_OF_WEEK, (i % 7) + SUNDAY);649if (!testCal.getTime().equals(save)) {650logln(" Parse failed: " + testCal.getTime());651fail = true;652} else {653logln(" Passed");654}655656testCal.setTime(save);657testCal.add(DAY_OF_MONTH, 1);658}659}660661// Test field disambiguation with a few special hard-coded cases.662// This shouldn't fail if the above cases aren't failing.663@SuppressWarnings("deprecation")664Object[] DISAM = {6651998, 1, SUNDAY,666new Date(97, DECEMBER, 28),6671998, 2, SATURDAY,668new Date(98, JANUARY, 10),6691998, 53, THURSDAY,670new Date(98, DECEMBER, 31),6711998, 53, FRIDAY,672new Date(99, JANUARY, 1)};673testCal.setMinimalDaysInFirstWeek(3);674testCal.setFirstDayOfWeek(SUNDAY);675for (int i = 0; i < DISAM.length; i += 4) {676int y = (Integer) DISAM[i];677int woy = (Integer) DISAM[i + 1];678int dow = (Integer) DISAM[i + 2];679Date exp = (Date) DISAM[i + 3];680testCal.clear();681testCal.set(YEAR, y);682testCal.set(WEEK_OF_YEAR, woy);683testCal.set(DAY_OF_WEEK, dow);684log(y + "-W" + woy + "-DOW" + dow);685if (!testCal.getTime().equals(exp)) {686logln(" FAILED expect: " + exp + "\n got: " + testCal.getTime());687fail = true;688} else {689logln(" OK");690}691}692693// Now try adding and rolling694Object ADD = new Object();695Object ROLL = new Object();696@SuppressWarnings("deprecation")697Object[] ADDROLL = {698ADD, 1, new Date(98, DECEMBER, 25), new Date(99, JANUARY, 1),699ADD, 1, new Date(97, DECEMBER, 28), new Date(98, JANUARY, 4),700ROLL, 1, new Date(98, DECEMBER, 27), new Date(98, JANUARY, 4),701ROLL, 1, new Date(99, DECEMBER, 24), new Date(99, DECEMBER, 31),702ROLL, 1, new Date(99, DECEMBER, 25), new Date(99, JANUARY, 9)};703testCal.setMinimalDaysInFirstWeek(3);704testCal.setFirstDayOfWeek(SUNDAY);705for (int i = 0; i < ADDROLL.length; i += 4) {706int amount = (Integer) ADDROLL[i + 1];707Date before = (Date) ADDROLL[i + 2];708Date after = (Date) ADDROLL[i + 3];709710testCal.setTime(before);711if (ADDROLL[i] == ADD) {712testCal.add(WEEK_OF_YEAR, amount);713} else {714testCal.roll(WEEK_OF_YEAR, amount);715}716log((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,")717+ amount + ")\t " + before718+ "\n\t\t => " + testCal.getTime());719if (!after.equals(testCal.getTime())) {720logln("\tFAIL\n\t\texp: " + after);721fail = true;722} else {723logln(" OK");724}725726testCal.setTime(after);727if (ADDROLL[i] == ADD) {728testCal.add(WEEK_OF_YEAR, -amount);729} else {730testCal.roll(WEEK_OF_YEAR, -amount);731}732log((ADDROLL[i] == ADD ? "add(WOY," : "roll(WOY,")733+ (-amount) + ") " + after734+ "\n\t\t => " + testCal.getTime());735if (!before.equals(testCal.getTime())) {736logln("\tFAIL\n\t\texp: " + before);737fail = true;738} else {739logln("\tOK");740}741}742743if (fail) {744errln("Fail: Week of year misbehaving");745}746}747748public void Test4106136() {749Locale saveLocale = Locale.getDefault();750try {751Locale[] locales = {Locale.CHINESE, Locale.CHINA};752for (int i = 0; i < locales.length; ++i) {753Locale.setDefault(locales[i]);754int[] n = {755getAvailableLocales().length,756DateFormat.getAvailableLocales().length,757NumberFormat.getAvailableLocales().length};758for (int j = 0; j < n.length; ++j) {759if (n[j] == 0) {760errln("Fail: No locales for " + locales[i]);761}762}763}764} finally {765Locale.setDefault(saveLocale);766}767}768769@SuppressWarnings("deprecation")770public void Test4108764() {771Date d00 = new Date(97, MARCH, 15, 12, 00, 00);772Date d01 = new Date(97, MARCH, 15, 12, 00, 56);773Date d10 = new Date(97, MARCH, 15, 12, 34, 00);774Date d11 = new Date(97, MARCH, 15, 12, 34, 56);775Date epoch = new Date(70, JANUARY, 1);776777Calendar cal = Calendar.getInstance();778cal.setTime(d11);779780cal.clear(MINUTE);781logln(cal.getTime().toString());782if (!cal.getTime().equals(d01)) {783errln("Fail: clear(MINUTE) broken");784}785786cal.set(SECOND, 0);787logln(cal.getTime().toString());788if (!cal.getTime().equals(d00)) {789errln("Fail: set(SECOND, 0) broken");790}791792cal.setTime(d11);793cal.set(SECOND, 0);794logln(cal.getTime().toString());795if (!cal.getTime().equals(d10)) {796errln("Fail: set(SECOND, 0) broken #2");797}798799cal.clear(MINUTE);800logln(cal.getTime().toString());801if (!cal.getTime().equals(d00)) {802errln("Fail: clear(MINUTE) broken #2");803}804805cal.clear();806logln(cal.getTime().toString());807if (!cal.getTime().equals(epoch)) {808errln("Fail: clear() broken Want " + epoch);809}810}811812@SuppressWarnings("deprecation")813public void Test4114578() {814Locale locale = Locale.getDefault();815if (!TestUtils.usesGregorianCalendar(locale)) {816logln("Skipping this test because locale is " + locale);817return;818}819820int ONE_HOUR = 60 * 60 * 1000;821TimeZone saveZone = TimeZone.getDefault();822boolean fail = false;823try {824TimeZone.setDefault(TimeZone.getTimeZone("PST"));825Calendar cal = Calendar.getInstance();826long onset = new Date(98, APRIL, 5, 1, 0).getTime() + ONE_HOUR;827long cease = new Date(98, OCTOBER, 25, 0, 0).getTime() + 2 * ONE_HOUR;828829final int ADD = 1;830final int ROLL = 2;831832long[] DATA = {833// Start Action Amt Expected_change834onset - ONE_HOUR, ADD, 1, ONE_HOUR,835onset, ADD, -1, -ONE_HOUR,836onset - ONE_HOUR, ROLL, 1, ONE_HOUR,837onset, ROLL, -1, -ONE_HOUR,838cease - ONE_HOUR, ADD, 1, ONE_HOUR,839cease, ADD, -1, -ONE_HOUR,840// roll() was changed to support wall-clock-based roll (JDK-8152077). The841// time value may jump 2 hours by skipping non-existent wall-clock time.842// Note that JDK-4114578 was a problem of add(), not roll().843cease - ONE_HOUR, ROLL, 1, ONE_HOUR * 2,844cease, ROLL, -1, -ONE_HOUR * 2};845846for (int i = 0; i < DATA.length; i += 4) {847Date date = new Date(DATA[i]);848int amt = (int) DATA[i + 2];849long expectedChange = DATA[i + 3];850851log(date.toString());852cal.setTime(date);853854switch ((int) DATA[i + 1]) {855case ADD:856log(" add (HOUR," + (amt < 0 ? "" : "+") + amt + ")= ");857cal.add(HOUR, amt);858break;859case ROLL:860log(" roll(HOUR," + (amt < 0 ? "" : "+") + amt + ")= ");861cal.roll(HOUR, amt);862break;863}864865log(cal.getTime().toString());866867long change = cal.getTime().getTime() - date.getTime();868if (change != expectedChange) {869fail = true;870logln(" FAIL");871} else {872logln(" OK");873}874}875} finally {876TimeZone.setDefault(saveZone);877}878879if (fail) {880errln("Fail: roll/add misbehaves around DST onset/cease");881}882}883884/**885* Make sure maximum for HOUR field is 11, not 12.886*/887public void Test4118384() {888Calendar cal = Calendar.getInstance();889if (cal.getMaximum(HOUR) != 11890|| cal.getLeastMaximum(HOUR) != 11891|| cal.getActualMaximum(HOUR) != 11) {892errln("Fail: maximum of HOUR field should be 11");893}894}895896/**897* Check isLeapYear for BC years.898*/899public void Test4125881() {900Locale locale = Locale.getDefault();901if (!TestUtils.usesGregorianCalendar(locale)) {902logln("Skipping this test because locale is " + locale);903return;904}905906GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();907DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");908cal.clear();909for (int y = -20; y <= 10; ++y) {910cal.set(ERA, y < 1 ? GregorianCalendar.BC : GregorianCalendar.AD);911cal.set(YEAR, y < 1 ? 1 - y : y);912logln(y + " = " + fmt.format(cal.getTime()) + " "913+ cal.isLeapYear(y));914if (cal.isLeapYear(y) != ((y + 40) % 4 == 0)) {915errln("Leap years broken");916}917}918}919920/**921* Prove that GregorianCalendar is proleptic (it used to cut off922* at 45 BC, and not have leap years before then).923*/924public void Test4125892() {925Locale locale = Locale.getDefault();926if (!TestUtils.usesGregorianCalendar(locale)) {927logln("Skipping this test because locale is " + locale);928return;929}930931GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();932DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");933cal.clear();934cal.set(ERA, GregorianCalendar.BC);935cal.set(YEAR, 81); // 81 BC is a leap year (proleptically)936cal.set(MONTH, FEBRUARY);937cal.set(DATE, 28);938cal.add(DATE, 1);939if (cal.get(DATE) != 29940|| !cal.isLeapYear(-80)) { // -80 == 81 BC941errln("Calendar not proleptic");942}943}944945/**946* Calendar and GregorianCalendar hashCode() methods need improvement.947* Calendar needs a good implementation that subclasses can override,948* and GregorianCalendar should use that implementation.949*/950public void Test4136399() {951/* Note: This test is actually more strict than it has to be.952* Technically, there is no requirement that unequal objects have953* unequal hashes. We only require equal objects to have equal hashes.954* It is desirable for unequal objects to have distributed hashes, but955* there is no hard requirement here.956*957* In this test we make assumptions about certain attributes of calendar958* objects getting represented in the hash, which need not always be the959* case (although it does work currently with the given test). */960Calendar a = Calendar.getInstance();961Calendar b = (Calendar) a.clone();962if (a.hashCode() != b.hashCode()) {963errln("Calendar hash code unequal for cloned objects");964}965966b.setMinimalDaysInFirstWeek(7 - a.getMinimalDaysInFirstWeek());967if (a.hashCode() == b.hashCode()) {968errln("Calendar hash code ignores minimal days in first week");969}970b.setMinimalDaysInFirstWeek(a.getMinimalDaysInFirstWeek());971972b.setFirstDayOfWeek((a.getFirstDayOfWeek() % 7) + 1); // Next day973if (a.hashCode() == b.hashCode()) {974errln("Calendar hash code ignores first day of week");975}976b.setFirstDayOfWeek(a.getFirstDayOfWeek());977978b.setLenient(!a.isLenient());979if (a.hashCode() == b.hashCode()) {980errln("Calendar hash code ignores lenient setting");981}982b.setLenient(a.isLenient());983984// Assume getTimeZone() returns a reference, not a clone985// of a reference -- this is true as of this writing986b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset() + 60 * 60 * 1000);987if (a.hashCode() == b.hashCode()) {988errln("Calendar hash code ignores zone");989}990b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset());991992GregorianCalendar c = new GregorianCalendar();993GregorianCalendar d = (GregorianCalendar) c.clone();994if (c.hashCode() != d.hashCode()) {995errln("GregorianCalendar hash code unequal for clones objects");996}997Date cutover = c.getGregorianChange();998d.setGregorianChange(new Date(cutover.getTime() + 24 * 60 * 60 * 1000));999if (c.hashCode() == d.hashCode()) {1000errln("GregorianCalendar hash code ignores cutover");1001}1002}10031004/**1005* GregorianCalendar.equals() ignores cutover date1006*/1007public void Test4141665() {1008GregorianCalendar cal = new GregorianCalendar();1009GregorianCalendar cal2 = (GregorianCalendar) cal.clone();1010Date cut = cal.getGregorianChange();1011Date cut2 = new Date(cut.getTime() + 100 * 24 * 60 * 60 * 1000L); // 100 days later1012if (!cal.equals(cal2)) {1013errln("Cloned GregorianCalendars not equal");1014}1015cal2.setGregorianChange(cut2);1016if (cal.equals(cal2)) {1017errln("GregorianCalendar.equals() ignores cutover");1018}1019}10201021/**1022* Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar.roll()1023* when IllegalArgumentException should be.1024*/1025public void Test4142933() {1026GregorianCalendar calendar = new GregorianCalendar();1027try {1028calendar.roll(-1, true);1029errln("Test failed, no exception trown");1030} catch (IllegalArgumentException e) {1031// OK: Do nothing1032// logln("Test passed");1033} catch (Exception e) {1034errln("Test failed. Unexpected exception is thrown: " + e);1035e.printStackTrace();1036}1037}10381039/**1040* GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is1041* confusing; unless the time zone has a raw offset of zero, one or the1042* other of these will wrap. We've modified the test given in the bug1043* report to therefore only check the behavior of a calendar with a zero raw1044* offset zone.1045*/1046public void Test4145158() {1047GregorianCalendar calendar = new GregorianCalendar();10481049calendar.setTimeZone(TimeZone.getTimeZone("GMT"));10501051calendar.setTime(new Date(Long.MIN_VALUE));1052int year1 = calendar.get(YEAR);1053int era1 = calendar.get(ERA);10541055calendar.setTime(new Date(Long.MAX_VALUE));1056int year2 = calendar.get(YEAR);1057int era2 = calendar.get(ERA);10581059if (year1 == year2 && era1 == era2) {1060errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");1061}1062}10631064/**1065* Maximum value for YEAR field wrong.1066*/1067public void Test4145983() {1068GregorianCalendar calendar = new GregorianCalendar();1069calendar.setTimeZone(TimeZone.getTimeZone("GMT"));1070Date[] DATES = {new Date(Long.MAX_VALUE), new Date(Long.MIN_VALUE)};1071for (int i = 0; i < DATES.length; ++i) {1072calendar.setTime(DATES[i]);1073int year = calendar.get(YEAR);1074int maxYear = calendar.getMaximum(YEAR);1075if (year > maxYear) {1076errln("Failed for " + DATES[i].getTime() + " ms: year="1077+ year + ", maxYear=" + maxYear);1078}1079}1080}10811082/**1083* This is a bug in the validation code of GregorianCalendar. As reported,1084* the bug seems worse than it really is, due to a bug in the way the bug1085* report test was written. In reality the bug is restricted to the DAY_OF_YEAR1086* field. - liu 6/29/981087*/1088public void Test4147269() {1089final String[] fieldName = {1090"ERA",1091"YEAR",1092"MONTH",1093"WEEK_OF_YEAR",1094"WEEK_OF_MONTH",1095"DAY_OF_MONTH",1096"DAY_OF_YEAR",1097"DAY_OF_WEEK",1098"DAY_OF_WEEK_IN_MONTH",1099"AM_PM",1100"HOUR",1101"HOUR_OF_DAY",1102"MINUTE",1103"SECOND",1104"MILLISECOND",1105"ZONE_OFFSET",1106"DST_OFFSET"};1107GregorianCalendar calendar = new GregorianCalendar();1108calendar.setLenient(false);1109@SuppressWarnings("deprecation")1110Date date = new Date(1996 - 1900, JANUARY, 3); // Arbitrary date1111for (int field = 0; field < FIELD_COUNT; field++) {1112calendar.setTime(date);1113// Note: In the bug report, getActualMaximum() was called instead1114// of getMaximum() -- this was an error. The validation code doesn't1115// use getActualMaximum(), since that's too costly.1116int max = calendar.getMaximum(field);1117int value = max + 1;1118calendar.set(field, value);1119try {1120calendar.getTime(); // Force time computation1121// We expect an exception to be thrown. If we fall through1122// to the next line, then we have a bug.1123errln("Test failed with field " + fieldName[field]1124+ ", date before: " + date1125+ ", date after: " + calendar.getTime()1126+ ", value: " + value + " (max = " + max + ")");1127} catch (IllegalArgumentException e) {1128}1129}1130}11311132/**1133* Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)1134* doesn't behave as a pure Julian calendar.1135* CANNOT REPRODUCE THIS BUG1136*/1137public void Test4149677() {1138TimeZone[] zones = {TimeZone.getTimeZone("GMT"),1139TimeZone.getTimeZone("PST"),1140TimeZone.getTimeZone("EAT")};1141for (int i = 0; i < zones.length; ++i) {1142GregorianCalendar calendar = new GregorianCalendar(zones[i]);11431144// Make sure extreme values don't wrap around1145calendar.setTime(new Date(Long.MIN_VALUE));1146if (calendar.get(ERA) != GregorianCalendar.BC) {1147errln("Fail: Date(Long.MIN_VALUE) has an AD year in " + zones[i]);1148}1149calendar.setTime(new Date(Long.MAX_VALUE));1150if (calendar.get(ERA) != GregorianCalendar.AD) {1151errln("Fail: Date(Long.MAX_VALUE) has a BC year in " + zones[i]);1152}11531154calendar.setGregorianChange(new Date(Long.MAX_VALUE));1155// to obtain a pure Julian calendar11561157boolean is100Leap = calendar.isLeapYear(100);1158if (!is100Leap) {1159errln("test failed with zone " + zones[i].getID());1160errln(" cutover date is Date(Long.MAX_VALUE)");1161errln(" isLeapYear(100) returns: " + is100Leap);1162}1163}1164}11651166/**1167* Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar1168* and Date classes will misbehave.1169*/1170public void Test4162587() {1171TimeZone savedTz = TimeZone.getDefault();1172TimeZone tz = TimeZone.getTimeZone("PST");1173TimeZone.setDefault(tz);1174GregorianCalendar cal = new GregorianCalendar(tz);1175Date d;11761177try {1178for (int i = 0; i < 5; ++i) {1179if (i > 0) {1180logln("---");1181}11821183cal.clear();1184cal.set(1998, APRIL, 5, i, 0);1185d = cal.getTime();1186String s0 = d.toString();1187logln("0 " + i + ": " + s0);11881189cal.clear();1190cal.set(1998, APRIL, 4, i + 24, 0);1191d = cal.getTime();1192String sPlus = d.toString();1193logln("+ " + i + ": " + sPlus);11941195cal.clear();1196cal.set(1998, APRIL, 6, i - 24, 0);1197d = cal.getTime();1198String sMinus = d.toString();1199logln("- " + i + ": " + sMinus);12001201if (!s0.equals(sPlus) || !s0.equals(sMinus)) {1202errln("Fail: All three lines must match");1203}1204}1205} finally {1206TimeZone.setDefault(savedTz);1207}1208}12091210/**1211* Adding 12 months behaves differently from adding 1 year1212*/1213public void Test4165343() {1214GregorianCalendar calendar = new GregorianCalendar(1996, FEBRUARY, 29);1215Date start = calendar.getTime();1216logln("init date: " + start);1217calendar.add(MONTH, 12);1218Date date1 = calendar.getTime();1219logln("after adding 12 months: " + date1);1220calendar.setTime(start);1221calendar.add(YEAR, 1);1222Date date2 = calendar.getTime();1223logln("after adding one year : " + date2);1224if (date1.equals(date2)) {1225logln("Test passed");1226} else {1227errln("Test failed");1228}1229}12301231/**1232* GregorianCalendar.getActualMaximum() does not account for first day of week.1233*/1234public void Test4166109() {1235/* Test month:1236*1237* March 19981238* Su Mo Tu We Th Fr Sa1239* 1 2 3 4 5 6 71240* 8 9 10 11 12 13 141241* 15 16 17 18 19 20 211242* 22 23 24 25 26 27 281243* 29 30 311244*/1245boolean passed = true;1246int field = WEEK_OF_MONTH;12471248GregorianCalendar calendar = new GregorianCalendar(Locale.US);1249calendar.set(1998, MARCH, 1);1250calendar.setMinimalDaysInFirstWeek(1);1251logln("Date: " + calendar.getTime());12521253int firstInMonth = calendar.get(DAY_OF_MONTH);12541255for (int firstInWeek = SUNDAY; firstInWeek <= SATURDAY; firstInWeek++) {1256calendar.setFirstDayOfWeek(firstInWeek);1257int returned = calendar.getActualMaximum(field);1258int expected = (31 + ((firstInMonth - firstInWeek + 7) % 7) + 6) / 7;12591260logln("First day of week = " + firstInWeek1261+ " getActualMaximum(WEEK_OF_MONTH) = " + returned1262+ " expected = " + expected1263+ ((returned == expected) ? " ok" : " FAIL"));12641265if (returned != expected) {1266passed = false;1267}1268}1269if (!passed) {1270errln("Test failed");1271}1272}12731274/**1275* Calendar.getActualMaximum(YEAR) works wrong.1276*1277* Note: Before 1.5, this test case assumed that1278* setGregorianChange didn't change object's date. But it was1279* changed. See 4928615.1280*/1281public void Test4167060() {1282int field = YEAR;1283DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy G",1284Locale.US);12851286int[][] dates = {1287// year, month, day of month1288{100, NOVEMBER, 1},1289{-99 /*100BC*/, JANUARY, 1},1290{1996, FEBRUARY, 29}};12911292String[] id = {"Hybrid", "Gregorian", "Julian"};12931294for (int k = 0; k < 3; ++k) {1295logln("--- " + id[k] + " ---");12961297for (int j = 0; j < dates.length; ++j) {1298GregorianCalendar calendar = new GregorianCalendar();1299if (k == 1) {1300calendar.setGregorianChange(new Date(Long.MIN_VALUE));1301} else if (k == 2) {1302calendar.setGregorianChange(new Date(Long.MAX_VALUE));1303}1304calendar.set(dates[j][0], dates[j][1], dates[j][2]);1305format.setCalendar((Calendar) calendar.clone());13061307Date dateBefore = calendar.getTime();13081309int maxYear = calendar.getActualMaximum(field);1310logln("maxYear: " + maxYear + " for " + format.format(calendar.getTime()));1311logln("date before: " + format.format(dateBefore));13121313int[] years = {2000, maxYear - 1, maxYear, maxYear + 1};13141315for (int i = 0; i < years.length; i++) {1316boolean valid = years[i] <= maxYear;1317calendar.set(field, years[i]);1318Date dateAfter = calendar.getTime();1319int newYear = calendar.get(field);1320calendar.setTime(dateBefore); // restore calendar for next use13211322logln(" Year " + years[i] + (valid ? " ok " : " bad")1323+ " => " + format.format(dateAfter));1324if (valid && newYear != years[i]) {1325errln(" FAIL: " + newYear + " should be valid; date, month and time shouldn't change");1326} else if (!valid && newYear == years[i]) {1327errln(" FAIL: " + newYear + " should be invalid");1328}1329}1330}1331}1332}13331334/**1335* Calendar.roll broken1336* This bug relies on the TimeZone bug 4173604 to also be fixed.1337*/1338public void Test4173516() {1339Locale locale = Locale.getDefault();1340if (!TestUtils.usesGregorianCalendar(locale)) {1341logln("Skipping this test because locale is " + locale);1342return;1343}13441345int[][] fieldsList = {1346{1997, FEBRUARY, 1, 10, 45, 15, 900},1347{1999, DECEMBER, 22, 23, 59, 59, 999},1348// test case for 4960642 with default cutover1349{1582, OCTOBER, 4, 23, 59, 59, 999}};1350String[] fieldNames = {1351"ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",1352"DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH",1353"AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND",1354"ZONE_OFFSET", "DST_OFFSET"};13551356Locale savedLocale = Locale.getDefault();1357Locale.setDefault(Locale.US);1358int limit = 40;13591360try {1361GregorianCalendar cal = new GregorianCalendar();13621363cal.setTime(new Date(0));1364cal.roll(HOUR, 0x7F000000);1365cal.roll(HOUR, -0x7F000000);1366if (cal.getTime().getTime() != 0) {1367errln("Hour rolling broken. expected 0, got " + cal.getTime().getTime());1368}13691370for (int op = 0; op < 2; ++op) {1371logln("Testing GregorianCalendar " + (op == 0 ? "add" : "roll"));13721373for (int field = 0; field < FIELD_COUNT; ++field) {1374if (field != ZONE_OFFSET1375&& field != DST_OFFSET) {1376for (int j = 0; j < fieldsList.length; ++j) {1377int[] fields = fieldsList[j];1378cal.clear();1379cal.set(fields[0], fields[1], fields[2],1380fields[3], fields[4], fields[5]);1381cal.set(MILLISECOND, fields[6]);1382for (int i = 0; i < 2 * limit; i++) {1383if (op == 0) {1384cal.add(field, i < limit ? 1 : -1);1385} else {1386cal.roll(field, i < limit ? 1 : -1);1387}1388}13891390if (cal.get(YEAR) != fields[0]1391|| cal.get(MONTH) != fields[1]1392|| cal.get(DATE) != fields[2]1393|| cal.get(HOUR_OF_DAY) != fields[3]1394|| cal.get(MINUTE) != fields[4]1395|| cal.get(SECOND) != fields[5]1396|| cal.get(MILLISECOND) != fields[6]) {1397errln("Field " + field1398+ " (" + fieldNames[field]1399+ ") FAIL, expected "1400+ fields[0]1401+ "/" + (fields[1] + 1)1402+ "/" + fields[2]1403+ " " + fields[3]1404+ ":" + fields[4]1405+ ":" + fields[5]1406+ "." + fields[6]1407+ ", got " + cal.get(YEAR)1408+ "/" + (cal.get(MONTH) + 1)1409+ "/" + cal.get(DATE)1410+ " " + cal.get(HOUR_OF_DAY)1411+ ":" + cal.get(MINUTE)1412+ ":" + cal.get(SECOND)1413+ "." + cal.get(MILLISECOND));14141415cal.clear();1416cal.set(fields[0], fields[1], fields[2],1417fields[3], fields[4], fields[5]);1418cal.set(MILLISECOND, fields[6]);1419errln(cal.get(YEAR)1420+ "/" + (cal.get(MONTH) + 1)1421+ "/" + cal.get(DATE)1422+ " " + cal.get(HOUR_OF_DAY)1423+ ":" + cal.get(MINUTE)1424+ ":" + cal.get(SECOND)1425+ "." + cal.get(MILLISECOND));14261427long prev = cal.getTime().getTime();1428for (int i = 0; i < 2 * limit; i++) {1429if (op == 0) {1430cal.add(field, i < limit ? 1 : -1);1431} else {1432cal.roll(field, i < limit ? 1 : -1);1433}1434long t = cal.getTime().getTime();1435long delta = t - prev;1436prev = t;1437errln((op == 0 ? "add(" : "roll(")1438+ fieldNames[field] + ", "1439+ (i < limit ? "+" : "-") + "1) => "1440+ cal.get(YEAR)1441+ "/" + (cal.get(MONTH) + 1)1442+ "/" + cal.get(DATE)1443+ " " + cal.get(HOUR_OF_DAY)1444+ ":" + cal.get(MINUTE)1445+ ":" + cal.get(SECOND)1446+ "." + cal.get(MILLISECOND)1447+ " d=" + delta);1448}1449}1450}1451}1452}1453}1454} finally {1455Locale.setDefault(savedLocale);1456}1457}14581459public void Test4174361() {1460GregorianCalendar calendar = new GregorianCalendar(1996, 1, 29);14611462calendar.add(MONTH, 10);1463Date date1 = calendar.getTime();1464int d1 = calendar.get(DAY_OF_MONTH);14651466calendar = new GregorianCalendar(1996, 1, 29);1467calendar.add(MONTH, 11);1468Date date2 = calendar.getTime();1469int d2 = calendar.get(DAY_OF_MONTH);14701471if (d1 != d2) {1472errln("adding months to Feb 29 broken");1473}1474}14751476/**1477* Calendar does not update field values when setTimeZone is called.1478*/1479public void Test4177484() {1480TimeZone PST = TimeZone.getTimeZone("PST");1481TimeZone EST = TimeZone.getTimeZone("EST");14821483Calendar cal = Calendar.getInstance(PST, Locale.US);1484cal.clear();1485cal.set(1999, 3, 21, 15, 5, 0); // Arbitrary1486int h1 = cal.get(HOUR_OF_DAY);1487cal.setTimeZone(EST);1488int h2 = cal.get(HOUR_OF_DAY);1489if (h1 == h2) {1490errln("FAIL: Fields not updated after setTimeZone");1491}14921493// getTime() must NOT change when time zone is changed.1494// getTime() returns zone-independent time in ms.1495cal.clear();1496cal.setTimeZone(PST);1497cal.set(HOUR_OF_DAY, 10);1498Date pst10 = cal.getTime();1499cal.setTimeZone(EST);1500Date est10 = cal.getTime();1501if (!pst10.equals(est10)) {1502errln("FAIL: setTimeZone changed time");1503}1504}15051506/**1507* Week of year is wrong at the start and end of the year.1508*/1509public void Test4197699() {1510GregorianCalendar cal = new GregorianCalendar();1511cal.setFirstDayOfWeek(MONDAY);1512cal.setMinimalDaysInFirstWeek(4);1513DateFormat fmt = new SimpleDateFormat("E dd MMM yyyy 'DOY='D 'WOY='w");1514fmt.setCalendar(cal);15151516int[] DATA = {15172000, JANUARY, 1, 52,15182001, DECEMBER, 31, 1};15191520for (int i = 0; i < DATA.length;) {1521cal.set(DATA[i++], DATA[i++], DATA[i++]);1522int expWOY = DATA[i++];1523int actWOY = cal.get(WEEK_OF_YEAR);1524if (expWOY == actWOY) {1525logln("Ok: " + fmt.format(cal.getTime()));1526} else {1527errln("FAIL: " + fmt.format(cal.getTime())1528+ ", expected WOY=" + expWOY);1529cal.add(DATE, -8);1530for (int j = 0; j < 14; ++j) {1531cal.add(DATE, 1);1532logln(fmt.format(cal.getTime()));1533}1534}1535}1536}15371538/**1539* Calendar DAY_OF_WEEK_IN_MONTH fields->time broken. The problem1540* is in the field disambiguation code in GregorianCalendar. This1541* code is supposed to choose the most recent set of fields1542* among the following:1543*1544* MONTH + DAY_OF_MONTH1545* MONTH + WEEK_OF_MONTH + DAY_OF_WEEK1546* MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK1547* DAY_OF_YEAR1548* WEEK_OF_YEAR + DAY_OF_WEEK1549*/1550@SuppressWarnings("deprecation")1551public void Test4209071() {1552Calendar cal = Calendar.getInstance(Locale.US);15531554// General field setting test1555int Y = 1995 - 1900;15561557Object[] FIELD_DATA = {1558// Add new test cases as needed.15591560// 01561new int[]{}, new Date(Y, JANUARY, 1),1562// 11563new int[]{MONTH, MARCH},1564new Date(Y, MARCH, 1),1565// 21566new int[]{DAY_OF_WEEK, WEDNESDAY},1567new Date(Y, JANUARY, 4),1568// 31569new int[]{DAY_OF_WEEK, THURSDAY,1570DAY_OF_MONTH, 18,},1571new Date(Y, JANUARY, 18),1572// 41573new int[]{DAY_OF_MONTH, 18,1574DAY_OF_WEEK, THURSDAY,},1575new Date(Y, JANUARY, 18),1576// 5 (WOM -1 is in previous month)1577new int[]{DAY_OF_MONTH, 18,1578WEEK_OF_MONTH, -1,1579DAY_OF_WEEK, THURSDAY,},1580new Date(Y - 1, DECEMBER, 22),1581// 61582new int[]{DAY_OF_MONTH, 18,1583WEEK_OF_MONTH, 4,1584DAY_OF_WEEK, THURSDAY,},1585new Date(Y, JANUARY, 26),1586// 7 (DIM -1 is in same month)1587new int[]{DAY_OF_MONTH, 18,1588DAY_OF_WEEK_IN_MONTH, -1,1589DAY_OF_WEEK, THURSDAY,},1590new Date(Y, JANUARY, 26),1591// 81592new int[]{WEEK_OF_YEAR, 9,1593DAY_OF_WEEK, WEDNESDAY,},1594new Date(Y, MARCH, 1),1595// 91596new int[]{MONTH, OCTOBER,1597DAY_OF_WEEK_IN_MONTH, 1,1598DAY_OF_WEEK, FRIDAY,},1599new Date(Y, OCTOBER, 6),1600// 101601new int[]{MONTH, OCTOBER,1602WEEK_OF_MONTH, 2,1603DAY_OF_WEEK, FRIDAY,},1604new Date(Y, OCTOBER, 13),1605// 111606new int[]{MONTH, OCTOBER,1607DAY_OF_MONTH, 15,1608DAY_OF_YEAR, 222,},1609new Date(Y, AUGUST, 10),1610// 121611new int[]{DAY_OF_WEEK, THURSDAY,1612MONTH, DECEMBER,},1613new Date(Y, DECEMBER, 7)};16141615for (int i = 0; i < FIELD_DATA.length; i += 2) {1616int[] fields = (int[]) FIELD_DATA[i];1617Date exp = (Date) FIELD_DATA[i + 1];16181619cal.clear();1620cal.set(YEAR, Y + 1900);1621for (int j = 0; j < fields.length; j += 2) {1622cal.set(fields[j], fields[j + 1]);1623}16241625Date act = cal.getTime();1626if (!act.equals(exp)) {1627errln("FAIL: Test " + (i / 2) + " got " + act1628+ ", want " + exp1629+ " (see test/java/util/Calendar/CalendarRegression.java");1630}1631}16321633// Test specific failure reported in bug1634@SuppressWarnings("deprecation")1635Object[] DATA = {16361, new Date(1997 - 1900, JANUARY, 5),16374, new Date(1997 - 1900, JANUARY, 26),16388, new Date(1997 - 1900, FEBRUARY, 23),1639-1, new Date(1997 - 1900, JANUARY, 26),1640-4, new Date(1997 - 1900, JANUARY, 5),1641-8, new Date(1996 - 1900, DECEMBER, 8)};1642for (int i = 0; i < DATA.length; i += 2) {1643cal.clear();1644cal.set(DAY_OF_WEEK_IN_MONTH,1645((Number) DATA[i]).intValue());1646cal.set(DAY_OF_WEEK, SUNDAY);1647cal.set(MONTH, JANUARY);1648cal.set(YEAR, 1997);1649Date actual = cal.getTime();1650if (!actual.equals(DATA[i + 1])) {1651errln("FAIL: Sunday " + DATA[i]1652+ " of Jan 1997 -> " + actual1653+ ", want " + DATA[i + 1]);1654}1655}1656}16571658public void Test4288792() throws Exception {1659TimeZone savedTZ = TimeZone.getDefault();1660TimeZone.setDefault(TimeZone.getTimeZone("GMT"));1661GregorianCalendar cal = new GregorianCalendar();1662try {1663for (int i = 1900; i < 2100; i++) {1664for (int j1 = 1; j1 <= 7; j1++) {1665// Loop for MinimalDaysInFirstWeek: 1..71666for (int j = SUNDAY; j <= SATURDAY; j++) {1667// Loop for FirstDayOfWeek: SUNDAY..SATURDAY1668cal.clear();1669cal.setMinimalDaysInFirstWeek(j1);1670cal.setFirstDayOfWeek(j);1671cal.set(YEAR, i);1672int maxWeek = cal.getActualMaximum(WEEK_OF_YEAR);1673cal.set(WEEK_OF_YEAR, maxWeek);1674cal.set(DAY_OF_WEEK, j);16751676for (int k = 1; k < 7; k++) {1677cal.add(DATE, 1);1678int WOY = cal.get(WEEK_OF_YEAR);1679if (WOY != maxWeek) {1680errln(cal.getTime() + ",got=" + WOY1681+ ",expected=" + maxWeek1682+ ",min=" + j1 + ",first=" + j);1683}1684}16851686cal.add(DATE, 1);1687int WOY = cal.get(WEEK_OF_YEAR);1688if (WOY != 1) {1689errln(cal.getTime() + ",got=" + WOY1690+ ",expected=1,min=" + j1 + ",first" + j);1691}1692}1693}1694}1695} finally {1696TimeZone.setDefault(savedTZ);1697}1698}16991700public void Test4328747() throws Exception {1701Calendar c = Calendar.getInstance(Locale.US);1702c.clear();1703c.set(1966, 0, 1); // 1 jan 196617041705// serialize1706ByteArrayOutputStream out = new ByteArrayOutputStream();1707ObjectOutputStream s = new ObjectOutputStream(out);1708s.writeObject(c);1709s.flush();17101711// deserialize1712ObjectInputStream t = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));1713Calendar result = (Calendar) t.readObject();17141715// let recalculate fields with the same UTC time1716result.setTime(result.getTime());1717// Bug gives 1965 11 191718if ((result.get(YEAR) != 1966) || (result.get(MONTH) != 0)1719|| (result.get(DATE) != 1)) {1720errln("deserialized Calendar returned wrong date field(s): "1721+ result.get(YEAR) + "/" + result.get(MONTH) + "/" + result.get(DATE)1722+ ", expected 1966/0/1");1723}1724}17251726/**1727* Test whether Calendar can be serialized/deserialized correctly1728* even if invalid/customized TimeZone is used.1729*/1730public void Test4413980() {1731TimeZone savedTimeZone = TimeZone.getDefault();1732try {1733boolean pass = true;1734String[] IDs = new String[]{"Undefined", "PST", "US/Pacific",1735"GMT+3:00", "GMT-01:30"};1736for (int i = 0; i < IDs.length; i++) {1737TimeZone tz = TimeZone.getTimeZone(IDs[i]);1738TimeZone.setDefault(tz);17391740Calendar c = Calendar.getInstance();17411742// serialize1743ByteArrayOutputStream out = new ByteArrayOutputStream();1744ObjectOutputStream s = new ObjectOutputStream(out);1745s.writeObject(c);1746s.flush();17471748// deserialize1749ObjectInputStream t = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));17501751if (!c.equals(t.readObject())) {1752pass = false;1753logln("Calendar instance which uses TimeZone <"1754+ IDs[i] + "> is incorrectly serialized/deserialized.");1755} else {1756logln("Calendar instance which uses TimeZone <"1757+ IDs[i] + "> is correctly serialized/deserialized.");1758}1759}1760if (!pass) {1761errln("Fail: Calendar serialization/equality bug");1762}1763} catch (IOException | ClassNotFoundException e) {1764errln("Fail: " + e);1765e.printStackTrace();1766} finally {1767TimeZone.setDefault(savedTimeZone);1768}1769}17701771/**1772* 4546637: Incorrect WEEK_OF_MONTH after changing First Day Of Week1773*/1774public void Test4546637() {1775GregorianCalendar day = new GregorianCalendar(2001, NOVEMBER, 04);1776day.setMinimalDaysInFirstWeek(1);1777int wom = day.get(WEEK_OF_MONTH);17781779day.setFirstDayOfWeek(MONDAY);1780if (day.get(WEEK_OF_MONTH) != 1) {1781errln("Fail: 2001/11/4 must be the first week of the month.");1782}1783}17841785/**1786* 4623997: GregorianCalendar returns bad WEEK_OF_YEAR1787*/1788public void Test4623997() {1789GregorianCalendar cal = new GregorianCalendar(2000, JANUARY, 1);17901791int dow = cal.get(DAY_OF_WEEK);17921793cal.setFirstDayOfWeek(MONDAY);1794cal.setMinimalDaysInFirstWeek(4);17951796if (cal.get(WEEK_OF_YEAR) != 52) {1797errln("Fail: 2000/1/1 must be the 52nd week of the year.");1798}1799}18001801/**1802* 4685354: Handling of Calendar fields setting state is broken1803*1804* <p>Need to use SimpleDateFormat to test because a call to1805* get(int) changes internal states of a Calendar.1806*/1807public void Test4685354() {1808Locale locale = Locale.getDefault();1809if (!TestUtils.usesAsciiDigits(locale)1810|| !TestUtils.usesGregorianCalendar(locale)) {1811logln("Skipping this test because locale is " + locale);1812return;1813}18141815Calendar calendar = Calendar.getInstance(Locale.US);1816DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);1817String expected = "1999/12/31";1818Date t;1819String s;18201821try {1822calendar.setTime(df.parse(expected));1823} catch (Exception e) {1824throw new RuntimeException("Unexpected parse exception", e);1825}18261827t = calendar.getTime();1828calendar.set(DAY_OF_MONTH, 33);1829t = calendar.getTime();1830calendar.set(DAY_OF_MONTH, 0);1831s = df.format(calendar.getTime());1832if (!expected.equals(s)) {1833errln("DAY_OF_MONTH w/o ZONE_OFFSET: expected: " + expected + ", got: " + s);1834}18351836// The same thing must work with ZONE_OFFSET set1837try {1838calendar.setTime(df.parse(expected));1839} catch (Exception e) {1840throw new RuntimeException("Unexpected parse exception", e);1841}1842t = calendar.getTime();1843calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET));1844calendar.set(DAY_OF_MONTH, 33);1845t = calendar.getTime();1846calendar.set(DAY_OF_MONTH, 0);1847s = df.format(calendar.getTime());1848if (!expected.equals(s)) {1849errln("DAY_OF_MONTH: expected: " + expected + ", got: " + s);1850}18511852expected = "1999/12/24"; // 0th week of 20001853calendar.clear();1854Date initialDate = null;1855try {1856initialDate = df.parse(expected);1857calendar.setTime(initialDate);1858} catch (Exception e) {1859throw new RuntimeException("Unexpected parse exception", e);1860}1861t = calendar.getTime();1862calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET));1863// jump to the next year1864calendar.set(WEEK_OF_YEAR, 100);1865t = calendar.getTime();1866calendar.set(WEEK_OF_YEAR, 0);1867s = df.format(calendar.getTime());1868if (!expected.equals(s)) {1869errln("WEEK_OF_YEAR: expected: " + expected + ", got: " + s);1870}1871// change the state back1872calendar.clear();1873calendar.setTime(initialDate);1874calendar.set(ZONE_OFFSET, calendar.get(ZONE_OFFSET));1875// jump to next month1876calendar.set(WEEK_OF_MONTH, 7);1877t = calendar.getTime();1878calendar.set(WEEK_OF_MONTH, 0);1879s = df.format(calendar.getTime());1880if (!expected.equals(s)) {1881errln("WEEK_OF_MONTH: expected: " + expected + ", got: " + s);1882}18831884// Make sure the time fields work correctly.1885calendar.clear();1886df = new SimpleDateFormat("HH:mm:ss");1887TimeZone tz = TimeZone.getTimeZone("GMT");1888df.setTimeZone(tz);1889calendar.setTimeZone(tz);1890expected = "22:59:59";1891try {1892calendar.setTime(df.parse(expected));1893} catch (Exception e) {1894throw new RuntimeException("Unexpected parse exception", e);1895}1896t = calendar.getTime();1897// time should be 22:59:59.1898calendar.set(MINUTE, 61);1899// time should be 23:01:59.1900t = calendar.getTime();1901calendar.set(MINUTE, -1);1902// time should be back to 22:59:59.1903s = df.format(calendar.getTime());1904if (!expected.equals(s)) {1905errln("MINUTE: expected: " + expected + ", got: " + s);1906}1907}19081909/**1910* 4655637: Calendar.set() for DAY_OF_WEEK does not return the right value1911*1912* <p>Need to use SimpleDateFormat to test because a call to1913* get(int) changes internal states of a Calendar.1914*/1915public void Test4655637() {1916Locale locale = Locale.getDefault();1917if (!TestUtils.usesGregorianCalendar(locale)) {1918logln("Skipping this test because locale is " + locale);1919return;1920}19211922Calendar cal = Calendar.getInstance();1923cal.setTime(new Date(1029814211523L));1924cal.set(YEAR, 2001);1925Date t = cal.getTime();1926cal.set(MONTH, JANUARY);1927t = cal.getTime();19281929cal.set(DAY_OF_MONTH, 8);1930t = cal.getTime();19311932cal.set(DAY_OF_WEEK, MONDAY);1933DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);1934String expected = "2001/01/08";1935String s = df.format(cal.getTime());1936if (!expected.equals(s)) {1937errln("expected: " + expected + ", got: " + s);1938}1939}19401941/**1942* 4683492: Invalid value for MONTH in GregorianCalendar causes exception in getTime().1943*1944* <p>Need to use SimpleDateFormat to test because a call to1945* get(int) changes internal states of a Calendar.1946*1947* <p>This test case throws ArrayIndexOutOfBoundsException without the fix.1948*/1949public void Test4683492() {1950Calendar cal = new GregorianCalendar(2002, 3, 29, 10, 0, 0);1951cal.set(DAY_OF_WEEK, FRIDAY);1952cal.set(DAY_OF_WEEK_IN_MONTH, -1);1953cal.set(MONTH, 12);1954DateFormat df = new SimpleDateFormat("yyyy/MM/dd", Locale.US);1955String expected = "2003/01/31";1956String s = df.format(cal.getTime());1957if (!expected.equals(s)) {1958errln("expected: " + expected + ", got: " + s);1959}1960}19611962/**1963* 4080631: Calendar.hashCode is amazingly bad1964*/1965public void Test4080631() {1966Calendar cal = Calendar.getInstance();1967int h1 = cal.hashCode();1968cal.add(SECOND, +1);1969int h2 = cal.hashCode();1970Calendar cal2 = (Calendar) cal.clone();1971cal.add(MILLISECOND, +1);1972int h3 = cal.hashCode();1973logln("hash code: h1=" + h1 + ", h2=" + h2 + ", h3=" + h3);1974if (h1 == h2 || h1 == h3 || h2 == h3) {1975errln("hash code is poor: hashCode=" + h1);1976}1977h2 = cal2.hashCode();1978cal.add(MILLISECOND, -1);1979int h4 = cal.hashCode();1980logln("hash code: h2=" + h2 + ", h4=" + h4);1981if (cal.equals(cal2) && h2 != h4) {1982errln("broken hash code: h2=" + h2 + ", h4=" + h4);1983}1984int x = cal.getFirstDayOfWeek() + 3;1985if (x > SATURDAY) {1986x -= 7;1987}1988cal.setFirstDayOfWeek(x);1989int h5 = cal.hashCode();1990logln("hash code: h4=" + h4 + ", h5=" + h5);1991if (h4 == h5) {1992errln("has code is poor with first day of week param: hashCode=" + h4);1993}1994}19951996/**1997* 4125161: RFE: GregorianCalendar needs more era names (BCE and CE)1998*/1999/*2000public void Test4125161() throws Exception {2001Class gc = GregorianCalendar.class;2002Field f;2003int mod;2004f = gc.getDeclaredField("BCE");2005mod = f.getModifiers();2006if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) {2007errln("BCE: wrong modifiers: " + mod);2008}2009f = gc.getDeclaredField("CE");2010mod = f.getModifiers();2011if (!Modifier.isStatic(mod) || !Modifier.isFinal(mod)) {2012errln("CE: wrong modifiers: " + mod);2013}2014if (GregorianCalendar.BCE != GregorianCalendar.BC2015|| GregorianCalendar.CE != GregorianCalendar.AD) {2016errln("Wrong BCE and/or CE values");2017}2018}2019*/2020/**2021* 4167995: GregorianCalendar.setGregorianChange() not to spec2022*/2023public void Test4167995() {2024Koyomi gc = new Koyomi(TimeZone.getTimeZone("GMT"));2025logln("Hybrid: min date");2026gc.setTime(new Date(Long.MIN_VALUE));2027if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY)2028|| !gc.checkFieldValue(ERA, GregorianCalendar.BC)) {2029errln(gc.getMessage());2030}2031logln("Hybrid: max date");2032gc.setTime(new Date(Long.MAX_VALUE));2033if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY)2034|| !gc.checkFieldValue(ERA, GregorianCalendar.AD)) {2035errln(gc.getMessage());2036}20372038gc.setGregorianChange(new Date(Long.MIN_VALUE));2039logln("Gregorian: min date");2040gc.setTime(new Date(Long.MIN_VALUE));2041if (!gc.checkDate(292275056, MAY, 16, SUNDAY)2042|| !gc.checkFieldValue(ERA, GregorianCalendar.BC)) {2043errln(gc.getMessage());2044}2045logln("Gregorian: max date");2046gc.setTime(new Date(Long.MAX_VALUE));2047if (!gc.checkDate(292278994, AUGUST, 17, SUNDAY)2048|| !gc.checkFieldValue(ERA, GregorianCalendar.AD)) {2049errln(gc.getMessage());2050}20512052gc.setGregorianChange(new Date(Long.MAX_VALUE));2053logln("Julian: min date");2054gc.setTime(new Date(Long.MIN_VALUE));2055if (!gc.checkDate(292269055, DECEMBER, 2, SUNDAY)2056|| !gc.checkFieldValue(ERA, GregorianCalendar.BC)) {2057errln(gc.getMessage());2058}2059logln("Julian: max date");2060gc.setTime(new Date(Long.MAX_VALUE));2061if (!gc.checkDate(292272993, JANUARY, 4, SUNDAY)2062|| !gc.checkFieldValue(ERA, GregorianCalendar.AD)) {2063errln(gc.getMessage());2064}2065}20662067/**2068* 4340146: Calendar.equals modifies state2069*/2070public void Test4340146() {2071Koyomi cal = new Koyomi();2072cal.clear();2073cal.set(2003, OCTOBER, 32);2074cal.equals(new Koyomi());2075if (!cal.checkInternalDate(2003, OCTOBER, 32)) {2076errln(cal.getMessage());2077}2078new Koyomi().equals(cal);2079if (!cal.checkInternalDate(2003, OCTOBER, 32)) {2080errln(cal.getMessage());2081}2082}20832084/**2085* 4639407: GregorianCalendar doesn't work in non-lenient due to timezone bounds checking2086*/2087public void Test4639407() {2088// The following operations in non-lenient mode shouldn't2089// throw IllegalArgumentException.2090Koyomi cal = new Koyomi(TimeZone.getTimeZone("Pacific/Kiritimati"));2091cal.setLenient(false);2092cal.set(2003, OCTOBER, 10);2093cal.getTime();2094cal.setTimeZone(TimeZone.getTimeZone("Pacific/Tongatapu"));2095cal.set(2003, OCTOBER, 10);2096cal.getTime();2097}20982099/**2100* 4652815: rolling week-of-year back hundreds of weeks changes year2101*/2102public void Test4652815() {2103Koyomi cal = new Koyomi(Locale.US);2104testRoll(cal, 2003, SEPTEMBER, 29);2105testRoll(cal, 2003, DECEMBER, 24);2106testRoll(cal, 1582, DECEMBER, 19);2107testRoll(cal, 1582, DECEMBER, 20);2108}21092110private void testRoll(Koyomi cal, int year, int month, int dayOfMonth) {2111cal.clear();2112cal.set(year, month, dayOfMonth);2113cal.getTime(); // normalize fields2114logln("Roll backwards from " + cal.toDateString());2115for (int i = 0; i < 1000; i++) {2116cal.roll(WEEK_OF_YEAR, -i);2117if (!cal.checkFieldValue(YEAR, year)) {2118errln(cal.getMessage());2119}2120}2121logln("Roll forewards from " + cal.toDateString());2122for (int i = 0; i < 1000; i++) {2123cal.roll(WEEK_OF_YEAR, +i);2124if (!cal.checkFieldValue(YEAR, year)) {2125errln(cal.getMessage());2126}2127}2128}21292130/**2131* 4652830: GregorianCalendar roll behaves unexpectedly for dates in BC era2132*/2133public void Test4652830() {2134Koyomi cal = new Koyomi(Locale.US);2135cal.clear();2136logln("BCE 9-2-28 (leap year) roll DAY_OF_MONTH++ twice");2137cal.set(ERA, GregorianCalendar.BC);2138cal.set(9, FEBRUARY, 28);2139if (cal.getActualMaximum(DAY_OF_YEAR) != 366) {2140errln(" wrong actual max of DAY_OF_YEAR: got "2141+ cal.getActualMaximum(DAY_OF_YEAR) + " expected " + 366);2142}2143cal.roll(DAY_OF_MONTH, +1);2144if (!cal.checkFieldValue(ERA, GregorianCalendar.BC)2145|| !cal.checkDate(9, FEBRUARY, 29)) {2146errln(cal.getMessage());2147}2148cal.roll(DAY_OF_MONTH, +1);2149if (!cal.checkFieldValue(ERA, GregorianCalendar.BC)2150|| !cal.checkDate(9, FEBRUARY, 1)) {2151errln(cal.getMessage());2152}2153}21542155/**2156* 4740554: GregorianCalendar.getActualMaximum is inconsistent with normalization2157*/2158public void Test4740554() {2159logln("1999/(Feb+12)/1 should be normalized to 2000/Feb/1 for getActualMaximum");2160Koyomi cal = new Koyomi(Locale.US);2161cal.clear();2162cal.set(1999, FEBRUARY + 12, 1);2163if (!cal.checkActualMaximum(DAY_OF_YEAR, 366)) {2164errln(cal.getMessage());2165}2166if (!cal.checkActualMaximum(DAY_OF_MONTH, 29)) {2167errln(cal.getMessage());2168}2169}21702171/**2172* 4936355: GregorianCalendar causes overflow/underflow with time of day calculation2173*/2174public void Test4936355() {2175Koyomi cal = new Koyomi(TimeZone.getTimeZone("GMT"));2176cal.clear();2177cal.set(1970, JANUARY, 1);2178checkTimeCalculation(cal, HOUR_OF_DAY, Integer.MAX_VALUE,2179(long) Integer.MAX_VALUE * 60 * 60 * 1000);21802181cal.clear();2182cal.set(1970, JANUARY, 1);2183checkTimeCalculation(cal, HOUR, Integer.MAX_VALUE,2184(long) Integer.MAX_VALUE * 60 * 60 * 1000);21852186cal.clear();2187cal.set(1970, JANUARY, 1);2188checkTimeCalculation(cal, MINUTE, Integer.MAX_VALUE,2189(long) Integer.MAX_VALUE * 60 * 1000);21902191cal.clear();2192// Make sure to use Gregorian dates (before and after the2193// set() call) for testing2194cal.set(250000, JANUARY, 1);2195checkTimeCalculation(cal, HOUR_OF_DAY, Integer.MIN_VALUE,2196(long) Integer.MIN_VALUE * 60 * 60 * 1000);21972198cal.clear();2199cal.set(250000, JANUARY, 1);2200checkTimeCalculation(cal, HOUR, Integer.MIN_VALUE,2201(long) Integer.MIN_VALUE * 60 * 60 * 1000);22022203cal.clear();2204cal.set(250000, JANUARY, 1);2205checkTimeCalculation(cal, MINUTE, Integer.MIN_VALUE,2206(long) Integer.MIN_VALUE * 60 * 1000);2207}22082209private void checkTimeCalculation(Koyomi cal, int field, int value, long expectedDelta) {2210long time = cal.getTimeInMillis();2211cal.set(field, value);2212long time2 = cal.getTimeInMillis();2213if ((time + expectedDelta) != time2) {2214String s = value == Integer.MAX_VALUE ? "Integer.MAX_VALUE" : "Integer.MIN_VALUE";2215errln("set(" + Koyomi.getFieldName(field) + ", " + s + ") failed." + " got " + time22216+ ", expected " + (time + expectedDelta));2217}2218}22192220/**2221* 4722650: Calendar.equals can throw an exception in non-lenient2222* (piggy-back tests for compareTo() which is new in 1.5)2223*/2224public void Test4722650() {2225Calendar cal1 = new GregorianCalendar();2226cal1.clear();2227Calendar cal2 = new GregorianCalendar();2228cal2.clear();2229cal2.setLenient(false);22302231cal1.set(2003, OCTOBER, 31);2232cal2.set(2003, OCTOBER, 31);2233try {2234if (cal1.equals(cal2)) {2235errln("lenient and non-lenient shouldn't be equal. (2003/10/31)");2236}2237if (cal1.compareTo(cal2) != 0) {2238errln("cal1 and cal2 should represent the same time. (2003/10/31)");2239}2240} catch (IllegalArgumentException e) {2241errln("equals threw IllegalArugumentException with non-lenient");2242}22432244cal1.set(2003, OCTOBER, 32);2245cal2.set(2003, OCTOBER, 32);2246try {2247if (cal1.equals(cal2)) {2248errln("lenient and non-lenient shouldn't be equal. (2003/10/32)");2249}2250if (cal1.compareTo(cal2) != 0) {2251errln("cal1 and cal2 should represent the same time. (2003/10/32)");2252}2253} catch (IllegalArgumentException e) {2254errln("equals threw IllegalArugumentException with non-lenient");2255}22562257cal1 = Calendar.getInstance(new Locale("th", "TH"));2258cal1.setTimeInMillis(0L);2259cal2 = Calendar.getInstance(Locale.US);2260cal2.setTimeInMillis(0L);2261if (cal1.equals(cal2)) {2262errln("Buddhist.equals(Gregorian) shouldn't be true. (millis=0)");2263}2264if (cal1.compareTo(cal2) != 0) {2265errln("cal1 (Buddhist) and cal2 (Gregorian) should represent the same time. (millis=0)");2266}2267}22682269/**2270* 4738710: API: Calendar comparison methods should be improved2271*/2272public void Test4738710() {2273Calendar cal0 = new GregorianCalendar(2003, SEPTEMBER, 30);2274Comparable<Calendar> cal1 = new GregorianCalendar(2003, OCTOBER, 1);2275Calendar cal2 = new GregorianCalendar(2003, OCTOBER, 2);2276if (!(cal1.compareTo(cal0) > 0)) {2277errln("!(cal1 > cal0)");2278}2279if (!(cal1.compareTo(cal2) < 0)) {2280errln("!(cal1 < cal2)");2281}2282if (cal1.compareTo(new GregorianCalendar(2003, OCTOBER, 1)) != 0) {2283errln("cal1 != new GregorianCalendar(2003, OCTOBER, 1)");2284}22852286if (cal0.after(cal2)) {2287errln("cal0 shouldn't be after cal2");2288}2289if (cal2.before(cal0)) {2290errln("cal2 shouldn't be before cal0");2291}22922293if (cal0.after(0)) {2294errln("cal0.after() returned true with an Integer.");2295}2296if (cal0.before(0)) {2297errln("cal0.before() returned true with an Integer.");2298}2299if (cal0.after(null)) {2300errln("cal0.after() returned true with null.");2301}2302if (cal0.before(null)) {2303errln("cal0.before() returned true with null.");2304}2305}23062307/**2308* 4633646: Setting WEEK_OF_MONTH to 1 results in incorrect date2309*/2310@SuppressWarnings("deprecation")2311public void Test4633646() {2312Koyomi cal = new Koyomi(Locale.US);2313cal.setTime(new Date(2002 - 1900, 1 - 1, 28));2314sub4633646(cal);23152316cal.setLenient(false);2317cal.setTime(new Date(2002 - 1900, 1 - 1, 28));2318sub4633646(cal);23192320cal = new Koyomi(Locale.US);2321cal.clear();2322cal.set(2002, JANUARY, 28);2323sub4633646(cal);23242325cal.clear();2326cal.setLenient(false);2327cal.set(2002, JANUARY, 28);2328sub4633646(cal);2329}23302331void sub4633646(Koyomi cal) {2332cal.getTime();2333cal.set(WEEK_OF_MONTH, 1);2334if (cal.isLenient()) {2335if (!cal.checkDate(2001, DECEMBER, 31)) {2336errln(cal.getMessage());2337}2338if (!cal.checkFieldValue(WEEK_OF_MONTH, 6)) {2339errln(cal.getMessage());2340}2341} else {2342try {2343Date d = cal.getTime();2344errln("didn't throw IllegalArgumentException in non-lenient");2345} catch (IllegalArgumentException e) {2346}2347}2348}23492350/**2351* 4846659: Calendar: Both set() and roll() don't work for AM_PM time field2352* (Partially fixed only roll as of 1.5)2353*/2354public void Test4846659() {2355Koyomi cal = new Koyomi();2356cal.clear();2357cal.set(2003, OCTOBER, 31, 10, 30, 30);2358cal.getTime();2359// Test roll()2360cal.roll(AM_PM, +1); // should turn to PM2361if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) {2362errln("roll: AM_PM didn't change to PM");2363}23642365cal.clear();2366cal.set(2003, OCTOBER, 31, 10, 30, 30);2367cal.getTime();2368// Test set()2369cal.set(AM_PM, PM); // should turn to PM2370if (!cal.checkFieldValue(HOUR_OF_DAY, 10 + 12)) {2371errln("set: AM_PM didn't change to PM");2372}23732374cal.clear();2375cal.set(2003, OCTOBER, 31, 10, 30, 30);2376cal.getTime();2377cal.set(AM_PM, PM);2378cal.set(HOUR, 9);2379if (!cal.checkFieldValue(HOUR_OF_DAY, 9 + 12)) {2380errln("set: both AM_PM and HOUT didn't change to PM");2381}2382}23832384/**2385* 4822110: GregorianCalendar.get() returns an incorrect date after setFirstDayOfWeek()2386*/2387public void Test4822110() {2388Koyomi cal = new Koyomi(Locale.US);2389// June 20032390// S M Tu W Th F S2391// 1 2 3 4 5 6 72392// 8 9 10 11 12 13 142393// 15 16 17 18 19 20 212394// 22 23 24 25 26 27 282395// 29 302396cal.clear();2397// 6/1 to 6/7 should be the 1st week of June.2398cal.set(2003, JUNE, 2);2399cal.getTime(); // Let cal calculate time.2400cal.setFirstDayOfWeek(MONDAY);2401// Now 6/2 to 6/8 should be the 2nd week of June. Sunday of2402// that week is 6/8.2403logln("1: " + cal.get(WEEK_OF_MONTH) + ", " + cal.get(DAY_OF_MONTH));2404cal.set(DAY_OF_WEEK, SUNDAY);2405logln("1st Sunday of June 2003 with FirstDayOfWeek=MONDAY");2406if (!cal.checkDate(2003, JUNE, 8)) {2407errln(cal.getMessage());2408}2409}24102411/**2412* 4973919: Inconsistent GregorianCalendar hashCode before and after serialization2413*/2414public void Test4966499() throws Exception {2415GregorianCalendar date1 = new GregorianCalendar(2004, JANUARY, 7);24162417// Serialize date12418ByteArrayOutputStream baos = new ByteArrayOutputStream();2419ObjectOutputStream oos = new ObjectOutputStream(baos);2420oos.writeObject(date1);24212422byte[] buffer = baos.toByteArray();24232424// Deserialize it2425ByteArrayInputStream bais = new ByteArrayInputStream(buffer);2426ObjectInputStream ois = new ObjectInputStream(bais);2427GregorianCalendar date2 = (GregorianCalendar) ois.readObject();24282429if (!date1.equals(date2)) {2430errln("date1.equals(date2) != true");2431}2432if (date1.hashCode() != date2.hashCode()) {2433errln("inconsistent hashCode() value (before=0x"2434+ Integer.toHexString(date1.hashCode())2435+ ", after=0x" + Integer.toHexString(date2.hashCode()) + ")");2436}2437}24382439/**2440* 4980088: GregorianCalendar.getActualMaximum doesn't throw exception2441*/2442public void Test4980088() {2443GregorianCalendar cal = new GregorianCalendar();2444try {2445int x = cal.getMaximum(100);2446errln("getMaximum(100) didn't throw an exception.");2447} catch (IndexOutOfBoundsException e) {2448logln("getMaximum: " + e.getClass().getName() + ": " + e.getMessage());2449}24502451try {2452int x = cal.getLeastMaximum(100);2453errln("getLeastMaximum(100) didn't throw an exception.");2454} catch (IndexOutOfBoundsException e) {2455logln("getLeastMaximum: " + e.getClass().getName() + ": " + e.getMessage());2456}24572458try {2459int x = cal.getActualMaximum(100);2460errln("getActualMaximum(100) didn't throw an exception.");2461} catch (IndexOutOfBoundsException e) {2462logln("getActualMaximum: " + e.getClass().getName() + ": " + e.getMessage());2463}24642465try {2466int x = cal.getMinimum(100);2467errln("getMinimum(100) didn't throw an exception.");2468} catch (IndexOutOfBoundsException e) {2469logln("getMinimum: " + e.getClass().getName() + ": " + e.getMessage());2470}24712472try {2473int x = cal.getGreatestMinimum(100);2474errln("getGreatestMinimum(100) didn't throw an exception.");2475} catch (IndexOutOfBoundsException e) {2476logln("getGreatestMinimum: " + e.getClass().getName() + ": " + e.getMessage());2477}24782479try {2480int x = cal.getActualMinimum(100);2481errln("getActualMinimum(100) didn't throw an exception.");2482} catch (IndexOutOfBoundsException e) {2483logln("getActualMinimum: " + e.getClass().getName() + ": " + e.getMessage());2484}2485}24862487/**2488* 4965624: GregorianCalendar.isLeapYear(1000) returns incorrect value2489*/2490public void Test4965624() {2491// 5013094: This test case needs to use "GMT" to specify2492// Gregorian cutover dates.2493TimeZone savedZone = TimeZone.getDefault();2494TimeZone.setDefault(TimeZone.getTimeZone("GMT"));2495try {2496Map<Date, Boolean> data = new HashMap<>();2497data.put(getGregorianDate(999, OCTOBER, 1), Boolean.FALSE);2498data.put(getGregorianDate(1000, JANUARY, 1), Boolean.FALSE);2499data.put(getGregorianDate(1000, FEBRUARY, 1), Boolean.FALSE);2500data.put(getGregorianDate(1000, FEBRUARY, 28), Boolean.FALSE);2501data.put(getGregorianDate(1000, MARCH, 1), Boolean.TRUE);2502data.put(getGregorianDate(1001, JANUARY, 1), Boolean.TRUE);2503data.put(getGregorianDate(1001, JANUARY, 6), Boolean.TRUE);2504data.put(getGregorianDate(1001, MARCH, 1), Boolean.TRUE);25052506data.keySet().forEach(d -> {2507boolean expected = data.get(d);2508GregorianCalendar cal = new GregorianCalendar();2509cal.setGregorianChange(d);2510if (cal.isLeapYear(1000) != expected) {2511errln("isLeapYear(1000) returned " + cal.isLeapYear(1000)2512+ " with cutover date (Julian) " + d);2513}2514});2515} finally {2516TimeZone.setDefault(savedZone);2517}2518}25192520// Note that we can't use Date to produce Gregorian calendar dates2521// before the default cutover date.2522static Date getGregorianDate(int year, int month, int dayOfMonth) {2523GregorianCalendar g = new GregorianCalendar();2524// Make g a pure Gregorian calendar2525g.setGregorianChange(new Date(Long.MIN_VALUE));2526g.clear();2527g.set(year, month, dayOfMonth);2528return g.getTime();2529}25302531/**2532* 5006864: Define the minimum value of DAY_OF_WEEK_IN_MONTH as 12533*/2534public void Test5006864() {2535GregorianCalendar cal = new GregorianCalendar();2536int min = cal.getMinimum(DAY_OF_WEEK_IN_MONTH);2537if (min != 1) {2538errln("GregorianCalendar.getMinimum(DAY_OF_WEEK_IN_MONTH) returned "2539+ min + ", expected 1.");2540}2541min = cal.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH);2542if (min != 1) {2543errln("GregorianCalendar.getGreatestMinimum(DAY_OF_WEEK_IN_MONTH) returned "2544+ min + ", expected 1.");2545}2546}2547}254825492550