--- /dev/null 2016-05-17 12:01:17.473251102 +0900 +++ new/test/java/util/TimeZone/TimeZoneRegression.java 2016-05-26 10:32:52.111565346 +0900 @@ -0,0 +1,995 @@ +/* + * Copyright (c) 1998, 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 4052967 4073209 4073215 4084933 4096952 4109314 4126678 4151406 4151429 + * 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960 + * 4966229 6433179 6851214 8007520 8008577 + * @library /java/text/testlib + * @run main/othervm -Djava.locale.providers=COMPAT,SPI TimeZoneRegression + */ + +import java.util.*; +import java.io.*; +import java.text.*; + +public class TimeZoneRegression extends IntlTest { + + public static void main(String[] args) throws Exception { + new TimeZoneRegression().run(args); + } + + public void Test4052967() { + logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***"); + String id = TimeZone.getDefault().getID(); + logln("user.timezone: " + System.getProperty("user.timezone", "")); + logln("TimeZone.getDefault().getID(): " + id); + logln(new Date().toString()); + logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***"); + } + + public void Test4073209() { + TimeZone z1 = TimeZone.getTimeZone("PST"); + TimeZone z2 = TimeZone.getTimeZone("PST"); + if (z1 == z2) { + errln("Fail: TimeZone should return clones"); + } + } + + @SuppressWarnings("deprecation") + public void Test4073215() { + SimpleTimeZone z = new SimpleTimeZone(0, "GMT"); + if (z.useDaylightTime()) { + errln("Fail: Fix test to start with non-DST zone"); + } + z.setStartRule(Calendar.FEBRUARY, 1, Calendar.SUNDAY, 0); + z.setEndRule(Calendar.MARCH, -1, Calendar.SUNDAY, 0); + if (!z.useDaylightTime()) { + errln("Fail: DST not active"); + } + if (z.inDaylightTime(new Date(97, Calendar.JANUARY, 31)) || + !z.inDaylightTime(new Date(97, Calendar.MARCH, 1)) || + z.inDaylightTime(new Date(97, Calendar.MARCH, 31))) { + errln("Fail: DST not working as expected"); + } + } + + /** + * The expected behavior of TimeZone around the boundaries is: + * (Assume transition time of 2:00 AM) + * day of onset 1:59 AM STD = display name 1:59 AM ST + * 2:00 AM STD = display name 3:00 AM DT + * day of end 0:59 AM STD = display name 1:59 AM DT + * 1:00 AM STD = display name 1:00 AM ST + */ + public void Test4084933() { + // test both SimpleTimeZone and ZoneInfo objects. + // @since 1.4 + sub4084933(getPST()); + sub4084933(TimeZone.getTimeZone("PST")); + } + + private void sub4084933(TimeZone tz) { + long offset1 = tz.getOffset(1, + 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)); + long offset2 = tz.getOffset(1, + 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)-1); + + long offset3 = tz.getOffset(1, + 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)); + long offset4 = tz.getOffset(1, + 1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)-1); + + /* + * The following was added just for consistency. It shows that going *to* Daylight + * Savings Time (PDT) does work at 2am. + */ + + long offset5 = tz.getOffset(1, + 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)); + long offset6 = tz.getOffset(1, + 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)-1); + + long offset7 = tz.getOffset(1, + 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)); + long offset8 = tz.getOffset(1, + 1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)-1); + + long SToffset = -8 * 60*60*1000L; + long DToffset = -7 * 60*60*1000L; + if (offset1 != SToffset || offset2 != SToffset || + offset3 != SToffset || offset4 != DToffset || + offset5 != DToffset || offset6 != SToffset || + offset7 != SToffset || offset8 != SToffset) + errln("Fail: TimeZone misbehaving"); { + } + } + + public void Test4096952() { + String[] ZONES = { "GMT", "MET", "IST" }; + boolean pass = true; + try { + for (int i=0; i= ONE_DAY) { + millis -= ONE_DAY; + ++date; + dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 1) % 7); + } + + tzOffset = testTZ.getOffset(testCal.get(Calendar.ERA), + testCal.get(Calendar.YEAR), + testCal.get(Calendar.MONTH), + date, + dow, + millis); + tzRawOffset = testTZ.getRawOffset(); + tzOffsetFloat = new Float((float)tzOffset/(float)3600000); + tzRawOffsetFloat = new Float((float)tzRawOffset/(float)3600000); + + Date testDate = testCal.getTime(); + + boolean inDaylightTime = testTZ.inDaylightTime(testDate); + SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm"); + sdf.setCalendar(testCal); + String inDaylightTimeString; + + boolean passed; + + if (inDaylightTime) + { + inDaylightTimeString = " DST "; + passed = (tzOffset == (tzRawOffset + 3600000)); + } + else + { + inDaylightTimeString = " "; + passed = (tzOffset == tzRawOffset); + } + + String output = testTZ.getID() + " " + sdf.format(testDate) + + " Offset(" + tzOffsetFloat + ")" + + " RawOffset(" + tzRawOffsetFloat + ")" + + " " + millis/(float)3600000 + " " + + inDaylightTimeString; + + if (passed) + output += " "; + else + output += "ERROR"; + + if (passed) logln(output); else errln(output); + return passed; + } + + /** + * CANNOT REPRODUDE + * + * Yet another _alleged_ bug in TimeZone.getOffset(), a method that never + * should have been made public. It's simply too hard to use correctly. + * + * The original test code failed to do the following: + * (1) Call Calendar.setTime() before getting the fields! + * (2) Use the right millis (as usual) for getOffset(); they were passing + * in the MILLIS field, instead of the STANDARD MILLIS IN DAY. + * When you fix these two problems, the test passes, as expected. + */ + public void Test4126678() { + // Note: this test depends on the PST time zone. + TimeZone initialZone = TimeZone.getDefault(); + + // test both SimpleTimeZone and ZoneInfo objects. + // @since 1.4 + sub4126678(getPST()); + sub4126678(TimeZone.getTimeZone("PST")); + + // restore the initial time zone so that this test case + // doesn't affect the others. + TimeZone.setDefault(initialZone); + } + + @SuppressWarnings("deprecation") + private void sub4126678(TimeZone tz) { + Calendar cal = Calendar.getInstance(); + TimeZone.setDefault(tz); + cal.setTimeZone(tz); + + Date dt = new Date(1998-1900, Calendar.APRIL, 5, 10, 0); + // the dt value is local time in PST. + if (!tz.inDaylightTime(dt)) + errln("We're not in Daylight Savings Time and we should be.\n"); + + cal.setTime(dt); + int era = cal.get(Calendar.ERA); + int year = cal.get(Calendar.YEAR); + int month = cal.get(Calendar.MONTH); + int day = cal.get(Calendar.DATE); + int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); + int millis = cal.get(Calendar.MILLISECOND) + + (cal.get(Calendar.SECOND) + + (cal.get(Calendar.MINUTE) + + (cal.get(Calendar.HOUR) * 60) * 60) * 1000) - + cal.get(Calendar.DST_OFFSET); + + long offset = tz.getOffset(era, year, month, day, dayOfWeek, millis); + long raw_offset = tz.getRawOffset(); + if (offset == raw_offset) { + errln("Offsets should not match when in DST"); + } + } + + /** + * TimeZone.getAvailableIDs(int) throws exception for certain values, + * due to a faulty constant in TimeZone.java. + */ + public void Test4151406() { + int max = 0; + for (int h=-28; h<=30; ++h) { + // h is in half-hours from GMT; rawoffset is in millis + int rawoffset = h * 1800000; + int hh = (h<0) ? -h : h; + String hname = ((h<0) ? "GMT-" : "GMT+") + + ((hh/2 < 10) ? "0" : "") + + (hh/2) + ':' + + ((hh%2==0) ? "00" : "30"); + try { + String[] ids = TimeZone.getAvailableIDs(rawoffset); + if (ids.length > max) max = ids.length; + logln(hname + ' ' + ids.length + + ((ids.length > 0) ? (" e.g. " + ids[0]) : "")); + } catch (Exception e) { + errln(hname + ' ' + "Fail: " + e); + } + } + logln("Maximum zones per offset = " + max); + } + + public void Test4151429() { + try { + TimeZone tz = TimeZone.getTimeZone("GMT"); + String name = tz.getDisplayName(true, Integer.MAX_VALUE, + Locale.getDefault()); + errln("IllegalArgumentException not thrown by TimeZone.getDisplayName()"); + } catch(IllegalArgumentException e) {} + } + + /** + * SimpleTimeZone accepts illegal DST savings values. These values + * must be non-zero. There is no upper limit at this time. + */ + public void Test4154525() { + final int GOOD = 1, BAD = 0; + int[] DATA = { + 1, GOOD, + 0, BAD, + -1, BAD, + 60*60*1000, GOOD, + Integer.MIN_VALUE, BAD, + // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time + }; + for (int i=0; i) should work but throws " + ex) + : ", ) should fail but doesn't")); + } + + ex = null; + try { + SimpleTimeZone temp = new SimpleTimeZone(0, "Z", + GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME, + month, day, dayOfWeek, time); + } catch (IllegalArgumentException e) { + ex = e; + } + if ((ex == null) != shouldBeGood) { + errln("SimpleTimeZone(, month=" + month + ", day=" + day + + ", dayOfWeek=" + dayOfWeek + ", time=" + time + + (shouldBeGood ? (") should work but throws " + ex) + : ") should fail but doesn't")); + } + } + } + + /** + * SimpleTimeZone.getOffset accepts illegal arguments. + */ + public void Test4154650() { + final int GOOD=1, BAD=0; + final int GOOD_ERA=GregorianCalendar.AD, GOOD_YEAR=1998, GOOD_MONTH=Calendar.AUGUST; + final int GOOD_DAY=2, GOOD_DOW=Calendar.SUNDAY, GOOD_TIME=16*3600000; + int[] DATA = { + GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, + + GOOD, GregorianCalendar.BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, + GOOD, GregorianCalendar.AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, + BAD, GregorianCalendar.BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, + BAD, GregorianCalendar.AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, + + GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME, + GOOD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME, + BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME, + BAD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIME, + + GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 1, GOOD_DOW, GOOD_TIME, + GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 31, GOOD_DOW, GOOD_TIME, + BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 0, GOOD_DOW, GOOD_TIME, + BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 32, GOOD_DOW, GOOD_TIME, + + GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY, GOOD_TIME, + GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY, GOOD_TIME, + BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY-1, GOOD_TIME, + BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY+1, GOOD_TIME, + + GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0, + GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1, + BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1, + BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000, + }; + + TimeZone tz = TimeZone.getDefault(); + for (int i=0; i " + DATA[i+1] + ", exp " + DATA[i+2]); + } + } + } + + /** + * SimpleTimeZone allows invalid DOM values. + */ + public void Test4184229() { + SimpleTimeZone zone = null; + try { + zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0); + errln("Failed. No exception has been thrown for DOM -1 startDay"); + } catch(IllegalArgumentException e) { + logln("(a) " + e.getMessage()); + } + try { + zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0); + errln("Failed. No exception has been thrown for DOM -1 endDay"); + } catch(IllegalArgumentException e) { + logln("(b) " + e.getMessage()); + } + try { + zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, 1000); + errln("Failed. No exception has been thrown for DOM -1 startDay +savings"); + } catch(IllegalArgumentException e) { + logln("(c) " + e.getMessage()); + } + try { + zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000); + errln("Failed. No exception has been thrown for DOM -1 endDay +savings"); + } catch(IllegalArgumentException e) { + logln("(d) " + e.getMessage()); + } + // Make a valid constructor call for subsequent tests. + zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0); + try { + zone.setStartRule(0, -1, 0, 0); + errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings"); + } catch(IllegalArgumentException e) { + logln("(e) " + e.getMessage()); + } + try { + zone.setStartRule(0, -1, 0); + errln("Failed. No exception has been thrown for DOM -1 setStartRule"); + } catch(IllegalArgumentException e) { + logln("(f) " + e.getMessage()); + } + try { + zone.setEndRule(0, -1, 0, 0); + errln("Failed. No exception has been thrown for DOM -1 setEndRule +savings"); + } catch(IllegalArgumentException e) { + logln("(g) " + e.getMessage()); + } + try { + zone.setEndRule(0, -1, 0); + errln("Failed. No exception has been thrown for DOM -1 setEndRule"); + } catch(IllegalArgumentException e) { + logln("(h) " + e.getMessage()); + } + } + + /** + * SimpleTimeZone.getOffset() throws IllegalArgumentException when to get + * of 2/29/1996 (leap day). + */ + public void Test4208960 () { + // test both SimpleTimeZone and ZoneInfo objects. + // @since 1.4 + sub4208960(getPST()); + sub4208960(TimeZone.getTimeZone("PST")); + } + + private void sub4208960(TimeZone tz) { + try { + int offset = tz.getOffset(GregorianCalendar.AD, 1996, Calendar.FEBRUARY, 29, + Calendar.THURSDAY, 0); + } catch (IllegalArgumentException e) { + errln("FAILED: to get TimeZone.getOffset(2/29/96)"); + } + try { + int offset = tz.getOffset(GregorianCalendar.AD, 1997, Calendar.FEBRUARY, 29, + Calendar.THURSDAY, 0); + errln("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception."); + } catch (IllegalArgumentException e) { + logln("got IllegalArgumentException"); + } + } + + /** + * 4966229: java.util.Date methods may works incorrect. + * sun.util.calendar.ZoneInfo doesn't clone properly. + */ + @SuppressWarnings("deprecation") + public void Test4966229() { + TimeZone savedTZ = TimeZone.getDefault(); + try { + TimeZone.setDefault(TimeZone.getTimeZone("GMT")); + Date d = new Date(2100-1900, 5, 1); // specify year >2037 + TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); + + Calendar cal = new GregorianCalendar(tz); + cal.setTime(d); + + // Change the raw offset in tz + int offset = tz.getRawOffset(); + tz.setRawOffset(0); + + TimeZone tz2 = (TimeZone) tz.clone(); + Calendar cal2 = new GregorianCalendar(tz2); + cal2.setTime(d); + int expectedHourOfDay = cal2.get(cal.HOUR_OF_DAY); + + // Restore the GMT offset in tz which shouldn't affect tz2 + tz.setRawOffset(offset); + cal2.setTime(d); + int hourOfDay = cal2.get(cal.HOUR_OF_DAY); + if (hourOfDay != expectedHourOfDay) { + errln("wrong hour of day: got: " + hourOfDay + + ", expected: " + expectedHourOfDay); + } + } finally { + TimeZone.setDefault(savedTZ); + } + } + + /** + * 6433179: (tz) Incorrect DST end for America/Winnipeg and Canada/Central in 2038+ + */ + public void Test6433179() { + // Use the old America/Winnipeg rule for testing. Note that + // startMode is WALL_TIME for testing. It's actually + // STANDARD_TIME, though. + //Rule Winn 1966 2005 - Oct lastSun 2:00s 0 S + //Rule Winn 1987 2005 - Apr Sun>=1 2:00s 1:00 D + TimeZone tz = new SimpleTimeZone(-6*ONE_HOUR, "America/Winnipeg", + Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, SimpleTimeZone.WALL_TIME, + Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, SimpleTimeZone.STANDARD_TIME, + 1*ONE_HOUR); + Calendar cal = Calendar.getInstance(tz, Locale.US); + cal.clear(); + cal.set(2039, Calendar.OCTOBER, 1); + cal.getTime(); + cal.set(cal.DAY_OF_WEEK, cal.SUNDAY); + cal.set(cal.DAY_OF_WEEK_IN_MONTH, -1); + cal.add(Calendar.HOUR_OF_DAY, 2); + if (cal.get(cal.DST_OFFSET) == 0) { + errln("Should still be in DST."); + } + } + + private static final int ONE_HOUR = 60 * 60 * 1000; + /** + * Returns an instance of SimpleTimeZone for + * "PST". (TimeZone.getTimeZone() no longer returns a + * SimpleTimeZone object.) + * @since 1.4 + */ + private SimpleTimeZone getPST() { + return new SimpleTimeZone(-8*ONE_HOUR, "PST", + Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, + Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, + 1*ONE_HOUR); + } +} +//eof