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