Path: blob/master/test/jdk/java/util/Calendar/CalendarLimitTest.java
41149 views
/*1* Copyright (c) 1997, 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 403366226* @summary test for limit on Calendar27* @library /java/text/testlib28* @run main CalendarLimitTest -verbose29*/3031import java.util.*;32import java.text.*;3334/**35* This test verifies the behavior of Calendar around the very earliest limits36* which it can handle. It also verifies the behavior for large values of millis.37*38* Note: There used to be a limit, due to a bug, for early times. There is39* currently no limit.40*41* March 17, 1998: Added code to make sure big + dates are big + AD years, and42* big - dates are big + BC years.43*/44public class CalendarLimitTest extends IntlTest45{46// This number determined empirically; this is the old limit,47// which we test for to make sure it isn't there anymore.48static final long EARLIEST_SUPPORTED_MILLIS = -210993120000000L;4950static final int EPOCH_JULIAN_DAY = 2440588; // Jaunary 1, 1970 (Gregorian)51static final int JAN_1_1_JULIAN_DAY = 1721426; // January 1, year 1 (Gregorian)5253// Useful millisecond constants54static final int ONE_SECOND = 1000;55static final int ONE_MINUTE = 60*ONE_SECOND;56static final int ONE_HOUR = 60*ONE_MINUTE;57static final int ONE_DAY = 24*ONE_HOUR;58static final int ONE_WEEK = 7*ONE_DAY;59static final long ONE_YEAR = (long)(365.2425 * ONE_DAY);6061static long ORIGIN; // This is the *approximate* point at which BC switches to AD6263public static void main(String argv[]) throws Exception {64Locale locale = Locale.getDefault();65if (!TestUtils.usesGregorianCalendar(locale)) {66System.out.println("Skipping this test because locale is " + locale);67return;68}6970new CalendarLimitTest().run(argv);71}7273/**74* Converts Julian day to time as milliseconds.75* @param julian the given Julian day number.76* @return time as milliseconds.77*/78private static final long julianDayToMillis(long julian) {79return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;80}8182/**83* Verify that the given time is processed without problem.84* @return the adjust year, with 0 = 1 BC, -1 = 2 BC, etc.85*/86int test(long millis, Calendar cal, DateFormat fmt)87{88Exception exception = null;89String theDate = "";90try {91Date d= new Date(millis);92cal.setTime(d);93theDate = fmt.format(d);94}95catch (IllegalArgumentException e) {96exception = e;97}98String s = "0x" + Long.toHexString(millis) + " " + theDate;99100int era=cal.get(Calendar.ERA), year=cal.get(Calendar.YEAR),101dom=cal.get(Calendar.DATE), mon=cal.get(Calendar.MONTH);102103cal.clear();104cal.set(year, mon, dom);105cal.set(Calendar.ERA, era);106Date rt = cal.getTime();107108boolean ok = true;109if (exception != null) {110errln("FAIL: Exception " + s);111ok = false;112}113if (((millis >= ORIGIN) && (era != GregorianCalendar.AD)) ||114((millis < ORIGIN) && (era != GregorianCalendar.BC)) ||115(year < 1)) {116errln("FAIL: Bad year/era " + s);117ok = false;118}119if (dom<1 || dom>31) {120errln("FAIL: Bad DOM " + s);121ok = false;122}123if (Math.abs(millis - rt.getTime()) > ONE_DAY) {124errln("FAIL: RT fail " + s + " -> 0x" +125Long.toHexString(rt.getTime()) + " " +126fmt.format(rt));127ok = false;128}129if (ok) logln(s);130if (era==GregorianCalendar.BC) year = 1-year;131return year;132}133134public void TestCalendarLimit()135{136ORIGIN = julianDayToMillis(JAN_1_1_JULIAN_DAY);137138Calendar cal = Calendar.getInstance();139// You must set the time zone to GMT+0 or the edge cases like140// Long.MIN_VALUE, Long.MAX_VALUE, and right around the threshold141// won't work, since before converting to fields the calendar code142// will add the offset for the zone.143cal.setTimeZone(TimeZone.getTimeZone("Africa/Casablanca"));144145DateFormat dateFormat = DateFormat.getDateInstance();146dateFormat.setCalendar(cal); // Make sure you do this -- same reason as above147((SimpleDateFormat)dateFormat).applyPattern("MMM d, yyyy G");148149// Don't expect any failure for positive longs150int lastYear=0;151boolean first=true;152for (long m = Long.MAX_VALUE; m > 0; m >>= 1)153{154int y = test(m, cal, dateFormat);155if (!first && y > lastYear)156errln("FAIL: Years should be decreasing " + lastYear + " " + y);157first = false;158lastYear = y;159}160161// Expect failures for negative millis below threshold162first = true;163for (long m = Long.MIN_VALUE; m < 0; m /= 2) // Don't use m >>= 1164{165int y = test(m, cal, dateFormat);166if (!first && y < lastYear)167errln("FAIL: Years should be increasing " + lastYear + " " + y);168first = false;169lastYear = y;170}171172// Test right around the threshold173test(EARLIEST_SUPPORTED_MILLIS, cal, dateFormat);174test(EARLIEST_SUPPORTED_MILLIS-1, cal, dateFormat);175176// Test a date that should work177test(Long.MIN_VALUE + ONE_DAY, cal, dateFormat);178179// Try hours in the earliest day or two180// JUST FOR DEBUGGING:181if (false) {182((SimpleDateFormat)dateFormat).applyPattern("H:mm MMM d, yyyy G");183for (int dom=2; dom<=3; ++dom) {184for (int h=0; h<24; ++h) {185cal.clear();186cal.set(Calendar.ERA, GregorianCalendar.BC);187cal.set(292269055, Calendar.DECEMBER, dom, h, 0);188Date d = cal.getTime();189cal.setTime(d);190logln("" + h + ":00 Dec "+dom+", 292269055 BC -> " +191Long.toHexString(d.getTime()) + " -> " +192dateFormat.format(cal.getTime()));193}194}195// Other way196long t = 0x80000000018c5c00L; // Dec 3, 292269055 BC197while (t<0) {198cal.setTime(new Date(t));199logln("0x" + Long.toHexString(t) + " -> " +200dateFormat.format(cal.getTime()));201t -= ONE_HOUR;202}203}204}205}206207//eof208209210