1 /* 2 ******************************************************************************* 3 * Copyright (C) 2007-2008, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.dev.test.timezone; 8 9 import java.util.Date; 10 11 import com.ibm.icu.dev.test.TestFmwk; 12 import com.ibm.icu.text.DateFormat; 13 import com.ibm.icu.util.AnnualTimeZoneRule; 14 import com.ibm.icu.util.BasicTimeZone; 15 import com.ibm.icu.util.Calendar; 16 import com.ibm.icu.util.DateTimeRule; 17 import com.ibm.icu.util.GregorianCalendar; 18 import com.ibm.icu.util.InitialTimeZoneRule; 19 import com.ibm.icu.util.RuleBasedTimeZone; 20 import com.ibm.icu.util.SimpleTimeZone; 21 import com.ibm.icu.util.TimeZone; 22 23 /** 24 * Testing getOffset APIs using local time 25 */ 26 public class TimeZoneOffsetLocalTest extends TestFmwk { 27 main(String[] args)28 public static void main(String[] args) throws Exception { 29 new TimeZoneOffsetLocalTest().run(args); 30 } 31 32 /* 33 * Testing getOffset APIs around rule transition by local standard/wall time. 34 */ TestGetOffsetAroundTransition()35 public void TestGetOffsetAroundTransition() { 36 final int HOUR = 60*60*1000; 37 final int MINUTE = 60*1000; 38 39 int[][] DATES = { 40 {2006, Calendar.APRIL, 2, 1, 30, 1*HOUR+30*MINUTE}, 41 {2006, Calendar.APRIL, 2, 2, 00, 2*HOUR}, 42 {2006, Calendar.APRIL, 2, 2, 30, 2*HOUR+30*MINUTE}, 43 {2006, Calendar.APRIL, 2, 3, 00, 3*HOUR}, 44 {2006, Calendar.APRIL, 2, 3, 30, 3*HOUR+30*MINUTE}, 45 {2006, Calendar.OCTOBER, 29, 0, 30, 0*HOUR+30*MINUTE}, 46 {2006, Calendar.OCTOBER, 29, 1, 00, 1*HOUR}, 47 {2006, Calendar.OCTOBER, 29, 1, 30, 1*HOUR+30*MINUTE}, 48 {2006, Calendar.OCTOBER, 29, 2, 00, 2*HOUR}, 49 {2006, Calendar.OCTOBER, 29, 2, 30, 2*HOUR+30*MINUTE}, 50 }; 51 52 // Expected offsets by getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) 53 int[] OFFSETS1 = { 54 // April 2, 2006 55 -8*HOUR, 56 -7*HOUR, 57 -7*HOUR, 58 -7*HOUR, 59 -7*HOUR, 60 61 // October 29, 2006 62 -7*HOUR, 63 -8*HOUR, 64 -8*HOUR, 65 -8*HOUR, 66 -8*HOUR, 67 }; 68 69 70 // Expected offsets by getOffset(long time, boolean local, int[] offsets) with local = true 71 // or getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) 72 // with nonExistingTimeOpt = LOCAL_STD/duplicatedTimeOpt = LOCAL_STD 73 int[][] OFFSETS2 = { 74 // April 2, 2006 75 {-8*HOUR, 0}, 76 {-8*HOUR, 0}, 77 {-8*HOUR, 0}, 78 {-8*HOUR, 1*HOUR}, 79 {-8*HOUR, 1*HOUR}, 80 81 // Oct 29, 2006 82 {-8*HOUR, 1*HOUR}, 83 {-8*HOUR, 0}, 84 {-8*HOUR, 0}, 85 {-8*HOUR, 0}, 86 {-8*HOUR, 0}, 87 }; 88 89 // Expected offsets by getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) 90 // with nonExistingTimeOpt = LOCAL_DST/duplicatedTimeOpt = LOCAL_DST 91 int[][] OFFSETS3 = { 92 // April 2, 2006 93 {-8*HOUR, 0}, 94 {-8*HOUR, 1*HOUR}, 95 {-8*HOUR, 1*HOUR}, 96 {-8*HOUR, 1*HOUR}, 97 {-8*HOUR, 1*HOUR}, 98 99 // October 29, 2006 100 {-8*HOUR, 1*HOUR}, 101 {-8*HOUR, 1*HOUR}, 102 {-8*HOUR, 1*HOUR}, 103 {-8*HOUR, 0}, 104 {-8*HOUR, 0}, 105 }; 106 107 int[] offsets = new int[2]; 108 109 TimeZone utc = TimeZone.getTimeZone("UTC"); 110 Calendar cal = Calendar.getInstance(utc); 111 cal.clear(); 112 113 // Set up TimeZone objects - OlsonTimeZone, SimpleTimeZone and RuleBasedTimeZone 114 BasicTimeZone[] TESTZONES = new BasicTimeZone[3]; 115 116 TESTZONES[0] = (BasicTimeZone)TimeZone.getTimeZone("America/Los_Angeles", TimeZone.TIMEZONE_ICU); 117 TESTZONES[1] = new SimpleTimeZone(-8*HOUR, "Simple Pacific Time", 118 Calendar.APRIL, 1, Calendar.SUNDAY, 2*HOUR, 119 Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*HOUR); 120 121 InitialTimeZoneRule ir = new InitialTimeZoneRule( 122 "Pacific Standard Time", // Initial time Name 123 -8*HOUR, // Raw offset 124 0*HOUR); // DST saving amount 125 126 RuleBasedTimeZone rbPT = new RuleBasedTimeZone("Rule based Pacific Time", ir); 127 128 DateTimeRule dtr; 129 AnnualTimeZoneRule atzr; 130 final int STARTYEAR = 2000; 131 132 dtr = new DateTimeRule(Calendar.APRIL, 1, Calendar.SUNDAY, 133 2*HOUR, DateTimeRule.WALL_TIME); // 1st Sunday in April, at 2AM wall time 134 atzr = new AnnualTimeZoneRule("Pacific Daylight Time", 135 -8*HOUR /* rawOffset */, 1*HOUR /* dstSavings */, dtr, 136 STARTYEAR, AnnualTimeZoneRule.MAX_YEAR); 137 rbPT.addTransitionRule(atzr); 138 139 dtr = new DateTimeRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 140 2*HOUR, DateTimeRule.WALL_TIME); // last Sunday in October, at 2AM wall time 141 atzr = new AnnualTimeZoneRule("Pacific Standard Time", 142 -8*HOUR /* rawOffset */, 0 /* dstSavings */, dtr, 143 STARTYEAR, AnnualTimeZoneRule.MAX_YEAR); 144 rbPT.addTransitionRule(atzr); 145 146 TESTZONES[2] = rbPT; 147 148 // Calculate millis 149 long [] MILLIS = new long[DATES.length]; 150 for (int i = 0; i < DATES.length; i++) { 151 cal.clear(); 152 cal.set(DATES[i][0], DATES[i][1], DATES[i][2], DATES[i][3], DATES[i][4]); 153 MILLIS[i] = cal.getTimeInMillis(); 154 } 155 156 DateFormat df = DateFormat.getInstance(); 157 df.setTimeZone(utc); 158 159 // Test getOffset(int era, int year, int month, int day, int dayOfWeek, int millis) 160 for (int i = 0; i < TESTZONES.length; i++) { 161 for (int d = 0; d < DATES.length; d++) { 162 int offset = TESTZONES[i].getOffset(GregorianCalendar.AD, DATES[d][0], DATES[d][1], DATES[d][2], 163 Calendar.SUNDAY, DATES[d][5]); 164 if (offset != OFFSETS1[d]) { 165 errln("Bad offset returned by " + TESTZONES[i].getID() + " at " 166 + df.format(new Date(MILLIS[d])) + "(standard) - Got: " + offset + " Expected: " + OFFSETS1[d]); 167 } 168 } 169 } 170 171 // Test getOffset(long time, boolean local, int[] offsets) with local=true 172 for (int i = 0; i < TESTZONES.length; i++) { 173 for (int m = 0; m < MILLIS.length; m++) { 174 TESTZONES[i].getOffset(MILLIS[m], true, offsets); 175 if (offsets[0] != OFFSETS2[m][0] || offsets[1] != OFFSETS2[m][1]) { 176 errln("Bad offset returned by " + TESTZONES[i].getID() + " at " 177 + df.format(new Date(MILLIS[m])) + "(wall) - Got: " 178 + offsets[0] + "/" + offsets[1] 179 + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]); 180 } 181 } 182 } 183 184 // Test getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) 185 // with nonExistingTimeOpt = LOCAL_STD/duplicatedTimeOpt = LOCAL_STD 186 for (int i = 0; i < TESTZONES.length; i++) { 187 for (int m = 0; m < MILLIS.length; m++) { 188 TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_STD, BasicTimeZone.LOCAL_STD, offsets); 189 if (offsets[0] != OFFSETS2[m][0] || offsets[1] != OFFSETS2[m][1]) { 190 errln("Bad offset returned by " + TESTZONES[i].getID() + " at " 191 + df.format(new Date(MILLIS[m])) + "(wall/STD/STD) - Got: " 192 + offsets[0] + "/" + offsets[1] 193 + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]); 194 } 195 } 196 } 197 198 // Test getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) 199 // with nonExistingTimeOpt = LOCAL_DST/duplicatedTimeOpt = LOCAL_DST 200 for (int i = 0; i < TESTZONES.length; i++) { 201 for (int m = 0; m < MILLIS.length; m++) { 202 TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_DST, BasicTimeZone.LOCAL_DST, offsets); 203 if (offsets[0] != OFFSETS3[m][0] || offsets[1] != OFFSETS3[m][1]) { 204 errln("Bad offset returned by " + TESTZONES[i].getID() + " at " 205 + df.format(new Date(MILLIS[m])) + "(wall/DST/DST) - Got: " 206 + offsets[0] + "/" + offsets[1] 207 + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]); 208 } 209 } 210 } 211 212 // Test getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) 213 // with nonExistingTimeOpt = LOCAL_FORMER/duplicatedTimeOpt = LOCAL_LATTER 214 for (int i = 0; i < TESTZONES.length; i++) { 215 for (int m = 0; m < MILLIS.length; m++) { 216 TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_FORMER, BasicTimeZone.LOCAL_LATTER, offsets); 217 if (offsets[0] != OFFSETS2[m][0] || offsets[1] != OFFSETS2[m][1]) { 218 errln("Bad offset returned by " + TESTZONES[i].getID() + " at " 219 + df.format(new Date(MILLIS[m])) + "(wall/FORMER/LATTER) - Got: " 220 + offsets[0] + "/" + offsets[1] 221 + " Expected: " + OFFSETS2[m][0] + "/" + OFFSETS2[m][1]); 222 } 223 } 224 } 225 226 // Test getOffsetFromLocal(long time, int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) 227 // with nonExistingTimeOpt = LOCAL_LATTER/duplicatedTimeOpt = LOCAL_FORMER 228 for (int i = 0; i < TESTZONES.length; i++) { 229 for (int m = 0; m < MILLIS.length; m++) { 230 TESTZONES[i].getOffsetFromLocal(MILLIS[m], BasicTimeZone.LOCAL_LATTER, BasicTimeZone.LOCAL_FORMER, offsets); 231 if (offsets[0] != OFFSETS3[m][0] || offsets[1] != OFFSETS3[m][1]) { 232 errln("Bad offset returned by " + TESTZONES[i].getID() + " at " 233 + df.format(new Date(MILLIS[m])) + "(wall/LATTER/FORMER) - Got: " 234 + offsets[0] + "/" + offsets[1] 235 + " Expected: " + OFFSETS3[m][0] + "/" + OFFSETS3[m][1]); 236 } 237 } 238 } 239 } 240 } 241