Path: blob/master/test/jdk/java/util/Calendar/CalendarTest.java
41149 views
/*1* Copyright (c) 1997, 2018, 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 4064654 4374886 4984320 4984574 4944795 821014226* @summary test for Calendar27* @library /java/text/testlib28* @modules java.base/java.util:+open29* @run main CalendarTest30* @key randomness31*/3233import java.io.File;34import java.io.FileInputStream;35import java.io.FileOutputStream;36import java.io.IOException;37import java.io.ObjectInputStream;38import java.io.ObjectOutput;39import java.io.ObjectOutputStream;40import java.lang.reflect.Field;41import java.util.Calendar;42import java.util.Date;43import java.util.GregorianCalendar;44import java.util.Locale;45import java.util.SimpleTimeZone;46import java.util.TimeZone;4748import static java.util.Calendar.*;4950public class CalendarTest extends IntlTest {5152static final int ONE_DAY = 24 * 60 * 60 * 1000;53static final int EPOCH_JULIAN = 2440588;5455public static void main(String argv[]) throws Exception {56new CalendarTest().run(argv);57}5859/**60* Test the behavior of the GregorianCalendar around the changeover.61*/62public void TestGregorianChangeover() {63TimeZone savedZone = TimeZone.getDefault();64/*65Changeover -7 days: 1582/9/28 dow=666Changeover -6 days: 1582/9/29 dow=767Changeover -5 days: 1582/9/30 dow=168Changeover -4 days: 1582/10/1 dow=269Changeover -3 days: 1582/10/2 dow=370Changeover -2 days: 1582/10/3 dow=471Changeover -1 days: 1582/10/4 dow=572Changeover +0 days: 1582/10/15 dow=673Changeover +1 days: 1582/10/16 dow=774Changeover +2 days: 1582/10/17 dow=175Changeover +3 days: 1582/10/18 dow=276Changeover +4 days: 1582/10/19 dow=377Changeover +5 days: 1582/10/20 dow=478Changeover +6 days: 1582/10/21 dow=579Changeover +7 days: 1582/10/22 dow=680*/81int[] MON = { 9, 9, 9,10,10,10,10, 10, 10, 10, 10, 10, 10, 10, 10 };82int[] DOM = { 28, 29, 30, 1, 2, 3, 4, 15, 16, 17, 18, 19, 20, 21, 22 };83int[] DOW = { 6, 7, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6 };84// ^ <-Changeover Fri Oct 15 158285try {86TimeZone.setDefault(TimeZone.getTimeZone("GMT"));87@SuppressWarnings("deprecation")88Date co = new Date(1582 - 1900, OCTOBER, 15);89GregorianCalendar cal = new GregorianCalendar();90int j = 0;91for (int i = -7; i <= 7; ++i, ++j) {92Date d = new Date(co.getTime() + i * ONE_DAY);93cal.setTime(d);94int y = cal.get(YEAR);95int mon = cal.get(MONTH) + 1 - JANUARY;96int dom = cal.get(DATE);97int dow = cal.get(DAY_OF_WEEK);9899logln("Changeover " + (i >= 0 ? "+" : "") + i100+ " days: " + y + "/" + mon + "/" + dom + " dow=" + dow);101if (y != 1582 || mon != MON[j] || dom != DOM[j] || dow != DOW[j]) {102errln(" Fail: Above line is wrong");103}104}105} finally {106TimeZone.setDefault(savedZone);107}108}109110/**111* Test the mapping between millis and fields. For the purposes112* of this test, we don't care about timezones and week data113* (first day of week, minimal days in first week).114*/115@SuppressWarnings("deprecation")116public void TestMapping() {117TimeZone saveZone = TimeZone.getDefault();118int[] DATA = {119// Julian# Year Month DOM JULIAN:Year Month, DOM1202440588, 1970, JANUARY, 1, 1969, DECEMBER, 19,1212415080, 1900, MARCH, 1, 1900, FEBRUARY, 17,1222451604, 2000, FEBRUARY, 29, 2000, FEBRUARY, 16,1232452269, 2001, DECEMBER, 25, 2001, DECEMBER, 12,1242416526, 1904, FEBRUARY, 15, 1904, FEBRUARY, 2,1252416656, 1904, JUNE, 24, 1904, JUNE, 11,1261721426, 1, JANUARY, 1, 1, JANUARY, 3,1272000000, 763, SEPTEMBER, 18, 763, SEPTEMBER, 14,1284000000, 6239, JULY, 12, 6239, MAY, 28,1298000000, 17191, FEBRUARY, 26, 17190, OCTOBER, 22,13010000000, 22666, DECEMBER, 20, 22666, JULY, 5};131132try {133TimeZone.setDefault(TimeZone.getTimeZone("UTC"));134Date PURE_GREGORIAN = new Date(Long.MIN_VALUE);135Date PURE_JULIAN = new Date(Long.MAX_VALUE);136GregorianCalendar cal = new GregorianCalendar();137for (int i = 0; i < DATA.length; i += 7) {138int julian = DATA[i];139int year = DATA[i + 1];140int month = DATA[i + 2];141int dom = DATA[i + 3];142int year2, month2, dom2;143long millis = ((long) julian - EPOCH_JULIAN) * ONE_DAY;144String s;145146// Test Gregorian computation147cal.setGregorianChange(PURE_GREGORIAN);148cal.clear();149cal.set(year, month, dom);150long calMillis = cal.getTime().getTime();151long delta = calMillis - millis;152cal.setTime(new Date(millis));153year2 = cal.get(YEAR);154month2 = cal.get(MONTH);155dom2 = cal.get(DAY_OF_MONTH);156s = "G " + year + "-" + (month + 1 - JANUARY) + "-" + dom157+ " => " + calMillis158+ " (" + ((float) delta / ONE_DAY) + " day delta) => "159+ year2 + "-" + (month2 + 1 - JANUARY) + "-" + dom2;160if (delta != 0 || year != year2 || month != month2161|| dom != dom2) {162errln(s + " FAIL");163} else {164logln(s);165}166167// Test Julian computation168year = DATA[i + 4];169month = DATA[i + 5];170dom = DATA[i + 6];171cal.setGregorianChange(PURE_JULIAN);172cal.clear();173cal.set(year, month, dom);174calMillis = cal.getTime().getTime();175delta = calMillis - millis;176cal.setTime(new Date(millis));177year2 = cal.get(YEAR);178month2 = cal.get(MONTH);179dom2 = cal.get(DAY_OF_MONTH);180s = "J " + year + "-" + (month + 1 - JANUARY) + "-" + dom181+ " => " + calMillis182+ " (" + ((float) delta / ONE_DAY) + " day delta) => "183+ year2 + "-" + (month2 + 1 - JANUARY) + "-" + dom2;184if (delta != 0 || year != year2 || month != month2185|| dom != dom2) {186errln(s + " FAIL");187} else {188logln(s);189}190}191192cal.setGregorianChange(new Date(1582 - 1900, OCTOBER, 15));193auxMapping(cal, 1582, OCTOBER, 4);194auxMapping(cal, 1582, OCTOBER, 15);195auxMapping(cal, 1582, OCTOBER, 16);196for (int y = 800; y < 3000; y += 1 + 100 * Math.random()) {197for (int m = JANUARY; m <= DECEMBER; ++m) {198auxMapping(cal, y, m, 15);199}200}201} finally {202TimeZone.setDefault(saveZone);203}204}205private void auxMapping(Calendar cal, int y, int m, int d) {206cal.clear();207cal.set(y, m, d);208long millis = cal.getTime().getTime();209cal.setTime(new Date(millis));210int year2 = cal.get(YEAR);211int month2 = cal.get(MONTH);212int dom2 = cal.get(DAY_OF_MONTH);213if (y != year2 || m != month2 || dom2 != d) {214errln("Round-trip failure: " + y + "-" + (m + 1) + "-" + d + " =>ms=> "215+ year2 + "-" + (month2 + 1) + "-" + dom2);216}217}218219@SuppressWarnings("deprecation")220public void TestGenericAPI() {221Locale locale = Locale.getDefault();222if (!TestUtils.usesGregorianCalendar(locale)) {223logln("Skipping this test because locale is " + locale);224return;225}226227String str;228Date when = new Date(90, APRIL, 15);229230String tzid = "TestZone";231int tzoffset = 123400;232233SimpleTimeZone zone = new SimpleTimeZone(tzoffset, tzid);234Calendar cal = Calendar.getInstance((SimpleTimeZone) zone.clone());235236if (!zone.equals(cal.getTimeZone())) {237errln("FAIL: Calendar.getTimeZone failed");238}239240Calendar cal2 = Calendar.getInstance(cal.getTimeZone());241242cal.setTime(when);243cal2.setTime(when);244245if (!(cal.equals(cal2))) {246errln("FAIL: Calendar.operator== failed");247}248// if ((*cal != *cal2)) errln("FAIL: Calendar.operator!= failed");249if (!cal.equals(cal2)250|| cal.before(cal2)251|| cal.after(cal2)) {252errln("FAIL: equals/before/after failed");253}254255cal2.setTime(new Date(when.getTime() + 1000));256if (cal.equals(cal2)257|| cal2.before(cal)258|| cal.after(cal2)) {259errln("FAIL: equals/before/after failed");260}261262cal.roll(SECOND, true);263if (!cal.equals(cal2)264|| cal.before(cal2)265|| cal.after(cal2)) {266errln("FAIL: equals/before/after failed");267}268269// Roll back to January270cal.roll(MONTH, 1 + DECEMBER - cal.get(MONTH));271if (cal.equals(cal2)272|| cal2.before(cal)273|| cal.after(cal2)) {274errln("FAIL: equals/before/after failed");275}276277// C++ only278/* TimeZone z = cal.orphanTimeZone();279if (z.getID(str) != tzid ||280z.getRawOffset() != tzoffset)281errln("FAIL: orphanTimeZone failed");282*/283for (int i = 0; i < 2; ++i) {284boolean lenient = (i > 0);285cal.setLenient(lenient);286if (lenient != cal.isLenient()) {287errln("FAIL: setLenient/isLenient failed");288}289// Later: Check for lenient behavior290}291292int i;293for (i = SUNDAY; i <= SATURDAY; ++i) {294cal.setFirstDayOfWeek(i);295if (cal.getFirstDayOfWeek() != i) {296errln("FAIL: set/getFirstDayOfWeek failed");297}298}299300for (i = 0; i <= 7; ++i) {301cal.setMinimalDaysInFirstWeek(i);302if (cal.getMinimalDaysInFirstWeek() != i) {303errln("FAIL: set/getFirstDayOfWeek failed");304}305}306307for (i = 0; i < FIELD_COUNT; ++i) {308if (cal.getMinimum(i) != cal.getGreatestMinimum(i)) {309errln("FAIL: getMinimum doesn't match getGreatestMinimum for field " + i);310}311if (cal.getLeastMaximum(i) > cal.getMaximum(i)) {312errln("FAIL: getLeastMaximum larger than getMaximum for field " + i);313}314if (cal.getMinimum(i) >= cal.getMaximum(i)) {315errln("FAIL: getMinimum not less than getMaximum for field " + i);316}317}318319cal.setTimeZone(TimeZone.getDefault());320cal.clear();321cal.set(1984, 5, 24);322if (cal.getTime().getTime() != new Date(84, 5, 24).getTime()) {323errln("FAIL: Calendar.set(3 args) failed");324logln(" Got: " + cal.getTime() + " Expected: " + new Date(84, 5, 24));325}326327cal.clear();328cal.set(1985, 3, 2, 11, 49);329if (cal.getTime().getTime() != new Date(85, 3, 2, 11, 49).getTime()) {330errln("FAIL: Calendar.set(5 args) failed");331logln(" Got: " + cal.getTime() + " Expected: " + new Date(85, 3, 2, 11, 49));332}333334cal.clear();335cal.set(1995, 9, 12, 1, 39, 55);336if (cal.getTime().getTime() != new Date(95, 9, 12, 1, 39, 55).getTime()) {337errln("FAIL: Calendar.set(6 args) failed");338logln(" Got: " + cal.getTime() + " Expected: " + new Date(95, 9, 12, 1, 39, 55));339}340341cal.getTime();342for (i = 0; i < FIELD_COUNT; ++i) {343switch (i) {344case YEAR:345case MONTH:346case DATE:347case HOUR_OF_DAY:348case MINUTE:349case SECOND:350if (!cal.isSet(i)) {351errln("FAIL: !Calendar.isSet test failed: " + calendarFieldNames[i]);352}353break;354default:355if (cal.isSet(i)) {356errln("FAIL: Calendar.isSet test failed: " + calendarFieldNames[i]);357}358}359cal.clear(i);360if (cal.isSet(i)) {361errln("FAIL: Calendar.clear/isSet failed");362}363}364365// delete cal;366// delete cal2;367Locale[] loc = Calendar.getAvailableLocales();368long count = loc.length;369if (count < 1 || loc == null) {370errln("FAIL: getAvailableLocales failed");371} else {372for (i = 0; i < count; ++i) {373cal = Calendar.getInstance(loc[i]);374// delete cal;375}376}377378cal = Calendar.getInstance(TimeZone.getDefault(), Locale.ENGLISH);379// delete cal;380381cal = Calendar.getInstance(zone, Locale.ENGLISH);382// delete cal;383384GregorianCalendar gc = new GregorianCalendar(zone);385// delete gc;386387gc = new GregorianCalendar(Locale.ENGLISH);388// delete gc;389390gc = new GregorianCalendar(Locale.ENGLISH);391// delete gc;392393gc = new GregorianCalendar(zone, Locale.ENGLISH);394// delete gc;395396gc = new GregorianCalendar(zone);397// delete gc;398399gc = new GregorianCalendar(1998, 10, 14, 21, 43);400if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43).getTime()) {401errln("FAIL: new GregorianCalendar(ymdhm) failed");402}403// delete gc;404405gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55);406if (gc.getTime().getTime() != new Date(98, 10, 14, 21, 43, 55).getTime()) {407errln("FAIL: new GregorianCalendar(ymdhms) failed");408}409410// C++ only:411// GregorianCalendar gc2 = new GregorianCalendar(Locale.ENGLISH);412// gc2 = gc;413// if (gc2 != gc || !(gc2 == gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");414// delete gc;415// delete z;416}417418// Verify Roger Webster's bug419public void TestRog() {420GregorianCalendar gc = new GregorianCalendar();421422int year = 1997, month = APRIL, date = 1;423gc.set(year, month, date); // April 1, 1997424425gc.set(HOUR_OF_DAY, 23);426gc.set(MINUTE, 0);427gc.set(SECOND, 0);428gc.set(MILLISECOND, 0);429430for (int i = 0; i < 9; i++, gc.add(DATE, 1)) {431if (gc.get(YEAR) != year432|| gc.get(MONTH) != month433|| gc.get(DATE) != (date + i)) {434errln("FAIL: Date " + gc.getTime() + " wrong");435}436}437}438439// Verify DAY_OF_WEEK440public void TestDOW943() {441dowTest(false);442dowTest(true);443}444445void dowTest(boolean lenient) {446GregorianCalendar cal = new GregorianCalendar();447cal.set(1997, AUGUST, 12); // Wednesday448cal.getTime(); // Force update449cal.setLenient(lenient);450cal.set(1996, DECEMBER, 1); // Set the date to be December 1, 1996451int dow = cal.get(DAY_OF_WEEK);452int min = cal.getMinimum(DAY_OF_WEEK);453int max = cal.getMaximum(DAY_OF_WEEK);454if (dow < min || dow > max) {455errln("FAIL: Day of week " + dow + " out of range");456}457if (dow != SUNDAY) {458errln("FAIL2: Day of week should be SUNDAY; is " + dow + ": " + cal.getTime());459}460if (min != SUNDAY || max != SATURDAY) {461errln("FAIL: Min/max bad");462}463}464465// Verify that the clone method produces distinct objects with no466// unintentionally shared fields.467public void TestClonesUnique908() {468Calendar c = Calendar.getInstance();469Calendar d = (Calendar) c.clone();470c.set(MILLISECOND, 123);471d.set(MILLISECOND, 456);472if (c.get(MILLISECOND) != 123473|| d.get(MILLISECOND) != 456) {474errln("FAIL: Clones share fields");475}476}477478// Verify effect of Gregorian cutoff value479@SuppressWarnings("deprecation")480public void TestGregorianChange768() {481boolean b;482GregorianCalendar c = new GregorianCalendar();483logln("With cutoff " + c.getGregorianChange());484logln(" isLeapYear(1800) = " + (b = c.isLeapYear(1800)));485logln(" (should be FALSE)");486if (b != false) {487errln("FAIL");488}489c.setGregorianChange(new Date(0, 0, 1)); // Jan 1 1900490logln("With cutoff " + c.getGregorianChange());491logln(" isLeapYear(1800) = " + (b = c.isLeapYear(1800)));492logln(" (should be TRUE)");493if (b != true) {494errln("FAIL");495}496}497498// Test the correct behavior of the disambiguation algorithm.499public void TestDisambiguation765() throws Exception {500Locale savedLocale = Locale.getDefault();501try {502Locale.setDefault(Locale.US);503Calendar c = Calendar.getInstance();504c.setLenient(false);505506c.clear();507c.set(YEAR, 1997);508c.set(MONTH, JUNE);509c.set(DATE, 3);510511verify765("1997 third day of June = ", c, 1997, JUNE, 3);512513c.clear();514c.set(YEAR, 1997);515c.set(DAY_OF_WEEK, TUESDAY);516c.set(MONTH, JUNE);517c.set(DAY_OF_WEEK_IN_MONTH, 1);518verify765("1997 first Tuesday in June = ", c, 1997, JUNE, 3);519520c.setLenient(true); // for 4944795521c.clear();522c.set(YEAR, 1997);523c.set(DAY_OF_WEEK, TUESDAY);524c.set(MONTH, JUNE);525c.set(DAY_OF_WEEK_IN_MONTH, -1);526verify765("1997 last Tuesday in June = ", c, 1997, JUNE, 24);527528c.setLenient(false);529IllegalArgumentException e = null;530try {531c.clear();532c.set(YEAR, 1997);533c.set(DAY_OF_WEEK, TUESDAY);534c.set(MONTH, JUNE);535c.set(DAY_OF_WEEK_IN_MONTH, 0);536c.getTime();537} catch (IllegalArgumentException ex) {538e = ex;539}540verify765("1997 zero-th Tuesday in June = ", e);541542c.clear();543c.set(YEAR, 1997);544c.set(DAY_OF_WEEK, TUESDAY);545c.set(MONTH, JUNE);546c.set(WEEK_OF_MONTH, 1);547verify765("1997 Tuesday in week 1 of June = ", c, 1997, JUNE, 3);548549c.clear();550c.set(YEAR, 1997);551c.set(DAY_OF_WEEK, TUESDAY);552c.set(MONTH, JUNE);553c.set(WEEK_OF_MONTH, 4);554verify765("1997 Tuesday in week 4 of June = ", c, 1997, JUNE, 24);555556try {557c.clear();558c.set(YEAR, 1997);559c.set(DAY_OF_WEEK, TUESDAY);560c.set(MONTH, JUNE);561c.set(WEEK_OF_MONTH, 1);562verify765("1997 Tuesday in week 0 of June = ", c, 1997, JUNE, 3);563} catch (IllegalArgumentException ex) {564errln("FAIL: Exception seen: " + ex.getMessage());565// ex.printStackTrace(log);566}567568c.clear();569c.set(YEAR, 1997);570c.set(DAY_OF_WEEK, TUESDAY);571c.set(WEEK_OF_YEAR, 2);572verify765("1997 Tuesday in week 2 of year = ", c, 1997, JANUARY, 7);573574c.clear();575c.set(YEAR, 1997);576c.set(DAY_OF_WEEK, TUESDAY);577c.set(WEEK_OF_YEAR, 10);578verify765("1997 Tuesday in week 10 of year = ", c, 1997, MARCH, 4);579580try {581c.clear();582c.set(YEAR, 1997);583c.set(DAY_OF_WEEK, TUESDAY);584c.set(WEEK_OF_YEAR, 0);585verify765("1997 Tuesday in week 0 of year = ", c, 1996, DECEMBER, 24);586throw new Exception("Fail: WEEK_OF_YEAR 0 should be illegal");587} catch (IllegalArgumentException ex) {588}589} finally {590Locale.setDefault(savedLocale);591}592}593594void verify765(String msg, Calendar c, int year, int month, int day) {595if (c.get(YEAR) == year596&& c.get(MONTH) == month597&& c.get(DATE) == day) {598logln("PASS: " + msg + c.getTime());599} else {600errln("FAIL: " + msg + c.getTime()601+ "; expected "602+ year + "/" + (month + 1) + "/" + day);603}604}605606// Called when e expected to be non-null607void verify765(String msg, IllegalArgumentException e) {608if (e == null) {609errln("FAIL: No IllegalArgumentException for " + msg);610} else {611logln("PASS: " + msg + "IllegalArgument as expected");612}613}614615// Test the behavior of GMT vs. local time616public void TestGMTvsLocal4064654() {617Locale locale = Locale.getDefault();618if (!TestUtils.usesGregorianCalendar(locale)) {619logln("Skipping this test because locale is " + locale);620return;621}622623// Sample output 1:624// % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 1 1 12 0 0625// date = Wed Jan 01 04:00:00 PST 1997626// offset for Wed Jan 01 04:00:00 PST 1997= -8hr627test4064654(1997, 1, 1, 12, 0, 0);628629// Sample output 2:630// % /usr/local/java/jdk1.1.3/solaris/bin/java test 1997 4 16 18 30 0631// date = Wed Apr 16 10:30:00 PDT 1997632// offset for Wed Apr 16 10:30:00 PDT 1997= -7hr633634// Note that in sample output 2 according to the offset, the gmt time635// of the result would be 1997 4 16 17 30 0 which is different from the636// input of 1997 4 16 18 30 0.637test4064654(1997, 4, 16, 18, 30, 0);638}639void test4064654(int yr, int mo, int dt, int hr, int mn, int sc) {640Date date;641Calendar gmtcal = Calendar.getInstance();642gmtcal.setTimeZone(TimeZone.getTimeZone("Africa/Casablanca"));643gmtcal.set(yr, mo - 1, dt, hr, mn, sc);644gmtcal.set(MILLISECOND, 0);645646date = gmtcal.getTime();647logln("date = " + date);648649Calendar cal = Calendar.getInstance();650cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));651cal.setTime(date);652653int offset = cal.getTimeZone().getOffset(cal.get(ERA),654cal.get(YEAR),655cal.get(MONTH),656cal.get(DATE),657cal.get(DAY_OF_WEEK),658cal.get(MILLISECOND));659660logln("offset for " + date + "= " + (offset / 1000 / 60 / 60.0) + "hr");661662int utc = ((cal.get(HOUR_OF_DAY) * 60663+ cal.get(MINUTE)) * 60664+ cal.get(SECOND)) * 1000665+ cal.get(MILLISECOND) - offset;666667int expected = ((hr * 60 + mn) * 60 + sc) * 1000;668669if (utc != expected) {670errln("FAIL: Discrepancy of "671+ (utc - expected) + " millis = "672+ ((utc - expected) / 1000 / 60 / 60.0) + " hr");673}674}675676// Verify that add and set work regardless of the order in which677// they are called.678public void TestAddSetOrder621() {679@SuppressWarnings("deprecation")680Date d = new Date(97, 4, 14, 13, 23, 45);681682Calendar cal = Calendar.getInstance();683cal.setTime(d);684cal.add(DATE, -5);685cal.set(HOUR_OF_DAY, 0);686cal.set(MINUTE, 0);687cal.set(SECOND, 0);688// ma feb 03 00:00:00 GMT+00:00 1997689String s = cal.getTime().toString();690691cal = Calendar.getInstance();692cal.setTime(d);693cal.set(HOUR_OF_DAY, 0);694cal.set(MINUTE, 0);695cal.set(SECOND, 0);696cal.add(DATE, -5);697// ma feb 03 13:11:06 GMT+00:00 1997698String s2 = cal.getTime().toString();699700if (s.equals(s2)) {701logln("Pass: " + s + " == " + s2);702} else {703errln("FAIL: " + s + " != " + s2);704}705}706707// Verify that add works.708public void TestAdd520() {709int y = 1997, m = FEBRUARY, d = 1;710GregorianCalendar temp = new GregorianCalendar(y, m, d);711check520(temp, y, m, d);712713temp.add(YEAR, 1);714y++;715check520(temp, y, m, d);716717temp.add(MONTH, 1);718m++;719check520(temp, y, m, d);720721temp.add(DATE, 1);722d++;723check520(temp, y, m, d);724725temp.add(DATE, 2);726d += 2;727check520(temp, y, m, d);728729temp.add(DATE, 28);730d = 1;731++m;732check520(temp, y, m, d);733}734735void check520(Calendar c, int y, int m, int d) {736if (c.get(YEAR) != y737|| c.get(MONTH) != m738|| c.get(DATE) != d) {739errln("FAILURE: Expected YEAR/MONTH/DATE of "740+ y + "/" + (m + 1) + "/" + d741+ "; got "742+ c.get(YEAR) + "/"743+ (c.get(MONTH) + 1) + "/"744+ c.get(DATE));745} else {746logln("Confirmed: "747+ y + "/" + (m + 1) + "/" + d);748}749}750751// Verify that setting fields works. This test fails when an exception is thrown.752public void TestFieldSet4781() {753try {754GregorianCalendar g = new GregorianCalendar();755GregorianCalendar g2 = new GregorianCalendar();756// At this point UTC value is set, various fields are not.757// Now set to noon.758g2.set(HOUR, 12);759g2.set(MINUTE, 0);760g2.set(SECOND, 0);761// At this point the object thinks UTC is NOT set, but fields are set.762// The following line will result in IllegalArgumentException because763// it thinks the YEAR is set and it is NOT.764if (g2.equals(g)) {765logln("Same");766} else {767logln("Different");768}769} catch (IllegalArgumentException e) {770errln("Unexpected exception seen: " + e);771}772}773774// Test serialization of a Calendar object775public void TestSerialize337() {776Calendar cal = Calendar.getInstance();777778boolean ok = false;779780try {781FileOutputStream f = new FileOutputStream(FILENAME);782ObjectOutput s = new ObjectOutputStream(f);783s.writeObject(PREFIX);784s.writeObject(cal);785s.writeObject(POSTFIX);786f.close();787788FileInputStream in = new FileInputStream(FILENAME);789ObjectInputStream t = new ObjectInputStream(in);790String pre = (String) t.readObject();791Calendar c = (Calendar) t.readObject();792String post = (String) t.readObject();793in.close();794795ok = pre.equals(PREFIX)796&& post.equals(POSTFIX)797&& cal.equals(c);798799File fl = new File(FILENAME);800fl.delete();801} catch (IOException e) {802errln("FAIL: Exception received:");803// e.printStackTrace(log);804} catch (ClassNotFoundException e) {805errln("FAIL: Exception received:");806// e.printStackTrace(log);807}808809if (!ok) {810errln("Serialization of Calendar object failed.");811}812}813static final String PREFIX = "abc";814static final String POSTFIX = "def";815static final String FILENAME = "tmp337.bin";816817// Try to zero out the seconds field818public void TestSecondsZero121() {819Calendar cal = new GregorianCalendar();820// Initialize with current date/time821cal.setTime(new Date());822// Round down to minute823cal.set(SECOND, 0);824Date d = cal.getTime();825String s = d.toString();826if (s.indexOf(":00 ") < 0) {827errln("Expected to see :00 in " + s);828}829}830831// Try various sequences of add, set, and get method calls.832public void TestAddSetGet0610() {833//834// Error case 1:835// - Upon initialization calendar fields, millis = System.currentTime836// - After set is called fields are initialized, time is not837// - Addition uses millis which are still *now*838//839{840Calendar calendar = new GregorianCalendar();841calendar.set(1993, JANUARY, 4);842logln("1A) " + value(calendar));843calendar.add(DATE, 1);844String v = value(calendar);845logln("1B) " + v);846logln("--) 1993/0/5");847if (!v.equals(EXPECTED_0610)) {848errln("Expected " + EXPECTED_0610849+ "; saw " + v);850}851}852853//854// Error case 2:855// - Upon initialization calendar fields set, millis = 0856// - Addition uses millis which are still 1970, 0, 1857//858{859Calendar calendar = new GregorianCalendar(1993, JANUARY, 4);860logln("2A) " + value(calendar));861calendar.add(DATE, 1);862String v = value(calendar);863logln("2B) " + v);864logln("--) 1993/0/5");865if (!v.equals(EXPECTED_0610)) {866errln("Expected " + EXPECTED_0610867+ "; saw " + v);868}869}870871//872// Error case 3:873// - Upon initialization calendar fields, millis = 0874// - getTime( ) is called which forces the millis to be set875// - Addition uses millis which are correct876//877{878Calendar calendar = new GregorianCalendar(1993, JANUARY, 4);879logln("3A) " + value(calendar));880calendar.getTime();881calendar.add(DATE, 1);882String v = value(calendar);883logln("3B) " + v);884logln("--) 1993/0/5");885if (!v.equals(EXPECTED_0610)) {886errln("Expected " + EXPECTED_0610887+ "; saw " + v);888}889}890}891static String value(Calendar calendar) {892return (calendar.get(YEAR) + "/"893+ calendar.get(MONTH) + "/"894+ calendar.get(DATE));895}896static String EXPECTED_0610 = "1993/0/5";897898// Test that certain fields on a certain date are as expected.899public void TestFields060() {900int year = 1997;901int month = OCTOBER; //october902int dDate = 22; //DAYOFWEEK should return 3 for Wednesday903GregorianCalendar calendar = null;904905calendar = new GregorianCalendar(year, month, dDate);906for (int i = 0; i < EXPECTED_FIELDS.length;) {907int field = EXPECTED_FIELDS[i++];908int expected = EXPECTED_FIELDS[i++];909if (calendar.get(field) != expected) {910errln("Expected field " + field + " to have value " + expected911+ "; received " + calendar.get(field) + " instead");912}913}914}915static int[] EXPECTED_FIELDS = {916YEAR, 1997,917MONTH, OCTOBER,918DAY_OF_MONTH, 22,919DAY_OF_WEEK, WEDNESDAY,920DAY_OF_WEEK_IN_MONTH, 4,921DAY_OF_YEAR, 295};922923static final String[] calendarFieldNames = {924/* 0 */ "ERA",925/* 1 */ "YEAR",926/* 2 */ "MONTH",927/* 3 */ "WEEK_OF_YEAR",928/* 4 */ "WEEK_OF_MONTH",929/* 5 */ "DAY_OF_MONTH",930/* 6 */ "DAY_OF_YEAR",931/* 7 */ "DAY_OF_WEEK",932/* 8 */ "DAY_OF_WEEK_IN_MONTH",933/* 9 */ "AM_PM",934/* 10 */ "HOUR",935/* 11 */ "HOUR_OF_DAY",936/* 12 */ "MINUTE",937/* 13 */ "SECOND",938/* 14 */ "MILLISECOND",939/* 15 */ "ZONE_OFFSET",940/* 16 */ "DST_OFFSET"};941942// Verify that the fields are as expected (mostly zero) at the epoch start.943// Note that we adjust for the default timezone to get most things to zero.944public void TestEpochStartFields() {945String[][] lt = {946{"en", "US", "US/Pacific"}, /* First day = 1, Minimum day = 1 */947{"en", "US", "America/Anchorage"}, /* First day = 1, Minimum day = 1 */948{"en", "TO", "Pacific/Tongatapu"}, /* First day = 1, Minimum day = 1 */949{"en", "MH", "Pacific/Majuro"}, /* First day = 1, Minimum day = 1 */950{"ja", "JP", "Asia/Tokyo"}, /* First day = 1, Minimum day = 1 */951{"iw", "IL", "Asia/Jerusalem"}, /* First day = 1, Minimum day = 1 */952{"hi", "IN", "Asia/Jakarta"}, /* First day = 1, Minimum day = 1 */953{"en", "GB", "Europe/London"}, /* First day = 2, Minimum day = 1 */954{"en", "GB", "GMT"}, /* First day = 2, Minimum day = 1 */955{"de", "DE", "Europe/Berlin"}, /* First day = 2, Minimum day = 4 */956{"ar", "EG", "Africa/Cairo"}}; /* First day = 7, Minimum day = 1 */957958int[][] goldenData = {959{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, -28800000, 0},960{1, 1969, 11, 1, 5, 31, 365, 4, 5, 1, 11, 23, 0, 0, 0, -36000000, 0},961{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 46800000, 0},962{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 43200000, 0},963{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 32400000, 0},964{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 7200000, 0},965{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 25200000, 0},966{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 1, 1, 0, 0, 0, 3600000, 0},967{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0},968{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 3600000, 0},969{1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 7200000, 0}};970971Locale savedLocale = Locale.getDefault();972TimeZone savedTimeZone = TimeZone.getDefault();973974try {975for (int j = 0; j < lt.length; j++) {976Locale l = new Locale(lt[j][0], lt[j][1]);977TimeZone z = TimeZone.getTimeZone(lt[j][2]);978Locale.setDefault(l);979TimeZone.setDefault(z);980Calendar c = Calendar.getInstance();981Date d = new Date(-z.getRawOffset());982983int val;984int[] EPOCH_FIELDS = goldenData[j];985c.setTime(d);986987boolean err = false;988for (int i = 0; i < calendarFieldNames.length; ++i) {989if ((val = c.get(i)) != EPOCH_FIELDS[i]) {990errln("Wrong value: " + val991+ " for field(" + calendarFieldNames[i]992+ "), expected: " + EPOCH_FIELDS[i]);993err = true;994}995}996if (err) {997errln("Failed: \n\tDate=" + d + "\n\tTimeZone=" + z998+ "\n\tLocale=" + l + "\n\tCalendar=" + c);999}1000}1001} finally {1002Locale.setDefault(savedLocale);1003TimeZone.setDefault(savedTimeZone);1004}1005}10061007// Verify that as you add days to the calendar (e.g., 24 day periods),1008// the day of the week shifts in the expected pattern.1009public void TestDOWProgression() {1010Calendar cal1011= new GregorianCalendar(1972, OCTOBER, 26);1012marchByDelta(cal, 24); // Last parameter must be != 0 modulo 71013}10141015// Supply a delta which is not a multiple of 7.1016void marchByDelta(Calendar cal, int delta) {1017Calendar cur = (Calendar) cal.clone();1018int initialDOW = cur.get(DAY_OF_WEEK);1019int DOW, newDOW = initialDOW;1020do {1021DOW = newDOW;1022logln("DOW = " + DOW + " " + cur.getTime());10231024cur.add(DAY_OF_WEEK, delta);1025newDOW = cur.get(DAY_OF_WEEK);1026int expectedDOW = 1 + (DOW + delta - 1) % 7;1027if (newDOW != expectedDOW) {1028errln("Day of week should be " + expectedDOW1029+ " instead of " + newDOW + " on " + cur.getTime());1030return;1031}1032} while (newDOW != initialDOW);1033}10341035public void TestActualMinMax() {1036Calendar cal = new GregorianCalendar(1967, MARCH, 10);1037cal.setFirstDayOfWeek(SUNDAY);1038cal.setMinimalDaysInFirstWeek(3);10391040if (cal.getActualMinimum(DAY_OF_MONTH) != 1) {1041errln("Actual minimum date for 3/10/1967 should have been 1; got "1042+ cal.getActualMinimum(DAY_OF_MONTH));1043}1044if (cal.getActualMaximum(DAY_OF_MONTH) != 31) {1045errln("Actual maximum date for 3/10/1967 should have been 31; got "1046+ cal.getActualMaximum(DAY_OF_MONTH));1047}10481049cal.set(MONTH, FEBRUARY);1050if (cal.getActualMaximum(DAY_OF_MONTH) != 28) {1051errln("Actual maximum date for 2/10/1967 should have been 28; got "1052+ cal.getActualMaximum(DAY_OF_MONTH));1053}1054if (cal.getActualMaximum(DAY_OF_YEAR) != 365) {1055errln("Number of days in 1967 should have been 365; got "1056+ cal.getActualMaximum(DAY_OF_YEAR));1057}10581059cal.set(YEAR, 1968);1060if (cal.getActualMaximum(DAY_OF_MONTH) != 29) {1061errln("Actual maximum date for 2/10/1968 should have been 29; got "1062+ cal.getActualMaximum(DAY_OF_MONTH));1063}1064if (cal.getActualMaximum(DAY_OF_YEAR) != 366) {1065errln("Number of days in 1968 should have been 366; got "1066+ cal.getActualMaximum(DAY_OF_YEAR));1067}1068// Using week settings of SUNDAY/3 (see above)1069if (cal.getActualMaximum(WEEK_OF_YEAR) != 52) {1070errln("Number of weeks in 1968 should have been 52; got "1071+ cal.getActualMaximum(WEEK_OF_YEAR));1072}10731074cal.set(YEAR, 1976);1075// Using week settings of SUNDAY/3 (see above)1076if (cal.getActualMaximum(WEEK_OF_YEAR) != 53) {1077errln("Number of weeks in 1976 should have been 53; got "1078+ cal.getActualMaximum(WEEK_OF_YEAR));1079}1080}10811082public void TestRoll() {1083Calendar cal = new GregorianCalendar(1997, JANUARY, 31);10841085int[] dayValues = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31};10861087for (int i = 0; i < dayValues.length; i++) {1088Calendar cal2 = (Calendar) cal.clone();1089cal2.roll(MONTH, i);1090if (cal2.get(DAY_OF_MONTH) != dayValues[i]) {1091errln("Rolling the month in 1/31/1997 up by " + i + " should have yielded "1092+ ((i + 1) % 12) + "/" + dayValues[i] + "/1997, but actually yielded "1093+ ((i + 1) % 12) + "/" + cal2.get(DAY_OF_MONTH) + "/1997.");1094}1095}10961097cal.set(1996, FEBRUARY, 29);10981099int[] monthValues = {1, 2, 2, 2, 1, 2, 2, 2, 1, 2};1100int[] dayValues2 = {29, 1, 1, 1, 29, 1, 1, 1, 29, 1};11011102for (int i = 0; i < dayValues2.length; i++) {1103Calendar cal2 = (Calendar) cal.clone();1104cal2.roll(YEAR, i);1105if (cal2.get(DAY_OF_MONTH) != dayValues2[i] || cal2.get(MONTH)1106!= monthValues[i]) {1107errln("Rolling the year in 2/29/1996 up by " + i + " should have yielded "1108+ (monthValues[i] + 1) + "/" + dayValues2[i] + "/"1109+ (1996 + i) + ", but actually yielded "1110+ (cal2.get(MONTH) + 1) + "/"1111+ cal2.get(DAY_OF_MONTH) + "/" + (1996 + i) + ".");1112}1113}11141115// Test rolling hour of day1116cal.set(HOUR_OF_DAY, 0);1117cal.roll(HOUR_OF_DAY, -2);1118int f = cal.get(HOUR_OF_DAY);1119if (f != 22) {1120errln("Rolling HOUR_OF_DAY=0 delta=-2 gave " + f + " Wanted 22");1121}1122cal.roll(HOUR_OF_DAY, 5);1123f = cal.get(HOUR_OF_DAY);1124if (f != 3) {1125errln("Rolling HOUR_OF_DAY=22 delta=5 gave " + f + " Wanted 3");1126}1127cal.roll(HOUR_OF_DAY, 21);1128f = cal.get(HOUR_OF_DAY);1129if (f != 0) {1130errln("Rolling HOUR_OF_DAY=3 delta=21 gave " + f + " Wanted 0");1131}11321133// Test rolling hour1134cal.set(HOUR_OF_DAY, 0);1135cal.roll(HOUR, -2);1136f = cal.get(HOUR);1137if (f != 10) {1138errln("Rolling HOUR=0 delta=-2 gave " + f + " Wanted 10");1139}1140cal.roll(HOUR, 5);1141f = cal.get(HOUR);1142if (f != 3) {1143errln("Rolling HOUR=10 delta=5 gave " + f + " Wanted 3");1144}1145cal.roll(HOUR, 9);1146f = cal.get(HOUR);1147if (f != 0) {1148errln("Rolling HOUR=3 delta=9 gave " + f + " Wanted 0");1149}1150}11511152/*1153* Confirm that multiple calls to Calendar.set() works correctly.1154*/1155public void Test4374886() {1156Locale savedLocale = Locale.getDefault();1157TimeZone savedTimeZone = TimeZone.getDefault();11581159try {1160Locale.setDefault(Locale.US);1161TimeZone.setDefault(TimeZone.getTimeZone("PST"));11621163Calendar cal = Calendar.getInstance();1164cal.set(YEAR, 2001);1165cal.set(MONTH, OCTOBER);1166cal.set(WEEK_OF_YEAR, 4);1167cal.set(DAY_OF_WEEK, 2);11681169if (cal.get(YEAR) != 20011170|| cal.get(MONTH) != JANUARY1171|| cal.get(DATE) != 221172|| cal.get(DAY_OF_WEEK) != MONDAY) {1173errln("Failed : got " + cal.getTime() + ", expected Mon Jan 22, 2001");1174}1175} finally {1176Locale.setDefault(savedLocale);1177TimeZone.setDefault(savedTimeZone);1178}1179}11801181public void TestClonedSharedZones() throws NoSuchFieldException, IllegalAccessException {1182Field zone = Calendar.class.getDeclaredField("zone");1183zone.setAccessible(true);1184Field sharedZone = Calendar.class.getDeclaredField("sharedZone");1185sharedZone.setAccessible(true);11861187// create a new calendar with any date, and clone it.1188Calendar c1 = new GregorianCalendar();1189Calendar c2 = (Calendar) c1.clone();11901191// c1 should have a shared zone1192if (!sharedZone.getBoolean(c1)) {1193errln("Failed : c1.sharedZone == false");1194} else {1195// c2 should have a shared zone too1196if (!sharedZone.getBoolean(c2)) {1197errln("Failed : c2.sharedZone == false");1198} else if (zone.get(c1) != zone.get(c2)) {1199errln("Failed : c1.zone != c2.zone");1200}1201}1202}1203}12041205//eof120612071208