]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneRegression.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / tests / core / src / com / ibm / icu / dev / test / timezone / TimeZoneRegression.java
1 /**\r
2  *******************************************************************************\r
3  * Copyright (C) 2000-2010, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 /**\r
9  * @test 1.18 99/09/21\r
10  * @bug 4052967 4073209 4073215 4084933 4096952 4109314 4126678 4151406 4151429\r
11  * @bug 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960\r
12  */\r
13 \r
14 package com.ibm.icu.dev.test.timezone;\r
15 import java.io.ByteArrayInputStream;\r
16 import java.io.ByteArrayOutputStream;\r
17 import java.io.IOException;\r
18 import java.io.ObjectInputStream;\r
19 import java.io.ObjectOutputStream;\r
20 import java.security.AccessControlException;\r
21 import java.util.Date;\r
22 import java.util.Locale;\r
23 \r
24 import com.ibm.icu.dev.test.TestFmwk;\r
25 import com.ibm.icu.text.DateFormat;\r
26 import com.ibm.icu.text.SimpleDateFormat;\r
27 import com.ibm.icu.util.Calendar;\r
28 import com.ibm.icu.util.GregorianCalendar;\r
29 import com.ibm.icu.util.SimpleTimeZone;\r
30 import com.ibm.icu.util.TimeZone;\r
31 import com.ibm.icu.util.ULocale;\r
32 \r
33 public class TimeZoneRegression extends TestFmwk {\r
34 \r
35     public static void main(String[] args) throws Exception {\r
36         new TimeZoneRegression().run(args);\r
37     }\r
38 \r
39     public void Test4052967() {\r
40         logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***");\r
41         String id = TimeZone.getDefault().getID();\r
42         try {\r
43             try {\r
44                 logln("user.timezone: " + System.getProperty("user.timezone", "<not set>"));\r
45             } catch (AccessControlException e) {\r
46                 // user.timezone is a protected system property - ignore\r
47             }\r
48             logln("TimeZone.getDefault().getID(): " + id);\r
49             logln(new Date().toString());\r
50             logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");\r
51         }\r
52         catch (SecurityException e) {\r
53             warnln("security exception: " + e.toString());\r
54         }\r
55     }\r
56 \r
57     public void Test4073209() {\r
58         TimeZone z1 = TimeZone.getTimeZone("PST");\r
59         TimeZone z2 = TimeZone.getTimeZone("PST");\r
60         if (z1 == z2) errln("Fail: TimeZone should return clones");\r
61     }\r
62 \r
63     public void Test4073215() {\r
64         SimpleTimeZone z = new SimpleTimeZone(0, "GMT");\r
65         if (z.useDaylightTime())\r
66             errln("Fail: Fix test to start with non-DST zone");\r
67         z.setStartRule(Calendar.FEBRUARY, 1, Calendar.SUNDAY, 0);\r
68         z.setEndRule(Calendar.MARCH, -1, Calendar.SUNDAY, 0);\r
69         if (!z.useDaylightTime())\r
70             errln("Fail: DST not active");\r
71         Calendar tempcal = Calendar.getInstance();\r
72         tempcal.clear();\r
73         tempcal.setTimeZone(z);\r
74         tempcal.set(1997, Calendar.JANUARY, 31);\r
75         Date d1 = tempcal.getTime();\r
76         if (z.inDaylightTime(d1)) {\r
77             errln("Fail: DST not working as expected");\r
78         } \r
79 \r
80         tempcal.set(1997, Calendar.MARCH, 1);\r
81         Date d2 = tempcal.getTime();\r
82         if (!z.inDaylightTime(d2)) {\r
83             errln("Fail: DST not working as expected");\r
84         }\r
85         tempcal.clear();\r
86         tempcal.set(1997, Calendar.MARCH, 31);\r
87         Date d3 = tempcal.getTime();\r
88         if (z.inDaylightTime(d3)) {\r
89             errln("Fail: DST not working as expected");\r
90         } \r
91     }\r
92 \r
93     /**\r
94      * The expected behavior of TimeZone around the boundaries is:\r
95      * (Assume transition time of 2:00 AM)\r
96      *    day of onset 1:59 AM STD  = display name 1:59 AM ST\r
97      *                 2:00 AM STD  = display name 3:00 AM DT\r
98      *    day of end   0:59 AM STD  = display name 1:59 AM DT\r
99      *                 1:00 AM STD  = display name 1:00 AM ST\r
100      */\r
101     public void Test4084933() {\r
102         TimeZone tz = TimeZone.getTimeZone("PST");\r
103 \r
104         long offset1 = tz.getOffset(1,\r
105             1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000));\r
106         long offset2 = tz.getOffset(1,\r
107             1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)-1);\r
108 \r
109         long offset3 = tz.getOffset(1,\r
110             1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000));\r
111         long offset4 = tz.getOffset(1,\r
112             1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)-1);\r
113 \r
114         /*\r
115          *  The following was added just for consistency.  It shows that going *to* Daylight\r
116          *  Savings Time (PDT) does work at 2am.\r
117          */\r
118 \r
119         long offset5 = tz.getOffset(1,\r
120             1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000));\r
121         long offset6 = tz.getOffset(1,\r
122             1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)-1);\r
123 \r
124         long offset7 = tz.getOffset(1,\r
125             1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000));\r
126         long offset8 = tz.getOffset(1,\r
127             1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)-1);\r
128 \r
129         long SToffset = -8 * 60*60*1000L;\r
130         long DToffset = -7 * 60*60*1000L;\r
131         if (offset1 != SToffset || offset2 != SToffset ||\r
132             offset3 != SToffset || offset4 != DToffset ||\r
133             offset5 != DToffset || offset6 != SToffset ||\r
134             offset7 != SToffset || offset8 != SToffset)\r
135             warnln("Fail: TimeZone misbehaving");\r
136     }\r
137 \r
138     public void Test4096952() {\r
139         String[] ZONES = { "GMT", "MET", "IST" };\r
140         boolean pass = true;\r
141         try {\r
142             for (int i=0; i<ZONES.length; ++i) {\r
143                 TimeZone zone = TimeZone.getTimeZone(ZONES[i]);\r
144                 if (!zone.getID().equals(ZONES[i]))\r
145                     warnln("Fail: Test broken; zones not instantiating");\r
146 \r
147                 ByteArrayOutputStream baos;\r
148                 ObjectOutputStream ostream =\r
149                     new ObjectOutputStream(baos = new\r
150                                            ByteArrayOutputStream());\r
151                 ostream.writeObject(zone);\r
152                 ostream.close();\r
153                 baos.close();\r
154                 ObjectInputStream istream =\r
155                     new ObjectInputStream(new\r
156                                           ByteArrayInputStream(baos.toByteArray()));\r
157                 TimeZone frankenZone = (TimeZone) istream.readObject();\r
158                 //logln("Zone:        " + zone);\r
159                 //logln("FrankenZone: " + frankenZone);\r
160                 if (!zone.equals(frankenZone)) {\r
161                     logln("TimeZone " + zone.getID() +\r
162                           " not equal to serialized/deserialized one");\r
163                     pass = false;\r
164                 }\r
165             }\r
166             if (!pass) errln("Fail: TimeZone serialization/equality bug");\r
167         }\r
168         catch (IOException e) {\r
169             errln("Fail: " + e);\r
170             e.printStackTrace();\r
171         }\r
172         catch (ClassNotFoundException e) {\r
173             errln("Fail: " + e);\r
174             e.printStackTrace();\r
175         }\r
176     }\r
177 \r
178     public void Test4109314() {\r
179         GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance();\r
180         TimeZone PST = TimeZone.getTimeZone("PST");\r
181         java.util.Calendar tempcal = java.util.Calendar.getInstance();\r
182         tempcal.clear();\r
183         tempcal.set(1998,Calendar.APRIL,4,22,0);\r
184         Date d1 = tempcal.getTime();\r
185         tempcal.set(1998,Calendar.APRIL,5,6,0);\r
186         Date d2 = tempcal.getTime();\r
187         tempcal.set(1998,Calendar.OCTOBER,24,22,0);\r
188         Date d3 = tempcal.getTime();\r
189         tempcal.set(1998,Calendar.OCTOBER,25,6,0);\r
190         Date d4 = tempcal.getTime();\r
191         Object[] testData = {\r
192             PST, d1, d2,\r
193             PST, d3, d4,\r
194         };\r
195         boolean pass=true;\r
196         for (int i=0; i<testData.length; i+=3) {\r
197             testCal.setTimeZone((TimeZone) testData[i]);\r
198             long t = ((Date)testData[i+1]).getTime();\r
199             Date end = (Date) testData[i+2];\r
200             while (t < end.getTime()) {\r
201                 testCal.setTime(new Date(t));\r
202                 if (!checkCalendar314(testCal, (TimeZone) testData[i]))\r
203                     pass = false;\r
204                 t += 60*60*1000L;\r
205             }\r
206         }\r
207         if (!pass) errln("Fail: TZ API inconsistent");\r
208     }\r
209 \r
210     boolean checkCalendar314(GregorianCalendar testCal, TimeZone testTZ) {\r
211         // GregorianCalendar testCal = (GregorianCalendar)aCal.clone();\r
212 \r
213         final int ONE_DAY = 24*60*60*1000;\r
214 \r
215         int tzOffset, tzRawOffset;\r
216         Float tzOffsetFloat,tzRawOffsetFloat;\r
217         // Here is where the user made an error.  They were passing in the value of\r
218         // the MILLSECOND field; you need to pass in the millis in the day in STANDARD\r
219         // time.\r
220         int millis = testCal.get(Calendar.MILLISECOND) +\r
221             1000 * (testCal.get(Calendar.SECOND) +\r
222                     60 * (testCal.get(Calendar.MINUTE) +\r
223                           60 * (testCal.get(Calendar.HOUR_OF_DAY)))) -\r
224             testCal.get(Calendar.DST_OFFSET);\r
225 \r
226         /* Fix up millis to be in range.  ASSUME THAT WE ARE NOT AT THE\r
227          * BEGINNING OR END OF A MONTH.  We must add this code because\r
228          * getOffset() has been changed to be more strict about the parameters\r
229          * it receives -- it turns out that this test was passing in illegal\r
230          * values. */\r
231         int date = testCal.get(Calendar.DATE);\r
232         int dow  = testCal.get(Calendar.DAY_OF_WEEK);\r
233         while (millis < 0) {\r
234             millis += ONE_DAY;\r
235             --date;\r
236             dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 6) % 7);\r
237         }\r
238         while (millis >= ONE_DAY) {\r
239             millis -= ONE_DAY;\r
240             ++date;\r
241             dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 1) % 7);\r
242         }\r
243 \r
244         tzOffset = testTZ.getOffset(testCal.get(Calendar.ERA),\r
245                                     testCal.get(Calendar.YEAR),\r
246                                     testCal.get(Calendar.MONTH),\r
247                                     date,\r
248                                     dow,\r
249                                     millis);\r
250         tzRawOffset = testTZ.getRawOffset();\r
251         tzOffsetFloat = new Float((float)tzOffset/(float)3600000);\r
252         tzRawOffsetFloat = new Float((float)tzRawOffset/(float)3600000);\r
253 \r
254         Date testDate = testCal.getTime();\r
255 \r
256         boolean inDaylightTime = testTZ.inDaylightTime(testDate);\r
257         SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm");\r
258         sdf.setCalendar(testCal);\r
259         String inDaylightTimeString;\r
260 \r
261         boolean passed;\r
262 \r
263         if (inDaylightTime)\r
264         {\r
265             inDaylightTimeString = " DST ";\r
266             passed = (tzOffset == (tzRawOffset + 3600000));\r
267         }\r
268         else\r
269         {\r
270             inDaylightTimeString = "     ";\r
271             passed = (tzOffset == tzRawOffset);\r
272         }\r
273 \r
274         String output = testTZ.getID() + " " + sdf.format(testDate) +\r
275             " Offset(" + tzOffsetFloat + ")" +\r
276             " RawOffset(" + tzRawOffsetFloat + ")" +\r
277             " " + millis/(float)3600000 + " " +\r
278             inDaylightTimeString;\r
279 \r
280         if (passed)\r
281             output += "     ";\r
282         else\r
283             output += "ERROR";\r
284 \r
285         if (passed) logln(output); else errln(output);\r
286         return passed;\r
287     }\r
288 \r
289     /**\r
290      * CANNOT REPRODUDE\r
291      *\r
292      * Yet another _alleged_ bug in TimeZone.getOffset(), a method that never\r
293      * should have been made public.  It's simply too hard to use correctly.\r
294      *\r
295      * The original test code failed to do the following:\r
296      * (1) Call Calendar.setTime() before getting the fields!\r
297      * (2) Use the right millis (as usual) for getOffset(); they were passing\r
298      *     in the MILLIS field, instead of the STANDARD MILLIS IN DAY.\r
299      * When you fix these two problems, the test passes, as expected.\r
300      */\r
301     public void Test4126678() {\r
302     // Note: this test depends on the PST time zone.\r
303     TimeZone initialZone = TimeZone.getDefault();\r
304         Calendar cal = Calendar.getInstance();\r
305         TimeZone tz = TimeZone.getTimeZone("PST");\r
306     TimeZone.setDefault(tz);\r
307         cal.setTimeZone(tz);\r
308 \r
309         java.util.Calendar tempcal = java.util.Calendar.getInstance();\r
310         tempcal.clear();\r
311         tempcal.set(1998, Calendar.APRIL, 5, 10, 0);\r
312         Date dt = tempcal.getTime();\r
313     // the dt value is local time in PST.\r
314         if (!tz.inDaylightTime(dt))\r
315             errln("We're not in Daylight Savings Time and we should be.\n");\r
316 \r
317         cal.setTime(dt);\r
318         int era = cal.get(Calendar.ERA);\r
319         int year = cal.get(Calendar.YEAR);\r
320         int month = cal.get(Calendar.MONTH);\r
321         int day = cal.get(Calendar.DATE);\r
322         int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);\r
323         int millis = cal.get(Calendar.MILLISECOND) +\r
324             (cal.get(Calendar.SECOND) +\r
325              (cal.get(Calendar.MINUTE) +\r
326               (cal.get(Calendar.HOUR) * 60) * 60) * 1000) -\r
327             cal.get(Calendar.DST_OFFSET);\r
328 \r
329         long offset = tz.getOffset(era, year, month, day, dayOfWeek, millis);\r
330         long raw_offset = tz.getRawOffset();\r
331         if (offset == raw_offset)\r
332             errln("Offsets should not match when in DST");\r
333 \r
334     // restore the initial time zone so that this test case\r
335     // doesn't affect the others.\r
336     TimeZone.setDefault(initialZone);\r
337     }\r
338 \r
339     /**\r
340      * TimeZone.getAvailableIDs(int) throws exception for certain values,\r
341      * due to a faulty constant in TimeZone.java.\r
342      */\r
343     public void Test4151406() {\r
344         int max = 0;\r
345         for (int h=-28; h<=30; ++h) {\r
346             // h is in half-hours from GMT; rawoffset is in millis\r
347             int rawoffset = h * 1800000;\r
348             int hh = (h<0) ? -h : h;\r
349             String hname = ((h<0) ? "GMT-" : "GMT+") +\r
350                 ((hh/2 < 10) ? "0" : "") +\r
351                 (hh/2) + ':' +\r
352                 ((hh%2==0) ? "00" : "30");\r
353             try {\r
354                 String[] ids = TimeZone.getAvailableIDs(rawoffset);\r
355                 if (ids.length > max) max = ids.length;\r
356                 logln(hname + ' ' + ids.length +\r
357                       ((ids.length > 0) ? (" e.g. " + ids[0]) : ""));\r
358             } catch (Exception e) {\r
359                 errln(hname + ' ' + "Fail: " + e);\r
360             }\r
361         }\r
362         logln("Maximum zones per offset = " + max);\r
363     }\r
364 \r
365     public void Test4151429() {\r
366         try {\r
367             TimeZone tz = TimeZone.getTimeZone("GMT");\r
368             /*String name =*/ tz.getDisplayName(true, Integer.MAX_VALUE,\r
369                                             Locale.getDefault());\r
370             errln("IllegalArgumentException not thrown by TimeZone.getDisplayName()");\r
371         } catch(IllegalArgumentException e) {\r
372             System.out.print("");\r
373         }\r
374     }\r
375 \r
376     /**\r
377      * SimpleTimeZone accepts illegal DST savings values.  These values\r
378      * must be non-zero.  There is no upper limit at this time.\r
379      */\r
380     public void Test4154525() {\r
381         final int GOOD = 1, BAD = 0;\r
382         int[] DATA = {\r
383             1, GOOD,\r
384             0, BAD,\r
385             -1, BAD,\r
386             60*60*1000, GOOD,\r
387             Integer.MIN_VALUE, BAD,\r
388             // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time\r
389         };\r
390         for (int i=0; i<DATA.length; i+=2) {\r
391             int savings = DATA[i];\r
392             boolean valid = DATA[i+1] == GOOD;\r
393             String method = null;\r
394             for (int j=0; j<2; ++j) {\r
395                 try {\r
396                     switch (j) {\r
397                     case 0:\r
398                         method = "constructor";\r
399                         SimpleTimeZone z = new SimpleTimeZone(0, "id",\r
400                             Calendar.JANUARY, 1, 0, 0,\r
401                             Calendar.MARCH, 1, 0, 0,\r
402                             savings); // <- what we're interested in\r
403                         break;\r
404                     case 1:\r
405                         method = "setDSTSavings()";\r
406                         z = new SimpleTimeZone(0, "GMT");\r
407                         z.setDSTSavings(savings);\r
408                         break;\r
409                     }\r
410                     if (valid) {\r
411                         logln("Pass: DST savings of " + savings + " accepted by " + method);\r
412                     } else {\r
413                         errln("Fail: DST savings of " + savings + " accepted by " + method);\r
414                     }\r
415                 } catch (IllegalArgumentException e) {\r
416                     if (valid) {\r
417                         errln("Fail: DST savings of " + savings + " to " + method + " gave " + e);\r
418                     } else {\r
419                         logln("Pass: DST savings of " + savings + " to " + method + " gave " + e);\r
420                     }\r
421                 }\r
422             }\r
423         }\r
424     }\r
425 \r
426     /**\r
427      * SimpleTimeZone.hasSameRules() doesn't work for zones with no DST\r
428      * and different DST parameters.\r
429      */\r
430     public void Test4154537() {\r
431         // tz1 and tz2 have no DST and different rule parameters\r
432         SimpleTimeZone tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0);\r
433         SimpleTimeZone tz2 = new SimpleTimeZone(0, "2", 1, 0, 0, 0, 3, 0, 0, 0);\r
434         // tza and tzA have the same rule params\r
435         SimpleTimeZone tza = new SimpleTimeZone(0, "a", 0, 1, 0, 0, 3, 2, 0, 0);\r
436         SimpleTimeZone tzA = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 3, 2, 0, 0);\r
437         // tzb differs from tza\r
438         SimpleTimeZone tzb = new SimpleTimeZone(0, "b", 0, 1, 0, 0, 3, 1, 0, 0);\r
439         if (tz1.useDaylightTime() || tz2.useDaylightTime() ||\r
440             !tza.useDaylightTime() || !tzA.useDaylightTime() ||\r
441             !tzb.useDaylightTime()) {\r
442             errln("Test is broken -- rewrite it");\r
443         }\r
444         if (!tza.hasSameRules(tzA) || tza.hasSameRules(tzb)) {\r
445             errln("Fail: hasSameRules() broken for zones with rules");\r
446         }\r
447         if (!tz1.hasSameRules(tz2)) {\r
448             errln("Fail: hasSameRules() returns false for zones without rules");\r
449             errln("zone 1 = " + tz1);\r
450             errln("zone 2 = " + tz2);\r
451         }\r
452     }\r
453 \r
454     /**\r
455      * SimpleTimeZone constructors, setStartRule(), and setEndRule() don't\r
456      * check for out-of-range arguments.\r
457      */\r
458     public void Test4154542() {\r
459         final int GOOD = 1;\r
460         final int BAD  = 0;\r
461 \r
462         final int GOOD_MONTH       = Calendar.JANUARY;\r
463         final int GOOD_DAY         = 1;\r
464         final int GOOD_DAY_OF_WEEK = Calendar.SUNDAY;\r
465         final int GOOD_TIME        = 0;\r
466 \r
467         int[] DATA = {\r
468             GOOD, Integer.MIN_VALUE,    0,  Integer.MAX_VALUE,   Integer.MIN_VALUE,\r
469             GOOD, Calendar.JANUARY,    -5,  Calendar.SUNDAY,     0,\r
470             GOOD, Calendar.DECEMBER,    5,  Calendar.SATURDAY,   24*60*60*1000-1,\r
471             BAD,  Calendar.DECEMBER,    5,  Calendar.SATURDAY,   24*60*60*1000+1,\r
472             BAD,  Calendar.DECEMBER,    5,  Calendar.SATURDAY,  -1,\r
473             BAD,  Calendar.JANUARY,    -6,  Calendar.SUNDAY,     0,\r
474             BAD,  Calendar.DECEMBER,    6,  Calendar.SATURDAY,   24*60*60*1000,\r
475             GOOD, Calendar.DECEMBER,    1,  0,                   0,\r
476             GOOD, Calendar.DECEMBER,   31,  0,                   0,\r
477             BAD,  Calendar.APRIL,      31,  0,                   0,\r
478             BAD,  Calendar.DECEMBER,   32,  0,                   0,\r
479             BAD,  Calendar.JANUARY-1,   1,  Calendar.SUNDAY,     0,\r
480             BAD,  Calendar.DECEMBER+1,  1,  Calendar.SUNDAY,     0,\r
481             GOOD, Calendar.DECEMBER,   31, -Calendar.SUNDAY,     0,\r
482             GOOD, Calendar.DECEMBER,   31, -Calendar.SATURDAY,   0,\r
483             BAD,  Calendar.DECEMBER,   32, -Calendar.SATURDAY,   0,\r
484             BAD,  Calendar.DECEMBER,  -32, -Calendar.SATURDAY,   0,\r
485             BAD,  Calendar.DECEMBER,   31, -Calendar.SATURDAY-1, 0,\r
486         };\r
487         SimpleTimeZone zone = new SimpleTimeZone(0, "Z");\r
488         for (int i=0; i<DATA.length; i+=5) {\r
489             boolean shouldBeGood = (DATA[i] == GOOD);\r
490             int month     = DATA[i+1];\r
491             int day       = DATA[i+2];\r
492             int dayOfWeek = DATA[i+3];\r
493             int time      = DATA[i+4];\r
494 \r
495             Exception ex = null;\r
496             try {\r
497                 zone.setStartRule(month, day, dayOfWeek, time);\r
498             } catch (IllegalArgumentException e) {\r
499                 ex = e;\r
500             }\r
501             if ((ex == null) != shouldBeGood) {\r
502                 errln("setStartRule(month=" + month + ", day=" + day +\r
503                       ", dayOfWeek=" + dayOfWeek + ", time=" + time +\r
504                       (shouldBeGood ? (") should work but throws " + ex)\r
505                        : ") should fail but doesn't"));\r
506             }\r
507 \r
508             ex = null;\r
509             try {\r
510                 zone.setEndRule(month, day, dayOfWeek, time);\r
511             } catch (IllegalArgumentException e) {\r
512                 ex = e;\r
513             }\r
514             if ((ex == null) != shouldBeGood) {\r
515                 errln("setEndRule(month=" + month + ", day=" + day +\r
516                       ", dayOfWeek=" + dayOfWeek + ", time=" + time +\r
517                       (shouldBeGood ? (") should work but throws " + ex)\r
518                        : ") should fail but doesn't"));\r
519             }\r
520 \r
521             ex = null;\r
522             try {\r
523                 /*SimpleTimeZone temp =*/ new SimpleTimeZone(0, "Z",\r
524                         month, day, dayOfWeek, time,\r
525                         GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME);\r
526             } catch (IllegalArgumentException e) {\r
527                 ex = e;\r
528             }\r
529             if ((ex == null) != shouldBeGood) {\r
530                 errln("SimpleTimeZone(month=" + month + ", day=" + day +\r
531                       ", dayOfWeek=" + dayOfWeek + ", time=" + time +\r
532                       (shouldBeGood ? (", <end>) should work but throws " + ex)\r
533                        : ", <end>) should fail but doesn't"));\r
534             }\r
535 \r
536             ex = null;\r
537             try {\r
538                 /*SimpleTimeZone temp = */new SimpleTimeZone(0, "Z",\r
539                         GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME,\r
540                         month, day, dayOfWeek, time);\r
541                // temp = null;\r
542             } catch (IllegalArgumentException e) {\r
543                 ex = e;\r
544             }\r
545             if ((ex == null) != shouldBeGood) {\r
546                 errln("SimpleTimeZone(<start>, month=" + month + ", day=" + day +\r
547                       ", dayOfWeek=" + dayOfWeek + ", time=" + time +\r
548                       (shouldBeGood ? (") should work but throws " + ex)\r
549                        : ") should fail but doesn't"));\r
550             }\r
551         }\r
552     }\r
553 \r
554     /**\r
555      * SimpleTimeZone.getOffset accepts illegal arguments.\r
556      */\r
557     public void Test4154650() {\r
558         final int GOOD=1, BAD=0;\r
559         final int GOOD_ERA=GregorianCalendar.AD, GOOD_YEAR=1998, GOOD_MONTH=Calendar.AUGUST;\r
560         final int GOOD_DAY=2, GOOD_DOW=Calendar.SUNDAY, GOOD_TIME=16*3600000;\r
561         int[] DATA = {\r
562             GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
563 \r
564             GOOD, GregorianCalendar.BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
565             GOOD, GregorianCalendar.AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
566             BAD,  GregorianCalendar.BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
567             BAD,  GregorianCalendar.AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
568 \r
569             GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
570             GOOD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
571             BAD,  GOOD_ERA, GOOD_YEAR, Calendar.JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
572             BAD,  GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIME,\r
573 \r
574             GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 1, GOOD_DOW, GOOD_TIME,\r
575             GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 31, GOOD_DOW, GOOD_TIME,\r
576             BAD,  GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 0, GOOD_DOW, GOOD_TIME,\r
577             BAD,  GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 32, GOOD_DOW, GOOD_TIME,\r
578 \r
579             GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY, GOOD_TIME,\r
580             GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY, GOOD_TIME,\r
581             BAD,  GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY-1, GOOD_TIME,\r
582             BAD,  GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY+1, GOOD_TIME,\r
583 \r
584             GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0,\r
585             GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1,\r
586             BAD,  GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1,\r
587             BAD,  GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000,\r
588         };\r
589 \r
590         TimeZone tz = TimeZone.getDefault();\r
591         for (int i=0; i<DATA.length; i+=7) {\r
592             boolean good = DATA[i] == GOOD;\r
593             IllegalArgumentException e = null;\r
594             try {\r
595                 /*int offset =*/ tz.getOffset(DATA[i+1], DATA[i+2], DATA[i+3],\r
596                                           DATA[i+4], DATA[i+5], DATA[i+6]);\r
597                 //offset = 0;\r
598            } catch (IllegalArgumentException ex) {\r
599                 e = ex;\r
600             }\r
601             if (good != (e == null)) {\r
602                 errln("Fail: getOffset(" +\r
603                       DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " +\r
604                       DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] +\r
605                       (good ? (") threw " + e) : ") accepts invalid args"));\r
606             }\r
607         }\r
608     }\r
609 \r
610     /**\r
611      * TimeZone constructors allow null IDs.\r
612      */\r
613     public void Test4159922() {\r
614         TimeZone z = null;\r
615 \r
616         // TimeZone API.  Only hasSameRules() and setDefault() should\r
617         // allow null.\r
618         try {\r
619             z = TimeZone.getTimeZone(null);\r
620             errln("FAIL: Null allowed in getTimeZone");\r
621         } catch (NullPointerException e) {\r
622             System.out.print("");\r
623         }\r
624         z = TimeZone.getTimeZone("GMT");\r
625         try {\r
626         // {dlf} requiring cast for disambiguation is ok for compatibility since null\r
627         // is not a valid argument to this API\r
628             z.getDisplayName(false, TimeZone.SHORT, (ULocale)null);\r
629             errln("FAIL: Null allowed in getDisplayName(3)");\r
630         } catch (NullPointerException e) {\r
631             System.out.print("");\r
632         }\r
633         try {\r
634         // {dlf} see above\r
635             z.getDisplayName((ULocale)null);\r
636             errln("FAIL: Null allowed in getDisplayName(1)");\r
637         } catch (NullPointerException e) {\r
638             System.out.print("");\r
639         }\r
640         try {\r
641             if (z.hasSameRules(null)) {\r
642                 errln("FAIL: hasSameRules returned true");\r
643             }\r
644         } catch (NullPointerException e) {\r
645             errln("FAIL: Null NOT allowed in hasSameRules");\r
646         }\r
647         try {\r
648             z.inDaylightTime(null);\r
649             errln("FAIL: Null allowed in inDaylightTime");\r
650         } catch (NullPointerException e) {\r
651             System.out.print("");\r
652         }\r
653         try {\r
654             z.setID(null);\r
655             errln("FAIL: Null allowed in setID");\r
656         } catch (NullPointerException e) {\r
657             System.out.print("");\r
658         }\r
659 \r
660         TimeZone save = TimeZone.getDefault();\r
661         try {\r
662             TimeZone.setDefault(null);\r
663         } catch (NullPointerException e) {\r
664             errln("FAIL: Null NOT allowed in setDefault");\r
665         } finally {\r
666             TimeZone.setDefault(save);\r
667         }\r
668 \r
669         // SimpleTimeZone API\r
670         SimpleTimeZone s = null;\r
671         try {\r
672             s = new SimpleTimeZone(0, null);\r
673             errln("FAIL: Null allowed in SimpleTimeZone(2)");\r
674         } catch (NullPointerException e) {\r
675             System.out.print("");\r
676         }\r
677         try {\r
678             s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0);\r
679             errln("FAIL: Null allowed in SimpleTimeZone(10)");\r
680         } catch (NullPointerException e) {\r
681             System.out.print("");\r
682         }\r
683         try {\r
684             s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0, 1000);\r
685             errln("FAIL: Null allowed in SimpleTimeZone(11)");\r
686         } catch (NullPointerException e) {\r
687             System.out.print("");\r
688         }\r
689         if(s!=null){\r
690             errln("FAIL: Did not get the expected Exception");\r
691         }\r
692     }\r
693 \r
694     /**\r
695      * TimeZone broken at midnight.  The TimeZone code fails to handle\r
696      * transitions at midnight correctly.\r
697      */\r
698     public void Test4162593() {\r
699         SimpleDateFormat fmt = new SimpleDateFormat("z", Locale.US);\r
700         final int ONE_HOUR = 60*60*1000;\r
701         final float H = (float) ONE_HOUR;\r
702         TimeZone initialZone = TimeZone.getDefault();\r
703         SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm z");\r
704 \r
705         SimpleTimeZone asuncion = new SimpleTimeZone(-4*ONE_HOUR, "America/Asuncion" /*PY%sT*/,\r
706             Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR,\r
707             Calendar.MARCH, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR);\r
708 \r
709         /* Zone\r
710          * Starting time\r
711          * Transition expected between start+1H and start+2H\r
712          */\r
713         Object[] DATA = {\r
714             new SimpleTimeZone(2*ONE_HOUR, "Asia/Damascus" /*EE%sT*/,\r
715                 Calendar.APRIL, 1, 0 /*DOM*/, 0*ONE_HOUR,\r
716                 Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR),\r
717             new int[] {1998, Calendar.SEPTEMBER, 30, 22, 0},\r
718             Boolean.TRUE,\r
719 \r
720             asuncion,\r
721             new int[] {2000, Calendar.FEBRUARY, 28, 22, 0},\r
722             Boolean.FALSE,\r
723 \r
724             asuncion,\r
725             new int[] {2000, Calendar.FEBRUARY, 29, 22, 0},\r
726             Boolean.TRUE,\r
727         };\r
728 \r
729         String[] zone = new String[4];\r
730 \r
731         for (int j=0; j<DATA.length; j+=3) {\r
732             TimeZone tz = (TimeZone)DATA[j];\r
733             TimeZone.setDefault(tz);\r
734             fmt.setTimeZone(tz);\r
735             sdf.setTimeZone(tz);\r
736 \r
737             // Must construct the Date object AFTER setting the default zone\r
738             int[] p = (int[])DATA[j+1];\r
739             Calendar cal = Calendar.getInstance();\r
740             cal.clear();\r
741             cal.set(p[0], p[1], p[2], p[3], p[4]);\r
742             long start = cal.getTime().getTime();\r
743             boolean transitionExpected = ((Boolean)DATA[j+2]).booleanValue();\r
744 \r
745             logln(tz.getID() + ":");\r
746             for (int i=0; i<4; ++i) {\r
747                 Date d = new Date(start + i*ONE_HOUR);\r
748                 zone[i] = fmt.format(d);\r
749                 logln("" + i + ": " + sdf.format(d) + " => " + zone[i] +\r
750                       " (" + d.getTime()/H + ")");\r
751             }\r
752             cal.set(p[0], p[1], p[2], 0, 0);\r
753             for (int i=0; i<4; ++i) {\r
754                 int h = 22+i;\r
755                 int dom = p[2]+(h>=24?1:0);\r
756                 h %= 24;\r
757                 int ms = h*ONE_HOUR;\r
758                 cal.clear();\r
759                 cal.set(p[0], p[1], dom, 0, 0);\r
760                 int off = tz.getOffset(GregorianCalendar.AD,\r
761                                        cal.get(Calendar.YEAR),\r
762                                        cal.get(Calendar.MONTH),\r
763                                        cal.get(Calendar.DATE),\r
764                                        cal.get(Calendar.DAY_OF_WEEK),\r
765                                        ms);\r
766                 cal.add(Calendar.HOUR, h);\r
767                 int dstOffset = cal.get(Calendar.DST_OFFSET);\r
768                 logln("h=" + h + "; dom=" + dom +\r
769                       "; ZONE_OFFSET=" + cal.get(Calendar.ZONE_OFFSET)/H +\r
770                       "; DST_OFFSET=" + dstOffset/H +\r
771                       "; getOffset()=" + off/H +\r
772                       " (" + cal.getTime().getTime()/H + ")");\r
773             }\r
774             if (zone[0].equals(zone[1]) &&\r
775                 (zone[1].equals(zone[2]) != transitionExpected) &&\r
776                 zone[2].equals(zone[3])) {\r
777                 logln("Ok: transition " + transitionExpected);\r
778             } else {\r
779                 errln("FAIL: expected " +\r
780                       (transitionExpected?"transition":"no transition"));\r
781             }\r
782         }\r
783 \r
784     // restore the initial time zone so that this test case\r
785     // doesn't affect the others.\r
786     TimeZone.setDefault(initialZone);\r
787     }\r
788 \r
789     /**\r
790      * TimeZone broken in last hour of year\r
791      */\r
792     public void Test4173604() {\r
793         TimeZone pst = TimeZone.getTimeZone("PST");\r
794         int o22 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 22*60*60*1000);\r
795         int o23 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 23*60*60*1000);\r
796         int o00 = pst.getOffset(1, 1999, 0, 1, Calendar.FRIDAY, 0);\r
797         if (o22 != o23 || o22 != o00) {\r
798             errln("Offsets should be the same (for PST), but got: " +\r
799                   "12/31 22:00 " + o22 +\r
800                   ", 12/31 23:00 " + o23 +\r
801                   ", 01/01 00:00 " + o00);\r
802         }\r
803 \r
804         GregorianCalendar cal = new GregorianCalendar();\r
805         cal.setTimeZone(pst);\r
806         cal.clear();\r
807         cal.set(1998, Calendar.JANUARY, 1);\r
808         int lastDST = cal.get(Calendar.DST_OFFSET);\r
809         int transitions = 0;\r
810         int delta = 5;\r
811         while (cal.get(Calendar.YEAR) < 2000) {\r
812             cal.add(Calendar.MINUTE, delta);\r
813             if (cal.get(Calendar.DST_OFFSET) != lastDST) {\r
814                 ++transitions;\r
815                 Calendar t = (Calendar)cal.clone();\r
816                 t.add(Calendar.MINUTE, -delta);\r
817                 logln(t.getTime() + "  " + t.get(Calendar.DST_OFFSET));\r
818                 logln(cal.getTime() + "  " + (lastDST=cal.get(Calendar.DST_OFFSET)));\r
819             }\r
820         }\r
821         if (transitions != 4) {\r
822             errln("Saw " + transitions + " transitions; should have seen 4");\r
823         }\r
824     }\r
825 \r
826     /**\r
827      * getDisplayName doesn't work with unusual savings/offsets.\r
828      */\r
829     public void Test4176686() {\r
830         // Construct a zone that does not observe DST but\r
831         // that does have a DST savings (which should be ignored).\r
832         int offset = 90 * 60000; // 1:30\r
833         SimpleTimeZone z1 = new SimpleTimeZone(offset, "_std_zone_");\r
834         z1.setDSTSavings(45 * 60000); // 0:45\r
835 \r
836         // Construct a zone that observes DST for the first 6 months.\r
837         SimpleTimeZone z2 = new SimpleTimeZone(offset, "_dst_zone_");\r
838         z2.setDSTSavings(45 * 60000); // 0:45\r
839         z2.setStartRule(Calendar.JANUARY, 1, 0);\r
840         z2.setEndRule(Calendar.JULY, 1, 0);\r
841 \r
842         // Also check DateFormat\r
843         DateFormat fmt1 = new SimpleDateFormat("z");\r
844         fmt1.setTimeZone(z1); // Format uses standard zone\r
845         DateFormat fmt2 = new SimpleDateFormat("z");\r
846         fmt2.setTimeZone(z2); // Format uses DST zone\r
847         java.util.Calendar tempcal = java.util.Calendar.getInstance();\r
848         tempcal.clear();\r
849         tempcal.set(1970, Calendar.FEBRUARY, 1);\r
850         Date dst = tempcal.getTime(); // Time in DST\r
851         tempcal.set(1970, Calendar.AUGUST, 1);\r
852         Date std = tempcal.getTime(); // Time in standard\r
853 \r
854         // Description, Result, Expected Result\r
855         String[] DATA = {\r
856             "getDisplayName(false, SHORT)/std zone",\r
857             z1.getDisplayName(false, TimeZone.SHORT), "GMT+01:30",\r
858             "getDisplayName(false, LONG)/std zone",\r
859             z1.getDisplayName(false, TimeZone.LONG ), "GMT+01:30",\r
860             "getDisplayName(true, SHORT)/std zone",\r
861             z1.getDisplayName(true, TimeZone.SHORT), "GMT+01:30",\r
862             "getDisplayName(true, LONG)/std zone",\r
863             z1.getDisplayName(true, TimeZone.LONG ), "GMT+01:30",\r
864             "getDisplayName(false, SHORT)/dst zone",\r
865             z2.getDisplayName(false, TimeZone.SHORT), "GMT+01:30",\r
866             "getDisplayName(false, LONG)/dst zone",\r
867             z2.getDisplayName(false, TimeZone.LONG ), "GMT+01:30",\r
868             "getDisplayName(true, SHORT)/dst zone",\r
869             z2.getDisplayName(true, TimeZone.SHORT), "GMT+02:15",\r
870             "getDisplayName(true, LONG)/dst zone",\r
871             z2.getDisplayName(true, TimeZone.LONG ), "GMT+02:15",\r
872             "DateFormat.format(std)/std zone", fmt1.format(std), "GMT+01:30",\r
873             "DateFormat.format(dst)/std zone", fmt1.format(dst), "GMT+01:30",\r
874             "DateFormat.format(std)/dst zone", fmt2.format(std), "GMT+01:30",\r
875             "DateFormat.format(dst)/dst zone", fmt2.format(dst), "GMT+02:15",\r
876         };\r
877 \r
878         for (int i=0; i<DATA.length; i+=3) {\r
879             if (!DATA[i+1].equals(DATA[i+2])) {\r
880                 errln("FAIL: " + DATA[i] + " -> " + DATA[i+1] + ", exp " + DATA[i+2]);\r
881             }\r
882         }\r
883     }\r
884 \r
885     /**\r
886      * SimpleTimeZone allows invalid DOM values.\r
887      */\r
888     // Current orgnaization of data in zoneinfor.res allows negative\r
889     // values from DOM so comment these tests out\r
890     \r
891     public void Test4184229() {\r
892         SimpleTimeZone zone = null;\r
893         try {\r
894             zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0);\r
895             errln("Failed. No exception has been thrown for DOM -1 startDay");\r
896         } catch(IllegalArgumentException e) {\r
897             logln("(a) " + e.getMessage());\r
898         }\r
899         try {\r
900             zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0);\r
901             errln("Failed. No exception has been thrown for DOM -1 endDay");\r
902         } catch(IllegalArgumentException e) {\r
903             logln("(b) " + e.getMessage());\r
904         }\r
905         try {\r
906             zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, 1000);\r
907             errln("Failed. No exception has been thrown for DOM -1 startDay +savings");\r
908         } catch(IllegalArgumentException e) {\r
909             logln("(c) " + e.getMessage());\r
910         }\r
911         try {\r
912             zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000);\r
913             errln("Failed. No exception has been thrown for DOM -1 endDay +savings");\r
914         } catch(IllegalArgumentException e) {\r
915             logln("(d) " + e.getMessage());\r
916         }\r
917         // Make a valid constructor call for subsequent tests.\r
918 \r
919         zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0);\r
920         \r
921         try {\r
922             zone.setStartRule(0, -1, 0, 0);\r
923             errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings");\r
924         } catch(IllegalArgumentException e) {\r
925             logln("(e) " + e.getMessage());\r
926         }\r
927         try {\r
928             zone.setStartRule(0, -1, 0);\r
929             errln("Failed. No exception has been thrown for DOM -1 setStartRule");\r
930         } catch(IllegalArgumentException e) {\r
931             logln("(f) " + e.getMessage());\r
932         }\r
933         try {\r
934             zone.setEndRule(0, -1, 0, 0);\r
935             errln("Failed. No exception has been thrown for DOM -1 setEndRule +savings");\r
936         } catch(IllegalArgumentException e) {\r
937             logln("(g) " + e.getMessage());\r
938         }\r
939         try {\r
940             zone.setEndRule(0, -1, 0);\r
941             errln("Failed. No exception has been thrown for DOM -1 setEndRule");\r
942         } catch(IllegalArgumentException e) {\r
943             logln("(h) " + e.getMessage());\r
944         }\r
945         \r
946     }\r
947 \r
948     /**\r
949      * SimpleTimeZone.getOffset() throws IllegalArgumentException when to get\r
950      * of 2/29/1996 (leap day).\r
951      */\r
952     public void Test4208960 () {\r
953     TimeZone tz = TimeZone.getTimeZone("PST");\r
954     try {\r
955         /*int offset =*/ tz.getOffset(GregorianCalendar.AD, 1996, Calendar.FEBRUARY, 29,\r
956                       Calendar.THURSDAY, 0);\r
957         //offset = 0;\r
958     } catch (IllegalArgumentException e) {\r
959         errln("FAILED: to get TimeZone.getOffset(2/29/96)");\r
960     }\r
961     try {\r
962         /*int offset =*/ tz.getOffset(GregorianCalendar.AD, 1997, Calendar.FEBRUARY, 29,\r
963                       Calendar.THURSDAY, 0);\r
964         //offset = 0;\r
965         warnln("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception.");\r
966     } catch (IllegalArgumentException e) {\r
967         logln("got IllegalArgumentException");\r
968     }\r
969     }\r
970 \r
971     /**\r
972      * Test to see if DateFormat understands zone equivalency groups.  It\r
973      * might seem that this should be a DateFormat test, but it's really a\r
974      * TimeZone test -- the changes to DateFormat are minor.\r
975      *\r
976      * We use two known, zones that are equivalent, where one zone has\r
977      * localized name data, and the other doesn't, in some locale.\r
978      */\r
979     public void TestJ449() {\r
980         // not used String str;\r
981 \r
982         // Modify the following three as necessary.  The two IDs must\r
983         // specify two zones in the same equivalency group.  One must have\r
984         // locale data in 'loc'; the other must not.\r
985         String idWithLocaleData = "America/Los_Angeles";\r
986         String idWithoutLocaleData = "PST"; // "US/Pacific";\r
987         Locale loc = new Locale("en", "", "");\r
988 \r
989         TimeZone zoneWith = TimeZone.getTimeZone(idWithLocaleData);\r
990         TimeZone zoneWithout = TimeZone.getTimeZone(idWithoutLocaleData);\r
991         // Make sure we got valid zones\r
992         if (!(zoneWith.getID().equals(idWithLocaleData) &&\r
993               zoneWithout.getID().equals(idWithoutLocaleData))) {\r
994             warnln("Fail: Unable to create zones");\r
995         } else {\r
996             GregorianCalendar calWith = new GregorianCalendar(zoneWith);\r
997             GregorianCalendar calWithout = new GregorianCalendar(zoneWithout);\r
998             SimpleDateFormat fmt =\r
999                 new SimpleDateFormat("MMM d yyyy hh:mm a zzz", loc);\r
1000             Date date = new Date(0L);\r
1001             fmt.setCalendar(calWith);\r
1002             String strWith = fmt.format(date);\r
1003             fmt.setCalendar(calWithout);\r
1004             String strWithout = fmt.format(date);\r
1005             if (strWith.equals(strWithout)) {\r
1006                 logln("Ok: " + idWithLocaleData + " -> " +\r
1007                       strWith + "; " + idWithoutLocaleData + " -> " +\r
1008                       strWithout);\r
1009             } else {\r
1010                 errln("FAIL: " + idWithLocaleData + " -> " +\r
1011                       strWith + "; " + idWithoutLocaleData + " -> " +\r
1012                       strWithout);\r
1013             }\r
1014         }\r
1015     }\r
1016 \r
1017     /**\r
1018      * getOffset returns wrong offset for days in early 20th century\r
1019      */\r
1020     public void TestJ5134() {\r
1021         GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance();\r
1022         TimeZone icuEastern = TimeZone.getTimeZone("America/New_York");        \r
1023         testCal.setTimeZone(icuEastern);\r
1024         testCal.set(1900, Calendar.JANUARY, 1, 0, 0, 0);\r
1025         long time = testCal.getTimeInMillis();\r
1026 \r
1027         int offset = icuEastern.getOffset(time);\r
1028         if (offset != -18000000) {\r
1029             errln("FAIL: UTC offset in time zone America/New_York on Jan 1, 1900 -> " + offset);\r
1030         }\r
1031         boolean isDst = icuEastern.inDaylightTime(new Date(time));\r
1032         if (isDst) {\r
1033             errln("FAIL: DST is observed in time zone America/New_York on Jan 1, 1900");\r
1034         }\r
1035 \r
1036         if (System.getProperty("java.vendor", "").startsWith("IBM") &&\r
1037             System.getProperty("java.version", "").equals("1.4.1")) {\r
1038             // IBM JDK 1.4.1 has a bug and fails to run this test case.\r
1039             return;\r
1040         }\r
1041         java.util.TimeZone jdkEastern = java.util.TimeZone.getTimeZone("America/New_York");\r
1042         // Compare offset and DST observation with JDK and ICU for 50 years since 1900\r
1043         testCal.add(Calendar.YEAR, 50);\r
1044         long endTime = testCal.getTimeInMillis();\r
1045         int jdkOffset;\r
1046         boolean isDstJdk;\r
1047         while (time < endTime) {\r
1048             offset = icuEastern.getOffset(time);\r
1049             jdkOffset = jdkEastern.getOffset(time);\r
1050             if (offset != jdkOffset) {\r
1051                 errln("FAIL: Incompatible UTC offset -> JDK:" + jdkOffset + "/ICU:" + offset + " [" + time + "]");\r
1052             }\r
1053             Date d = new Date(time);\r
1054             isDst = icuEastern.inDaylightTime(d);\r
1055             isDstJdk = jdkEastern.inDaylightTime(d);\r
1056             if (isDst != isDstJdk) {\r
1057                 errln("FAIL: Incompatible DST -> JDK:" + isDstJdk + "/ICU:" + isDst + " [" + time + "]");\r
1058             }\r
1059             time += 24*60*60*1000L; // increment 1 day\r
1060         }\r
1061     }\r
1062 \r
1063     /**\r
1064      * Test setRawOffset works OK with system timezone\r
1065      */\r
1066     public void TestT5280() {\r
1067         String[] tzids = TimeZone.getAvailableIDs();\r
1068         for (int i = 0; i < tzids.length; i++) {\r
1069             TimeZone tz = TimeZone.getTimeZone(tzids[i]);\r
1070             boolean useDst = tz.useDaylightTime();\r
1071 \r
1072             // Increase offset for 30 minutes\r
1073             int newRawOffset = tz.getRawOffset() + 30*60*1000;\r
1074             try {\r
1075                 tz.setRawOffset(newRawOffset);\r
1076             } catch (Exception e) {\r
1077                 errln("FAIL: setRawOffset throws an exception");\r
1078             }\r
1079             int offset = tz.getRawOffset();\r
1080             if (offset != newRawOffset) {\r
1081                 errln("FAIL: Modified zone(" + tz.getID() + ") - getRawOffset returns " + offset + "/ Expected: " + newRawOffset);\r
1082             }\r
1083             // Ticket#5917\r
1084             // Check if DST observation status is not unexpectedly changed.\r
1085             boolean newDst = tz.useDaylightTime();\r
1086             if (useDst != newDst) {\r
1087                 errln("FAIL: Modified zone(" + tz.getID() + ") - useDaylightTime has changed from " + useDst + " to " + newDst);\r
1088             }\r
1089             // Make sure the offset is preserved in a clone\r
1090             TimeZone tzClone = (TimeZone)tz.clone();\r
1091             offset = tzClone.getRawOffset();\r
1092             if (offset != newRawOffset) {\r
1093                 errln("FAIL: Cloned modified zone(" + tz.getID() + ") - getRawOffset returns " + offset + "/ Expected: " + newRawOffset);\r
1094             }\r
1095         }\r
1096     }\r
1097 \r
1098     /*\r
1099      * Zone ID is not set by a SimpleTimeZone constructor\r
1100      */\r
1101     public void TestT5432() {\r
1102         String tzid = "MyZone";\r
1103         SimpleTimeZone stz;\r
1104 \r
1105         // 2-arg constructor\r
1106         stz = new SimpleTimeZone(0, tzid);\r
1107         if (!tzid.equals(stz.getID())) {\r
1108             errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected ("\r
1109                     + tzid + ") [2-arg constructor]");\r
1110         }\r
1111 \r
1112         // 10-arg constructor\r
1113         stz = new SimpleTimeZone(0, tzid, 3, -1, 1, 3600000, 9, -1, 1, 3600000);\r
1114         if (!tzid.equals(stz.getID())) {\r
1115             errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected ("\r
1116                     + tzid + ") [10-arg constructor]");\r
1117         }\r
1118 \r
1119         // 11-arg constructor\r
1120         stz = new SimpleTimeZone(0, tzid, 3, -1, 1, 3600000, 9, -1, 1, 3600000, 3600000);\r
1121         if (!tzid.equals(stz.getID())) {\r
1122             errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected ("\r
1123                     + tzid + ") [11-arg constructor]");\r
1124         }\r
1125 \r
1126         // 13-arg constructor - this version had a problem reported by trac#5432\r
1127         stz = new SimpleTimeZone(0, tzid, 3, -1, 1, 3600000, SimpleTimeZone.WALL_TIME,\r
1128                 9, -1, 1, 3600000, SimpleTimeZone.WALL_TIME, 3600000);\r
1129         if (!tzid.equals(stz.getID())) {\r
1130             errln("FAIL: Bad zone id (" + stz.getID() + ") is returned - expected ("\r
1131                     + tzid + ") [13-arg constructor]");\r
1132         }\r
1133     }\r
1134     \r
1135     // test bug #4265\r
1136     public void TestJohannesburg() {\r
1137         String j_id="Africa/Johannesburg";\r
1138         TimeZone johannesburg = TimeZone.getTimeZone(j_id);\r
1139         final int ONE_HOUR = 60*60*1000;\r
1140         int expectedOffset = ONE_HOUR*2;  // GMT+2 - NO DST\r
1141         int offset = johannesburg.getOffset(GregorianCalendar.AD,2007,Calendar.JULY,5,Calendar.THURSDAY,0);        \r
1142         \r
1143         if(offset != expectedOffset) {\r
1144             errln("FAIL: zone " + j_id +" returned offset in July " + offset +", expected "+expectedOffset);\r
1145         } else {\r
1146             logln("OK: zone " + j_id +" returned offset in July: " + offset);\r
1147         }\r
1148 \r
1149         int offset2 = johannesburg.getOffset(GregorianCalendar.AD,2007,Calendar.DECEMBER,12,Calendar.WEDNESDAY,0);\r
1150 \r
1151         if(offset2 != expectedOffset) {\r
1152             errln("FAIL: zone " + j_id +" returned offset in December " + offset2 +", expected "+expectedOffset);\r
1153         } else {\r
1154             logln("OK: zone " + j_id +" returned offset in December: " + offset2);\r
1155         }\r
1156     }\r
1157 \r
1158     public void TestT7107() {\r
1159         Thread[] workers = new Thread[20];\r
1160         for (int i = 0 ; i < workers.length; i++) {\r
1161             workers[i] = new Thread(new Runnable() {\r
1162                 public void run() {\r
1163                     for (int j = 0; j < 10000; j++) {\r
1164                         try {\r
1165                             com.ibm.icu.util.TimeZone.getTimeZone("GMT").getDisplayName();\r
1166                         } catch (Exception e) {\r
1167                             errln("FAIL: Caught an exception " + e);\r
1168                         }\r
1169                     }\r
1170                 }\r
1171             });\r
1172         }\r
1173         for (Thread wk : workers) {\r
1174             wk.start();\r
1175         }\r
1176         for (Thread wk : workers) {\r
1177             try {\r
1178                 wk.join();\r
1179             } catch (InterruptedException ie) {\r
1180                 \r
1181             }\r
1182         }\r
1183     }\r
1184 }\r
1185 \r
1186 //eof\r