Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/util/TimeZone/TimeZoneTest.java
38821 views
/*1* Copyright (c) 1997, 2019, 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 4028006 4044013 4096694 4107276 4107570 4112869 4130885 7039469 7126465 715848326* 8008577 8077685 8098547 8133321 8138716 8148446 8151876 822846927* @library /java/text/testlib28* @summary test TimeZone29*/3031import java.io.*;32import java.text.*;33import java.util.*;34import sun.util.resources.LocaleData;3536public class TimeZoneTest extends IntlTest37{38static final int millisPerHour = 3600000;3940public static void main(String[] args) throws Exception {41new TimeZoneTest().run(args);42}4344/**45* Bug 413088546* Certain short zone IDs, used since 1.1.x, are incorrect.47*48* The worst of these is:49*50* "CAT" (Central African Time) should be GMT+2:00, but instead returns a51* zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,52* or AZOST, depending on which zone is meant, but in no case is it CAT.53*54* Other wrong zone IDs:55*56* ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,57* GMT-5:00. European Central time is abbreviated CEST.58*59* SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,60* GMT-11:00. Solomon Island time is SBT.61*62* NST (New Zealand Time) GMT+12:00. NST is the abbreviation for63* Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.64*65* AST (Alaska Standard Time) GMT-9:00. [This has already been noted in66* another bug.] It should be "AKST". AST is Atlantic Standard Time,67* GMT-4:00.68*69* PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,70* GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct71* from MST with daylight savings.72*73* In addition to these problems, a number of zones are FAKE. That is, they74* don't match what people use in the real world.75*76* FAKE zones:77*78* EET (should be EEST)79* ART (should be EET)80* MET (should be IRST)81* NET (should be AMST)82* PLT (should be PKT)83* BST (should be BDT)84* VST (should be ICT)85* CTT (should be CST) +86* ACT (should be CST) +87* AET (should be EST) +88* MIT (should be WST) +89* IET (should be EST) +90* PRT (should be AST) +91* CNT (should be NST)92* AGT (should be ARST)93* BET (should be EST) +94*95* + A zone with the correct name already exists and means something96* else. E.g., EST usually indicates the US Eastern zone, so it cannot be97* used for Brazil (BET).98*/99public void TestShortZoneIDs() throws Exception {100101ZoneDescriptor[] JDK_116_REFERENCE_LIST = {102new ZoneDescriptor("MIT", 780, true),103new ZoneDescriptor("HST", -600, false),104new ZoneDescriptor("AST", -540, true),105new ZoneDescriptor("PST", -480, true),106new ZoneDescriptor("PNT", -420, false),107new ZoneDescriptor("MST", -420, false),108new ZoneDescriptor("CST", -360, true),109new ZoneDescriptor("IET", -300, true),110new ZoneDescriptor("EST", -300, false),111new ZoneDescriptor("PRT", -240, false),112new ZoneDescriptor("CNT", -210, true),113new ZoneDescriptor("AGT", -180, false),114new ZoneDescriptor("BET", -180, false),115// new ZoneDescriptor("CAT", -60, false), // Wrong:116// As of bug 4130885, fix CAT (Central Africa)117new ZoneDescriptor("CAT", 120, false), // Africa/Harare118new ZoneDescriptor("GMT", 0, false),119new ZoneDescriptor("UTC", 0, false),120new ZoneDescriptor("ECT", 60, true),121new ZoneDescriptor("ART", 120, false),122new ZoneDescriptor("EET", 120, true),123new ZoneDescriptor("EAT", 180, false),124new ZoneDescriptor("MET", 60, true),125new ZoneDescriptor("NET", 240, false),126new ZoneDescriptor("PLT", 300, false),127new ZoneDescriptor("IST", 330, false),128new ZoneDescriptor("BST", 360, false),129new ZoneDescriptor("VST", 420, false),130new ZoneDescriptor("CTT", 480, false),131new ZoneDescriptor("JST", 540, false),132new ZoneDescriptor("ACT", 570, false),133new ZoneDescriptor("AET", 600, true),134new ZoneDescriptor("SST", 660, false),135// new ZoneDescriptor("NST", 720, false),136// As of bug 4130885, fix NST (New Zealand)137new ZoneDescriptor("NST", 720, true), // Pacific/Auckland138};139140Map<String, ZoneDescriptor> hash = new HashMap<>();141142String[] ids = TimeZone.getAvailableIDs();143for (String id : ids) {144if (id.length() == 3) {145hash.put(id, new ZoneDescriptor(TimeZone.getTimeZone(id)));146}147}148149for (int i = 0; i < JDK_116_REFERENCE_LIST.length; ++i) {150ZoneDescriptor referenceZone = JDK_116_REFERENCE_LIST[i];151ZoneDescriptor currentZone = hash.get(referenceZone.getID());152if (referenceZone.equals(currentZone)) {153logln("ok " + referenceZone);154}155else {156errln("Fail: Expected " + referenceZone +157"; got " + currentZone);158}159}160}161162/**163* A descriptor for a zone; used to regress the short zone IDs.164*/165static class ZoneDescriptor {166String id;167int offset; // In minutes168boolean daylight;169170ZoneDescriptor(TimeZone zone) {171this.id = zone.getID();172this.offset = zone.getRawOffset() / 60000;173this.daylight = zone.useDaylightTime();174}175176ZoneDescriptor(String id, int offset, boolean daylight) {177this.id = id;178this.offset = offset;179this.daylight = daylight;180}181182public String getID() { return id; }183184@Override185public boolean equals(Object o) {186ZoneDescriptor that = (ZoneDescriptor)o;187return that != null &&188id.equals(that.id) &&189offset == that.offset &&190daylight == that.daylight;191}192193@Override194public int hashCode() {195return id.hashCode() ^ offset | (daylight ? 1 : 0);196}197198@Override199public String toString() {200int min = offset;201char sign = '+';202if (min < 0) { sign = '-'; min = -min; }203204return "Zone[\"" + id + "\", GMT" + sign + (min/60) + ':' +205(min%60<10?"0":"") + (min%60) + ", " +206(daylight ? "Daylight" : "Standard") + "]";207}208209public static int compare(Object o1, Object o2) {210ZoneDescriptor i1 = (ZoneDescriptor)o1;211ZoneDescriptor i2 = (ZoneDescriptor)o2;212if (i1.offset > i2.offset) return 1;213if (i1.offset < i2.offset) return -1;214if (i1.daylight && !i2.daylight) return 1;215if (!i1.daylight && i2.daylight) return -1;216return i1.id.compareTo(i2.id);217}218}219220static final String formatMinutes(int min) {221char sign = '+';222if (min < 0) { sign = '-'; min = -min; }223int h = min/60;224min = min%60;225return "" + sign + h + ":" + ((min<10) ? "0" : "") + min;226}227/**228* As part of the VM fix (see CCC approved RFE 4028006, bug229* 4044013), TimeZone.getTimeZone() has been modified to recognize230* generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and231* GMT[+-]hh. Test this behavior here.232*233* Bug 4044013234*235* ID "Custom" is no longer used for TimeZone objects created with236* a custom time zone ID, such as "GMT-8". See 4322313.237*/238public void TestCustomParse() throws Exception {239Object[] DATA = {240// ID Expected offset in minutes241"GMT", null,242"GMT+0", new Integer(0),243"GMT+1", new Integer(60),244"GMT-0030", new Integer(-30),245"GMT+15:99", null,246"GMT+", null,247"GMT-", null,248"GMT+0:", null,249"GMT-:", null,250"GMT+0010", new Integer(10), // Interpret this as 00:10251"GMT-10", new Integer(-10*60),252"GMT+30", null,253"GMT-3:30", new Integer(-(3*60+30)),254"GMT-230", new Integer(-(2*60+30)),255};256for (int i=0; i<DATA.length; i+=2) {257String id = (String)DATA[i];258Integer exp = (Integer)DATA[i+1];259TimeZone zone = TimeZone.getTimeZone(id);260if (zone.getID().equals("GMT")) {261logln(id + " -> generic GMT");262// When TimeZone.getTimeZone() can't parse the id, it263// returns GMT -- a dubious practice, but required for264// backward compatibility.265if (exp != null) {266throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +267" for " + id + ", got parse failure");268}269}270else {271int ioffset = zone.getRawOffset()/60000;272String offset = formatMinutes(ioffset);273logln(id + " -> " + zone.getID() + " GMT" + offset);274if (exp == null) {275throw new Exception("Expected parse failure for " + id +276", got offset of " + offset +277", id " + zone.getID());278}279else if (ioffset != exp.intValue()) {280throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +281", id Custom, for " + id +282", got offset of " + offset +283", id " + zone.getID());284}285}286}287}288289/**290* Test the basic functionality of the getDisplayName() API.291*292* Bug 4112869293* Bug 4028006294*295* See also API change request A41.296*297* 4/21/98 - make smarter, so the test works if the ext resources298* are present or not.299*/300public void TestDisplayName() {301TimeZone zone = TimeZone.getTimeZone("PST");302String name = zone.getDisplayName(Locale.ENGLISH);303logln("PST->" + name);304if (!name.equals("Pacific Standard Time"))305errln("Fail: Expected \"Pacific Standard Time\"");306307//*****************************************************************308// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES309// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES310// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES311//*****************************************************************312Object[] DATA = {313new Boolean(false), new Integer(TimeZone.SHORT), "PST",314new Boolean(true), new Integer(TimeZone.SHORT), "PDT",315new Boolean(false), new Integer(TimeZone.LONG), "Pacific Standard Time",316new Boolean(true), new Integer(TimeZone.LONG), "Pacific Daylight Time",317};318319for (int i=0; i<DATA.length; i+=3) {320name = zone.getDisplayName(((Boolean)DATA[i]).booleanValue(),321((Integer)DATA[i+1]).intValue(),322Locale.ENGLISH);323if (!name.equals(DATA[i+2]))324errln("Fail: Expected " + DATA[i+2] + "; got " + name);325}326327// Make sure that we don't display the DST name by constructing a fake328// PST zone that has DST all year long.329SimpleTimeZone zone2 = new SimpleTimeZone(0, "PST");330zone2.setStartRule(Calendar.JANUARY, 1, 0);331zone2.setEndRule(Calendar.DECEMBER, 31, 0);332logln("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date()));333name = zone2.getDisplayName(Locale.ENGLISH);334logln("Modified PST->" + name);335if (!name.equals("Pacific Standard Time"))336errln("Fail: Expected \"Pacific Standard Time\"");337338// Make sure we get the default display format for Locales339// with no display name data.340Locale zh_CN = Locale.SIMPLIFIED_CHINESE;341name = zone.getDisplayName(zh_CN);342//*****************************************************************343// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES344// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES345// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES346//*****************************************************************347logln("PST(zh_CN)->" + name);348349// Now be smart -- check to see if zh resource is even present.350// If not, we expect the en fallback behavior.351ResourceBundle enRB = LocaleData.getBundle("sun.util.resources.TimeZoneNames",352Locale.ENGLISH);353ResourceBundle zhRB = LocaleData.getBundle("sun.util.resources.TimeZoneNames",354zh_CN);355356boolean noZH = enRB == zhRB;357358if (noZH) {359logln("Warning: Not testing the zh_CN behavior because resource is absent");360if (!name.equals("Pacific Standard Time"))361errln("Fail: Expected Pacific Standard Time");362}363else if (!name.equals("Pacific Standard Time") &&364!name.equals("\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4") &&365!name.equals("GMT-08:00") &&366!name.equals("GMT-8:00") &&367!name.equals("GMT-0800") &&368!name.equals("GMT-800")) {369errln("Fail: Expected GMT-08:00 or something similar");370errln("************************************************************");371errln("THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED");372errln("************************************************************");373}374375// Now try a non-existent zone376zone2 = new SimpleTimeZone(90*60*1000, "xyzzy");377name = zone2.getDisplayName(Locale.ENGLISH);378logln("GMT+90min->" + name);379if (!name.equals("GMT+01:30") &&380!name.equals("GMT+1:30") &&381!name.equals("GMT+0130") &&382!name.equals("GMT+130"))383errln("Fail: Expected GMT+01:30 or something similar");384}385386public void TestGenericAPI() {387String id = "NewGMT";388int offset = 12345;389390SimpleTimeZone zone = new SimpleTimeZone(offset, id);391if (zone.useDaylightTime()) {392errln("FAIL: useDaylightTime should return false");393}394395TimeZone zoneclone = (TimeZone)zone.clone();396if (!zoneclone.equals(zone)) {397errln("FAIL: clone or operator== failed");398}399zoneclone.setID("abc");400if (zoneclone.equals(zone)) {401errln("FAIL: clone or operator!= failed");402}403404zoneclone = (TimeZone)zone.clone();405if (!zoneclone.equals(zone)) {406errln("FAIL: clone or operator== failed");407}408zoneclone.setRawOffset(45678);409if (zoneclone.equals(zone)) {410errln("FAIL: clone or operator!= failed");411}412413TimeZone saveDefault = TimeZone.getDefault();414try {415TimeZone.setDefault(zone);416TimeZone defaultzone = TimeZone.getDefault();417if (defaultzone == zone) {418errln("FAIL: Default object is identical, not clone");419}420if (!defaultzone.equals(zone)) {421errln("FAIL: Default object is not equal");422}423}424finally {425TimeZone.setDefault(saveDefault);426}427}428429@SuppressWarnings("deprecation")430public void TestRuleAPI()431{432// ErrorCode status = ZERO_ERROR;433434int offset = (int)(60*60*1000*1.75); // Pick a weird offset435SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone");436if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");437438// Establish our expected transition times. Do this with a non-DST439// calendar with the (above) declared local offset.440GregorianCalendar gc = new GregorianCalendar(zone);441gc.clear();442gc.set(1990, Calendar.MARCH, 1);443long marchOneStd = gc.getTime().getTime(); // Local Std time midnight444gc.clear();445gc.set(1990, Calendar.JULY, 1);446long julyOneStd = gc.getTime().getTime(); // Local Std time midnight447448// Starting and ending hours, WALL TIME449int startHour = (int)(2.25 * 3600000);450int endHour = (int)(3.5 * 3600000);451452zone.setStartRule(Calendar.MARCH, 1, 0, startHour);453zone.setEndRule (Calendar.JULY, 1, 0, endHour);454455gc = new GregorianCalendar(zone);456// if (failure(status, "new GregorianCalendar")) return;457458long marchOne = marchOneStd + startHour;459long julyOne = julyOneStd + endHour - 3600000; // Adjust from wall to Std time460461long expMarchOne = 636251400000L;462if (marchOne != expMarchOne)463{464errln("FAIL: Expected start computed as " + marchOne +465" = " + new Date(marchOne));466logln(" Should be " + expMarchOne +467" = " + new Date(expMarchOne));468}469470long expJulyOne = 646793100000L;471if (julyOne != expJulyOne)472{473errln("FAIL: Expected start computed as " + julyOne +474" = " + new Date(julyOne));475logln(" Should be " + expJulyOne +476" = " + new Date(expJulyOne));477}478479testUsingBinarySearch(zone, new Date(90, Calendar.JANUARY, 1).getTime(),480new Date(90, Calendar.JUNE, 15).getTime(), marchOne);481testUsingBinarySearch(zone, new Date(90, Calendar.JUNE, 1).getTime(),482new Date(90, Calendar.DECEMBER, 31).getTime(), julyOne);483484if (zone.inDaylightTime(new Date(marchOne - 1000)) ||485!zone.inDaylightTime(new Date(marchOne)))486errln("FAIL: Start rule broken");487if (!zone.inDaylightTime(new Date(julyOne - 1000)) ||488zone.inDaylightTime(new Date(julyOne)))489errln("FAIL: End rule broken");490491zone.setStartYear(1991);492if (zone.inDaylightTime(new Date(marchOne)) ||493zone.inDaylightTime(new Date(julyOne - 1000)))494errln("FAIL: Start year broken");495496// failure(status, "TestRuleAPI");497// delete gc;498// delete zone;499}500501void testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedBoundary)502{503// ErrorCode status = ZERO_ERROR;504boolean startsInDST = tz.inDaylightTime(new Date(min));505// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;506if (tz.inDaylightTime(new Date(max)) == startsInDST) {507logln("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST));508return;509}510// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;511while ((max - min) > INTERVAL) {512long mid = (min + max) / 2;513if (tz.inDaylightTime(new Date(mid)) == startsInDST) {514min = mid;515}516else {517max = mid;518}519// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;520}521logln("Binary Search Before: " + min + " = " + new Date(min));522logln("Binary Search After: " + max + " = " + new Date(max));523long mindelta = expectedBoundary - min;524long maxdelta = max - expectedBoundary;525if (mindelta >= 0 &&526mindelta <= INTERVAL &&527mindelta >= 0 &&528mindelta <= INTERVAL)529logln("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));530else531errln("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));532}533534static final int INTERVAL = 100;535536// Bug 006; verify the offset for a specific zone.537public void TestPRTOffset()538{539TimeZone tz = TimeZone.getTimeZone( "PRT" );540if( tz == null ) {541errln( "FAIL: TimeZone(PRT) is null" );542}543else{544if (tz.getRawOffset() != (-4*millisPerHour))545errln("FAIL: Offset for PRT should be -4");546}547548}549550// Test various calls551@SuppressWarnings("deprecation")552public void TestVariousAPI518()553{554TimeZone time_zone = TimeZone.getTimeZone("PST");555Date d = new Date(97, Calendar.APRIL, 30);556557logln("The timezone is " + time_zone.getID());558559if (time_zone.inDaylightTime(d) != true)560errln("FAIL: inDaylightTime returned false");561562if (time_zone.useDaylightTime() != true)563errln("FAIL: useDaylightTime returned false");564565if (time_zone.getRawOffset() != -8*millisPerHour)566errln( "FAIL: getRawOffset returned wrong value");567568GregorianCalendar gc = new GregorianCalendar();569gc.setTime(d);570if (time_zone.getOffset(gc.AD, gc.get(gc.YEAR), gc.get(gc.MONTH),571gc.get(gc.DAY_OF_MONTH),572gc.get(gc.DAY_OF_WEEK), 0)573!= -7*millisPerHour)574errln("FAIL: getOffset returned wrong value");575}576577// Test getAvailableID API578public void TestGetAvailableIDs913()579{580StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { ");581String[] s = TimeZone.getAvailableIDs();582for (int i=0; i<s.length; ++i)583{584if (i > 0) buf.append(", ");585buf.append(s[i]);586}587buf.append(" };");588logln(buf.toString());589590buf.setLength(0);591buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { ");592s = TimeZone.getAvailableIDs(+2 * 60 * 60 * 1000);593for (int i=0; i<s.length; ++i)594{595if (i > 0) buf.append(", ");596buf.append(s[i]);597}598buf.append(" };");599logln(buf.toString());600601TimeZone tz = TimeZone.getTimeZone("PST");602if (tz != null)603logln("getTimeZone(PST) = " + tz.getID());604else605errln("FAIL: getTimeZone(PST) = null");606607tz = TimeZone.getTimeZone("America/Los_Angeles");608if (tz != null)609logln("getTimeZone(America/Los_Angeles) = " + tz.getID());610else611errln("FAIL: getTimeZone(PST) = null");612613// Bug 4096694614tz = TimeZone.getTimeZone("NON_EXISTENT");615if (tz == null)616errln("FAIL: getTimeZone(NON_EXISTENT) = null");617else if (!tz.getID().equals("GMT"))618errln("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID());619}620621/**622* Bug 4107276623*/624public void TestDSTSavings() {625// It might be better to find a way to integrate this test into the main TimeZone626// tests above, but I don't have time to figure out how to do this (or if it's627// even really a good idea). Let's consider that a future. --rtg 1/27/98628SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "dstSavingsTest",629Calendar.MARCH, 1, 0, 0, Calendar.SEPTEMBER, 1, 0, 0,630(int)(0.5 * millisPerHour));631632if (tz.getRawOffset() != -5 * millisPerHour)633errln("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) +634" hours instead of -5 hours.");635if (!tz.useDaylightTime())636errln("Test time zone should use DST but claims it doesn't.");637if (tz.getDSTSavings() != 0.5 * millisPerHour)638errln("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() /639millisPerHour) + " hours instead.");640641int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,642Calendar.THURSDAY, 10 * millisPerHour);643if (offset != -5 * millisPerHour)644errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "645+ (offset / millisPerHour) + " hours.");646647offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,64810 * millisPerHour);649if (offset != -4.5 * millisPerHour)650errln("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got "651+ (offset / millisPerHour) + " hours.");652653tz.setDSTSavings(millisPerHour);654offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,655Calendar.THURSDAY, 10 * millisPerHour);656if (offset != -5 * millisPerHour)657errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "658+ (offset / millisPerHour) + " hours.");659660offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,66110 * millisPerHour);662if (offset != -4 * millisPerHour)663errln("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got "664+ (offset / millisPerHour) + " hours.");665}666667/**668* Bug 4107570669*/670public void TestAlternateRules() {671// Like TestDSTSavings, this test should probably be integrated somehow with the main672// test at the top of this class, but I didn't have time to figure out how to do that.673// --rtg 1/28/98674675SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "alternateRuleTest");676677// test the day-of-month API678tz.setStartRule(Calendar.MARCH, 10, 12 * millisPerHour);679tz.setEndRule(Calendar.OCTOBER, 20, 12 * millisPerHour);680681int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5,682Calendar.THURSDAY, 10 * millisPerHour);683if (offset != -5 * millisPerHour)684errln("The offset for 10AM, 3/5/98 should have been -5 hours, but we got "685+ (offset / millisPerHour) + " hours.");686687offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15,688Calendar.SUNDAY, 10 * millisPerHour);689if (offset != -4 * millisPerHour)690errln("The offset for 10AM, 3/15/98 should have been -4 hours, but we got "691+ (offset / millisPerHour) + " hours.");692693offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,694Calendar.THURSDAY, 10 * millisPerHour);695if (offset != -4 * millisPerHour)696errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "697+ (offset / millisPerHour) + " hours.");698699offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25,700Calendar.SUNDAY, 10 * millisPerHour);701if (offset != -5 * millisPerHour)702errln("The offset for 10AM, 10/25/98 should have been -5 hours, but we got "703+ (offset / millisPerHour) + " hours.");704705// test the day-of-week-after-day-in-month API706tz.setStartRule(Calendar.MARCH, 10, Calendar.FRIDAY, 12 * millisPerHour, true);707tz.setEndRule(Calendar.OCTOBER, 20, Calendar.FRIDAY, 12 * millisPerHour, false);708709offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11,710Calendar.WEDNESDAY, 10 * millisPerHour);711if (offset != -5 * millisPerHour)712errln("The offset for 10AM, 3/11/98 should have been -5 hours, but we got "713+ (offset / millisPerHour) + " hours.");714715offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14,716Calendar.SATURDAY, 10 * millisPerHour);717if (offset != -4 * millisPerHour)718errln("The offset for 10AM, 3/14/98 should have been -4 hours, but we got "719+ (offset / millisPerHour) + " hours.");720721offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,722Calendar.THURSDAY, 10 * millisPerHour);723if (offset != -4 * millisPerHour)724errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "725+ (offset / millisPerHour) + " hours.");726727offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17,728Calendar.SATURDAY, 10 * millisPerHour);729if (offset != -5 * millisPerHour)730errln("The offset for 10AM, 10/17/98 should have been -5 hours, but we got "731+ (offset / millisPerHour) + " hours.");732}733}734735//eof736737738