--- /dev/null 2016-05-17 12:01:17.473251102 +0900 +++ new/test/java/util/Calendar/GregorianCutoverTest.java 2016-05-26 10:32:40.759323779 +0900 @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4359204 4928615 4743587 4956232 6459836 6549953 + * @library /java/text/testlib + * @build Koyomi + * @run main GregorianCutoverTest + * @summary Unit tests related to the Gregorian cutover support. + */ + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import static java.util.GregorianCalendar.*; + +public class GregorianCutoverTest extends IntlTest { + + public static void main(String[] args) throws Exception { + TimeZone tz = TimeZone.getDefault(); + Locale lc = Locale.getDefault(); + try { + TimeZone.setDefault(TimeZone.getTimeZone("GMT")); + Locale.setDefault(Locale.US); + + new GregorianCutoverTest().run(args); + } finally { + TimeZone.setDefault(tz); + Locale.setDefault(lc); + } + } + + /** + * 4359204: GregorianCalendar.get(cal.DAY_OF_YEAR) is inconsistent for year 1582 + */ + public void Test4359204() { + Koyomi cal = new Koyomi(); + + cal.set(1582, JANUARY, 1); + checkContinuity(cal, DAY_OF_YEAR); + checkContinuity(cal, WEEK_OF_YEAR); + cal.set(1582, OCTOBER, 1); + checkContinuity(cal, WEEK_OF_MONTH); + + // JCK tests the cutover date 1970-1-1 (Epoch) + cal.setGregorianChange(new Date(0)); + cal.set(1969, JANUARY, 1); + checkContinuity(cal, DAY_OF_YEAR); + checkContinuity(cal, WEEK_OF_YEAR); + cal.set(1969, DECEMBER, 1); + checkContinuity(cal, WEEK_OF_MONTH); + cal.set(1970, JANUARY, 1); + checkContinuity(cal, DAY_OF_YEAR); + checkContinuity(cal, WEEK_OF_YEAR); + + // Use large date (year >= 50000) + cal.setGregorianChange(new Date(50000-1900, JANUARY, 20)); + cal.set(49998, JANUARY, 1); + checkContinuity(cal, DAY_OF_YEAR); + checkContinuity(cal, WEEK_OF_YEAR); + cal.set(49999, JANUARY, 1); + checkContinuity(cal, DAY_OF_YEAR); + checkContinuity(cal, WEEK_OF_YEAR); + cal.set(50000, JANUARY, 20); + checkContinuity(cal, DAY_OF_YEAR); + checkContinuity(cal, WEEK_OF_YEAR); + + // Handling of "overlapping" dates may still be incorrect as + // of 1.5. Also, there's no way to disambiguate "overlapping" + // dates. + // millis=-112033929600000: date=-1581-10-15T00:00:00.000Z + cal.setGregorianChange(new Date(-112033929600000L)); + cal.set(ERA, AD); + cal.set(-1581, JANUARY, 1); + // The year should have 379 days. + checkContinuity(cal, DAY_OF_YEAR); + checkContinuity(cal, WEEK_OF_YEAR); + + logln("Default cutover"); + cal = new Koyomi(); + cal.set(1582, OCTOBER, 1); + logln(" roll --DAY_OF_MONTH from 1582/10/01"); + cal.roll(DAY_OF_MONTH, -1); + if (!cal.checkDate(1582, OCTOBER, 31)) { + errln(cal.getMessage()); + } + logln(" roll DAY_OF_MONTH+10 from 1582/10/31"); + cal.roll(DAY_OF_MONTH, +10); + if (!cal.checkDate(1582, OCTOBER, 20)) { + errln(cal.getMessage()); + } + logln(" roll DAY_OF_MONTH-10 from 1582/10/20"); + cal.roll(DAY_OF_MONTH, -10); + if (!cal.checkDate(1582, OCTOBER, 31)) { + errln(cal.getMessage()); + } + logln(" roll back one day further"); + cal.roll(DAY_OF_MONTH, +1); + if (!cal.checkDate(1582, OCTOBER, 1)) { + errln(cal.getMessage()); + } + + // should handle the gap between 1969/12/22 (Julian) to 1970/1/5 (Gregorian) + logln("Cutover date is 1970/1/5"); + cal.setGregorianChange(new Date(1970-1900, JANUARY, 5)); + cal.set(ERA, AD); + cal.set(YEAR, 1970); + logln(" Set DAY_OF_YEAR to the 28th day of 1970"); + cal.set(DAY_OF_YEAR, 28); + if (!cal.checkDate(1970, FEBRUARY, 1)) { + errln(cal.getMessage()); + } + if (!cal.checkFieldValue(WEEK_OF_YEAR, 5)) { + errln(cal.getMessage()); + } + logln(" 1969/12/22 should be the 356th day of the year."); + cal.set(1969, DECEMBER, 22); + if (!cal.checkFieldValue(DAY_OF_YEAR, 356)) { + errln(cal.getMessage()); + } + logln(" Set DAY_OF_YEAR to autual maximum."); + int actualMaxDayOfYear = cal.getActualMaximum(DAY_OF_YEAR); + if (actualMaxDayOfYear != 356) { + errln("actual maximum of DAY_OF_YEAR: got " + actualMaxDayOfYear + ", expected 356"); + } + cal.set(DAY_OF_YEAR, actualMaxDayOfYear); + if (!cal.checkDate(1969, DECEMBER, 22)) { + errln(cal.getMessage()); + } + cal.set(1969, DECEMBER, 22); + cal.roll(DAY_OF_YEAR, +1); + logln(" Set to 1969/12/22 and roll DAY_OF_YEAR++"); + if (!cal.checkDate(1969, JANUARY, 1)) { + errln(cal.getMessage()); + } + logln(" 1970/1/5 should be the first day of the year."); + cal.set(1970, JANUARY, 5); + if (!cal.checkFieldValue(DAY_OF_YEAR, 1)) { + errln(cal.getMessage()); + } + logln(" roll --DAY_OF_MONTH from 1970/1/5"); + cal.roll(DAY_OF_MONTH, -1); + if (!cal.checkDate(1970, JANUARY, 31)) { + errln(cal.getMessage()); + } + logln(" roll back one day of month"); + cal.roll(DAY_OF_MONTH, +1); + if (!cal.checkDate(1970, JANUARY, 5)) { + errln(cal.getMessage()); + } + + // Test "missing" dates in non-lenient. + cal = new Koyomi(); // new instance for the default cutover + cal.setLenient(false); + try { + // the next day of 1582/10/4 (Julian) is 1582/10/15 (Gregorian) + logln("1582/10/10 doesn't exit with the default cutover."); + cal.set(1582, OCTOBER, 10); + cal.getTime(); + errln(" Didn't throw IllegalArgumentException in non-lenient."); + } catch (IllegalArgumentException e) { + } + } + + private void checkContinuity(Koyomi cal, int field) { + cal.getTime(); + logln(Koyomi.getFieldName(field) + " starting on " + cal.toDateString()); + int max = cal.getActualMaximum(field); + for (int i = 1; i <= max; i++) { + logln(i + " " + cal.toDateString()); + if (!cal.checkFieldValue(field, i)) { + errln(" " + cal.toDateString() + ":\t" + cal.getMessage()); + } + cal.add(field, +1); + } + } + + /** + * 4928615: GregorianCalendar returns wrong dates after setGregorianChange + */ + public void Test4928615() { + Koyomi cal = new Koyomi(); + logln("Today is 2003/10/1 Gregorian."); + Date x = new Date(2003-1900, 10-1, 1); + cal.setTime(x); + + logln(" Changing the cutover date to yesterday..."); + cal.setGregorianChange(new Date(x.getTime() - (24*3600*1000))); + if (!cal.checkDate(2003, OCTOBER, 1)) { + errln(" " + cal.getMessage()); + } + logln(" Changing the cutover date to tomorrow..."); + cal.setGregorianChange(new Date(x.getTime() + (24*3600*1000))); + if (!cal.checkDate(2003, SEPTEMBER, 18)) { + errln(" " + cal.getMessage()); + } + } + + /** + * 4743587: GregorianCalendar.getLeastMaximum() returns wrong values + */ + public void Test4743587() { + Koyomi cal = new Koyomi(); + Koyomi cal2 = (Koyomi) cal.clone(); + logln("getLeastMaximum should handle cutover year.\n" + +" default cutover date"); + if (!cal.checkLeastMaximum(DAY_OF_YEAR, 365-10)) { + errln(" " + cal.getMessage()); + } + if (!cal.checkLeastMaximum(WEEK_OF_YEAR, 52-((10+6)/7))) { + errln(" " + cal.getMessage()); + } + // Corrected for 4956232 + if (!cal.checkLeastMaximum(DAY_OF_MONTH, 28)) { + errln(" " + cal.getMessage()); + } + if (!cal.checkLeastMaximum(WEEK_OF_MONTH, 3)) { + errln(" " + cal.getMessage()); + } + if (!cal.checkLeastMaximum(DAY_OF_WEEK_IN_MONTH, 3)) { + errln(" " + cal.getMessage()); + } + // make sure that getLeastMaximum calls didn't affect the date + if (!cal.equals(cal2)) { + errln(" getLeastMaximum calls modified the object."); + } + if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 1)) { + errln(" " + cal.getMessage()); + } + + logln(" changing the date to 1582/10/20 for actual min/max tests"); + cal.set(1582, OCTOBER, 20); + if (!cal.checkActualMinimum(DAY_OF_MONTH, 1)) { + errln(" " + cal.getMessage()); + } + if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) { + errln(" " + cal.getMessage()); + } + + cal = new Koyomi(); + logln("Change the cutover date to 1970/1/5."); + cal.setGregorianChange(new Date(1970-1900, 0, 5)); + if (!cal.checkLeastMaximum(DAY_OF_YEAR, 356)) { + errln(" " + cal.getMessage()); + } + if (!cal.checkLeastMaximum(DAY_OF_MONTH, 22)) { + errln(" " + cal.getMessage()); + } + if (!cal.checkGreatestMinimum(DAY_OF_MONTH, 5)) { + errln(" " + cal.getMessage()); + } + cal.set(1970, JANUARY, 10); + if (!cal.checkActualMinimum(DAY_OF_MONTH, 5)) { + errln(" " + cal.getMessage()); + } + if (!cal.checkActualMaximum(DAY_OF_MONTH, 31)) { + errln(" " + cal.getMessage()); + } + } + + /** + * 6459836: (cal) GregorianCalendar set method provides wrong result + */ + public void Test6459836() { + int hour = 13865672; + Koyomi gc1 = new Koyomi(); + gc1.clear(); + gc1.set(1, gc1.JANUARY, 1, 0, 0, 0); + gc1.set(gc1.HOUR_OF_DAY, hour); + if (!gc1.checkDate(1582, gc1.OCTOBER, 4)) { + errln("test case 1: " + gc1.getMessage()); + } + gc1.clear(); + gc1.set(1, gc1.JANUARY, 1, 0, 0, 0); + gc1.set(gc1.HOUR_OF_DAY, hour + 24); + if (!gc1.checkDate(1582, gc1.OCTOBER, 15)) { + errln("test case 2: " + gc1.getMessage()); + } + } + + /** + * 6549953 (cal) WEEK_OF_YEAR and DAY_OF_YEAR calculation problems around Gregorian cutover + */ + public void Test6549953() { + Koyomi cal = new Koyomi(); + + cal.set(YEAR, 1582); + cal.set(WEEK_OF_YEAR, 42); + cal.set(DAY_OF_WEEK, FRIDAY); + cal.checkFieldValue(WEEK_OF_YEAR, 42); + cal.checkFieldValue(DAY_OF_WEEK, FRIDAY); + if (!cal.checkDate(1582, OCTOBER, 29)) { + errln(cal.getMessage()); + } + cal.clear(); + cal.set(1582, OCTOBER, 1); + cal.set(DAY_OF_YEAR, 292); + if (!cal.checkDate(1582, OCTOBER, 29)) { + errln(cal.getMessage()); + } + } +}