]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_8_1_1/main/tests/core/src/com/ibm/icu/dev/test/calendar/CalendarRegression.java
Added flags.
[Dictionary.git] / jars / icu4j-4_8_1_1 / main / tests / core / src / com / ibm / icu / dev / test / calendar / CalendarRegression.java
1 /**
2  *******************************************************************************
3  * Copyright (C) 2000-2011, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.dev.test.calendar;
8
9 import java.io.ByteArrayInputStream;
10 import java.io.ByteArrayOutputStream;
11 import java.io.IOException;
12 import java.io.ObjectInputStream;
13 import java.io.ObjectOutputStream;
14 import java.util.Arrays;
15 import java.util.Date;
16 import java.util.HashSet;
17 import java.util.Locale;
18 import java.util.MissingResourceException;
19
20 import com.ibm.icu.text.DateFormat;
21 import com.ibm.icu.text.NumberFormat;
22 import com.ibm.icu.text.SimpleDateFormat;
23 import com.ibm.icu.util.Calendar;
24 import com.ibm.icu.util.GregorianCalendar;
25 import com.ibm.icu.util.SimpleTimeZone;
26 import com.ibm.icu.util.TimeZone;
27 import com.ibm.icu.util.ULocale;
28
29 /**
30  * @test 1.32 99/11/14
31  * @bug 4031502 4035301 4040996 4051765 4059654 4061476 4070502 4071197 4071385
32  * 4073929 4083167 4086724 4092362 4095407 4096231 4096539 4100311 4103271
33  * 4106136 4108764 4114578 4118384 4125881 4125892 4136399 4141665 4142933
34  * 4145158 4145983 4147269 4149677 4162587 4165343 4166109 4167060 4173516
35  * 4174361 4177484 4197699 4209071 4288792
36  */
37 public class CalendarRegression extends com.ibm.icu.dev.test.TestFmwk {
38
39     public static void main(String[] args) throws Exception {
40         new CalendarRegression().run(args);
41     }
42     static final String[] FIELD_NAME = {
43             "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",
44             "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK",
45             "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY",
46             "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
47             "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR",
48             "JULIAN_DAY", "MILLISECONDS_IN_DAY"
49         };
50
51
52     /*
53       Synopsis: java.sql.Timestamp constructor works wrong on Windows 95
54
55       ==== Here is the test ==== 
56       public static void main (String args[]) { 
57         java.sql.Timestamp t= new java.sql.Timestamp(0,15,5,5,8,13,123456700); 
58         logln("expected=1901-04-05 05:08:13.1234567"); 
59         logln(" result="+t); 
60       } 
61       
62       ==== Here is the output of the test on Solaris or NT ==== 
63       expected=1901-04-05 05:08:13.1234567 
64       result=1901-04-05 05:08:13.1234567 
65       
66       ==== Here is the output of the test on Windows95 ==== 
67       expected=1901-04-05 05:08:13.1234567 
68       result=1901-04-05 06:08:13.1234567 
69       */
70
71     public void Test4031502() {
72         try{
73             // This bug actually occurs on Windows NT as well, and doesn't
74             // require the host zone to be set; it can be set in Java.
75             String[] ids = TimeZone.getAvailableIDs();
76             boolean bad = false;
77             for (int i=0; i<ids.length; ++i) {
78                 TimeZone zone = TimeZone.getTimeZone(ids[i]);
79                 GregorianCalendar cal = new GregorianCalendar(zone);
80                 cal.clear();
81                 cal.set(1900, 15, 5, 5, 8, 13);
82                 if (cal.get(Calendar.HOUR) != 5) {
83                     logln("Fail: " + zone.getID() + " " +
84                           zone.useDaylightTime() + "; DST_OFFSET = " +
85                           cal.get(Calendar.DST_OFFSET) / (60*60*1000.0) + "; ZONE_OFFSET = " +
86                           cal.get(Calendar.ZONE_OFFSET) / (60*60*1000.0) + "; getRawOffset() = " +
87                           zone.getRawOffset() / (60*60*1000.0) +
88                           "; HOUR = " + cal.get(Calendar.HOUR));
89                     cal.clear();
90                     cal.set(1900, 15, 5, 5, 8, 13);
91                     if (cal.get(Calendar.HOUR) != 5) {
92                         logln("Fail: " + zone.getID() + " " +
93                               zone.useDaylightTime() + "; DST_OFFSET = " +
94                               cal.get(Calendar.DST_OFFSET) / (60*60*1000.0) + "; ZONE_OFFSET = " +
95                               cal.get(Calendar.ZONE_OFFSET) / (60*60*1000.0) + "; getRawOffset() = " +
96                               zone.getRawOffset() / (60*60*1000.0) +
97                               "; HOUR = " + cal.get(Calendar.HOUR));
98                         cal.clear();
99                         cal.set(1900, 15, 5, 5, 8, 13);
100                         logln("ms = " + cal.getTime() + " (" + cal.getTime().getTime() + ")");
101                         cal.get(Calendar.HOUR);
102                         java.util.GregorianCalendar cal2 = new java.util.GregorianCalendar(java.util.TimeZone.getTimeZone(ids[i]));
103                         cal2.clear();
104                         cal2.set(1900, 15, 5, 5, 8, 13);
105                         cal2.get(Calendar.HOUR);
106                         logln("java.util.GC: " + zone.getID() + " " +
107                             zone.useDaylightTime() + "; DST_OFFSET = " +
108                             cal2.get(Calendar.DST_OFFSET) / (60*60*1000.0) + "; ZONE_OFFSET = " +
109                             cal2.get(Calendar.ZONE_OFFSET) / (60*60*1000.0) + "; getRawOffset() = " +
110                             zone.getRawOffset() / (60*60*1000.0) +
111                             "; HOUR = " + cal.get(Calendar.HOUR));
112                         logln("ms = " + cal2.getTime() + " (" + cal2.getTime().getTime() + ")");
113                         bad = true;
114                     } else if (false) { // Change to true to debug
115                         logln("OK: " + zone.getID() + " " +
116                               zone.useDaylightTime() + " " +
117                               cal.get(Calendar.DST_OFFSET) / (60*60*1000) + " " +
118                               zone.getRawOffset() / (60*60*1000) +
119                               ": HOUR = " + cal.get(Calendar.HOUR));
120                     }
121                 }
122                 if (bad) errln("TimeZone problems with GC");
123             }
124         } catch (MissingResourceException e) {
125             warnln("Could not load data. "+ e.getMessage());
126         }
127     }
128
129     public void Test4035301() {
130         
131         try {
132             GregorianCalendar c = new GregorianCalendar(98, 8, 7);
133             GregorianCalendar d = new GregorianCalendar(98, 8, 7);
134             if (c.after(d) ||
135                 c.after(c) ||
136                 c.before(d) ||
137                 c.before(c) ||
138                 !c.equals(c) ||
139                 !c.equals(d))
140                 errln("Fail");
141         } catch (Exception e) {
142             // TODO Auto-generated catch block
143             warnln("Could not load data. "+ e.getMessage());
144         }
145     }
146
147     public void Test4040996() {
148         try {
149             String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
150             SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, ids[0]);
151             pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
152             pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
153             Calendar calendar = new GregorianCalendar(pdt);
154
155             calendar.set(Calendar.MONTH,3);
156             calendar.set(Calendar.DAY_OF_MONTH,18);
157             calendar.set(Calendar.SECOND, 30);
158
159             logln("MONTH: " + calendar.get(Calendar.MONTH));
160             logln("DAY_OF_MONTH: " + 
161                                calendar.get(Calendar.DAY_OF_MONTH));
162             logln("MINUTE: " + calendar.get(Calendar.MINUTE));
163             logln("SECOND: " + calendar.get(Calendar.SECOND));
164
165             calendar.add(Calendar.SECOND,6);
166             //This will print out todays date for MONTH and DAY_OF_MONTH
167             //instead of the date it was set to.
168             //This happens when adding MILLISECOND or MINUTE also
169             logln("MONTH: " + calendar.get(Calendar.MONTH));
170             logln("DAY_OF_MONTH: " + 
171                                calendar.get(Calendar.DAY_OF_MONTH));
172             logln("MINUTE: " + calendar.get(Calendar.MINUTE));
173             logln("SECOND: " + calendar.get(Calendar.SECOND));
174             if (calendar.get(Calendar.MONTH) != 3 ||
175                 calendar.get(Calendar.DAY_OF_MONTH) != 18 ||
176                 calendar.get(Calendar.SECOND) != 36)
177                 errln("Fail: Calendar.add misbehaves");
178         } catch (Exception e) {
179             warnln("Could not load data. "+ e.getMessage());
180         }
181     }
182
183     public void Test4051765() {
184         try {
185             Calendar cal = Calendar.getInstance();
186             cal.setLenient(false);
187             cal.set(Calendar.DAY_OF_WEEK, 0);
188             try {
189                 cal.getTime();
190                 errln("Fail: DAY_OF_WEEK 0 should be disallowed");
191             }
192             catch (IllegalArgumentException e) {
193                 return;
194             }
195         } catch (Exception e) {
196             // TODO Auto-generated catch block
197             warnln("Could not load data. "+ e.getMessage());
198         }
199     }
200     
201     /*
202      * User error - no bug here public void Test4059524() { // Create calendar
203      * for April 10, 1997 GregorianCalendar calendar = new GregorianCalendar(); //
204      * print out a bunch of interesting things logln("ERA: " +
205      * calendar.get(calendar.ERA)); logln("YEAR: " +
206      * calendar.get(calendar.YEAR)); logln("MONTH: " +
207      * calendar.get(calendar.MONTH)); logln("WEEK_OF_YEAR: " +
208      * calendar.get(calendar.WEEK_OF_YEAR)); logln("WEEK_OF_MONTH: " +
209      * calendar.get(calendar.WEEK_OF_MONTH)); logln("DATE: " +
210      * calendar.get(calendar.DATE)); logln("DAY_OF_MONTH: " +
211      * calendar.get(calendar.DAY_OF_MONTH)); logln("DAY_OF_YEAR: " +
212      * calendar.get(calendar.DAY_OF_YEAR)); logln("DAY_OF_WEEK: " +
213      * calendar.get(calendar.DAY_OF_WEEK)); logln("DAY_OF_WEEK_IN_MONTH: " +
214      * calendar.get(calendar.DAY_OF_WEEK_IN_MONTH)); logln("AM_PM: " +
215      * calendar.get(calendar.AM_PM)); logln("HOUR: " +
216      * calendar.get(calendar.HOUR)); logln("HOUR_OF_DAY: " +
217      * calendar.get(calendar.HOUR_OF_DAY)); logln("MINUTE: " +
218      * calendar.get(calendar.MINUTE)); logln("SECOND: " +
219      * calendar.get(calendar.SECOND)); logln("MILLISECOND: " +
220      * calendar.get(calendar.MILLISECOND)); logln("ZONE_OFFSET: " +
221      * (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); logln("DST_OFFSET: " +
222      * (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); calendar = new
223      * GregorianCalendar(1997,3,10); calendar.getTime(); logln("April 10,
224      * 1997"); logln("ERA: " + calendar.get(calendar.ERA)); logln("YEAR: " +
225      * calendar.get(calendar.YEAR)); logln("MONTH: " +
226      * calendar.get(calendar.MONTH)); logln("WEEK_OF_YEAR: " +
227      * calendar.get(calendar.WEEK_OF_YEAR)); logln("WEEK_OF_MONTH: " +
228      * calendar.get(calendar.WEEK_OF_MONTH)); logln("DATE: " +
229      * calendar.get(calendar.DATE)); logln("DAY_OF_MONTH: " +
230      * calendar.get(calendar.DAY_OF_MONTH)); logln("DAY_OF_YEAR: " +
231      * calendar.get(calendar.DAY_OF_YEAR)); logln("DAY_OF_WEEK: " +
232      * calendar.get(calendar.DAY_OF_WEEK)); logln("DAY_OF_WEEK_IN_MONTH: " +
233      * calendar.get(calendar.DAY_OF_WEEK_IN_MONTH)); logln("AM_PM: " +
234      * calendar.get(calendar.AM_PM)); logln("HOUR: " +
235      * calendar.get(calendar.HOUR)); logln("HOUR_OF_DAY: " +
236      * calendar.get(calendar.HOUR_OF_DAY)); logln("MINUTE: " +
237      * calendar.get(calendar.MINUTE)); logln("SECOND: " +
238      * calendar.get(calendar.SECOND)); logln("MILLISECOND: " +
239      * calendar.get(calendar.MILLISECOND)); logln("ZONE_OFFSET: " +
240      * (calendar.get(calendar.ZONE_OFFSET)/(60*60*1000))); // in hours
241      * logln("DST_OFFSET: " + (calendar.get(calendar.DST_OFFSET)/(60*60*1000))); //
242      * in hours }
243      */
244
245     public void Test4059654() {
246    //     try {
247             // work around bug for jdk1.4 on solaris 2.6, which uses funky
248             // timezone names
249             // jdk1.4.1 will drop support for 2.6 so we should be ok when it
250             // comes out
251             java.util.TimeZone javazone = java.util.TimeZone.getTimeZone("GMT");
252             TimeZone icuzone = TimeZone.getTimeZone("GMT");
253
254             GregorianCalendar gc = new GregorianCalendar(icuzone);
255             
256             gc.set(1997, 3, 1, 15, 16, 17); // April 1, 1997
257
258             gc.set(Calendar.HOUR, 0);
259             gc.set(Calendar.AM_PM, Calendar.AM);
260             gc.set(Calendar.MINUTE, 0);
261             gc.set(Calendar.SECOND, 0);
262             gc.set(Calendar.MILLISECOND, 0);
263
264             Date cd = gc.getTime();
265             java.util.Calendar cal = java.util.Calendar.getInstance(javazone);
266             cal.clear();
267             cal.set(1997, 3, 1, 0, 0, 0);
268             Date exp = cal.getTime();
269             if (!cd.equals(exp))
270                 errln("Fail: Calendar.set broken. Got " + cd + " Want " + exp);
271    //     } catch (RuntimeException e) {
272             // TODO Auto-generated catch block
273    //         e.printStackTrace();
274   //      }
275     }
276
277     public void Test4061476() {
278         SimpleDateFormat fmt = new SimpleDateFormat("ddMMMyy", Locale.UK);
279         Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"), 
280                                                      Locale.UK);
281         fmt.setCalendar(cal);
282         try
283             {
284                 Date date = fmt.parse("29MAY97");
285                 cal.setTime(date);
286             }
287         catch (Exception e) {
288             System.out.print("");
289         }
290         cal.set(Calendar.HOUR_OF_DAY, 13);
291         logln("Hour: "+cal.get(Calendar.HOUR_OF_DAY));
292         cal.add(Calendar.HOUR_OF_DAY, 6);
293         logln("Hour: "+cal.get(Calendar.HOUR_OF_DAY));
294         if (cal.get(Calendar.HOUR_OF_DAY) != 19)
295             errln("Fail: Want 19 Got " + cal.get(Calendar.HOUR_OF_DAY));
296     }
297
298     public void Test4070502() {
299         java.util.Calendar tempcal = java.util.Calendar.getInstance();
300         tempcal.clear();
301         tempcal.set(1998, 0, 30);
302         Date d = getAssociatedDate(tempcal.getTime());
303         Calendar cal = new GregorianCalendar();
304         cal.setTime(d);
305         if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY ||
306             cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
307             errln("Fail: Want weekday Got " + d);
308     }
309
310     /**
311      * Get the associated date starting from a specified date NOTE: the
312      * unnecessary "getTime()'s" below are a work-around for a bug in jdk 1.1.3
313      * (and probably earlier versions also)
314      * <p>
315      * 
316      * @param d
317      *            The date to start from
318      */
319     public static Date getAssociatedDate(Date d) {
320         GregorianCalendar cal = new GregorianCalendar();
321         cal.setTime(d);
322         //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
323         // cal.getTime(); // <--- REMOVE THIS TO SEE BUG
324         while (true) {
325             int wd = cal.get(Calendar.DAY_OF_WEEK);
326             if (wd == Calendar.SATURDAY || wd == Calendar.SUNDAY) {
327                 cal.add(Calendar.DATE, 1);
328                 // cal.getTime();
329             }
330             else
331                 break;
332         }
333         return cal.getTime();
334     }
335
336     public void Test4071197() {
337         dowTest(false);
338         dowTest(true);
339     }
340
341     void dowTest(boolean lenient) {
342         GregorianCalendar cal = new GregorianCalendar();
343         cal.set(1997, Calendar.AUGUST, 12); // Wednesday
344         // cal.getTime(); // Force update
345         cal.setLenient(lenient);
346         cal.set(1996, Calendar.DECEMBER, 1); // Set the date to be December 1,
347                                              // 1996
348         int dow = cal.get(Calendar.DAY_OF_WEEK);
349         int min = cal.getMinimum(Calendar.DAY_OF_WEEK);
350         int max = cal.getMaximum(Calendar.DAY_OF_WEEK);
351         logln(cal.getTime().toString());
352         if (min != Calendar.SUNDAY || max != Calendar.SATURDAY)
353             errln("FAIL: Min/max bad");
354         if (dow < min || dow > max) 
355             errln("FAIL: Day of week " + dow + " out of range");
356         if (dow != Calendar.SUNDAY) 
357             errln("FAIL: Day of week should be SUNDAY Got " + dow);
358     }
359
360     public void Test4071385() {
361     // work around bug for jdk1.4 on solaris 2.6, which uses funky timezone
362     // names
363     // jdk1.4.1 will drop support for 2.6 so we should be ok when it comes out
364     java.util.TimeZone javazone = java.util.TimeZone.getTimeZone("GMT");
365     TimeZone icuzone = TimeZone.getTimeZone("GMT");
366
367         Calendar cal = Calendar.getInstance(icuzone);
368         java.util.Calendar tempcal = java.util.Calendar.getInstance(javazone);
369         tempcal.clear();
370         tempcal.set(1998, Calendar.JUNE, 24);
371         cal.setTime(tempcal.getTime());
372         cal.set(Calendar.MONTH, Calendar.NOVEMBER); // change a field
373         logln(cal.getTime().toString());
374         tempcal.set(1998, Calendar.NOVEMBER, 24);
375         if (!cal.getTime().equals(tempcal.getTime()))
376             errln("Fail");
377     }
378
379     public void Test4073929() {
380         GregorianCalendar foo1 = new GregorianCalendar(1997, 8, 27);
381         foo1.add(Calendar.DAY_OF_MONTH, +1);
382         int testyear = foo1.get(Calendar.YEAR);
383         int testmonth = foo1.get(Calendar.MONTH);
384         int testday = foo1.get(Calendar.DAY_OF_MONTH);
385         if (testyear != 1997 ||
386             testmonth != 8 ||
387             testday != 28)
388             errln("Fail: Calendar not initialized");
389     }
390
391     public void Test4083167() {
392         TimeZone saveZone = TimeZone.getDefault();
393         try {
394             TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
395             Date firstDate = new Date();
396             Calendar cal = new GregorianCalendar();
397             cal.setTime(firstDate);
398             long firstMillisInDay = cal.get(Calendar.HOUR_OF_DAY) * 3600000L +
399                 cal.get(Calendar.MINUTE) * 60000L +
400                 cal.get(Calendar.SECOND) * 1000L +
401                 cal.get(Calendar.MILLISECOND);
402             
403             logln("Current time: " + firstDate.toString());
404
405             for (int validity=0; validity<30; validity++) {
406                 Date lastDate = new Date(firstDate.getTime() +
407                                          (long)validity*1000*24*60*60);
408                 cal.setTime(lastDate);
409                 long millisInDay = cal.get(Calendar.HOUR_OF_DAY) * 3600000L +
410                     cal.get(Calendar.MINUTE) * 60000L +
411                     cal.get(Calendar.SECOND) * 1000L +
412                     cal.get(Calendar.MILLISECOND);
413                 if (firstMillisInDay != millisInDay) 
414                     errln("Day has shifted " + lastDate);
415             }
416         }
417         finally {
418             TimeZone.setDefault(saveZone);
419         }
420     }
421
422     public void Test4086724() {
423         SimpleDateFormat date;
424         TimeZone saveZone = TimeZone.getDefault();
425         Locale saveLocale = Locale.getDefault();
426         try {
427             Locale.setDefault(Locale.UK); 
428             TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
429             date=new SimpleDateFormat("dd MMM yyy (zzzz) 'is in week' ww"); 
430             Calendar cal=Calendar.getInstance(); 
431             cal.set(1997,Calendar.SEPTEMBER,30); 
432             Date now=cal.getTime(); 
433             logln(date.format(now)); 
434             cal.set(1997,Calendar.JANUARY,1); 
435             now=cal.getTime(); 
436             logln(date.format(now)); 
437             cal.set(1997,Calendar.JANUARY,8); 
438             now=cal.getTime(); 
439             logln(date.format(now)); 
440             cal.set(1996,Calendar.DECEMBER,31); 
441             now=cal.getTime(); 
442             logln(date.format(now)); 
443         }
444         finally {
445             Locale.setDefault(saveLocale);
446             TimeZone.setDefault(saveZone);
447         }
448         logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
449     }
450
451     public void Test4092362() {
452         GregorianCalendar cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40); 
453         /*
454          * cal1.set( Calendar.YEAR, 1997 ); cal1.set( Calendar.MONTH, 10 );
455          * cal1.set( Calendar.DATE, 11 ); cal1.set( Calendar.HOUR, 10 );
456          * cal1.set( Calendar.MINUTE, 20 ); cal1.set( Calendar.SECOND, 40 );
457          */
458
459         logln( " Cal1 = " + cal1.getTime().getTime() ); 
460         logln( " Cal1 time in ms = " + cal1.get(Calendar.MILLISECOND) ); 
461         for( int k = 0; k < 100 ; k++ ) {
462             System.out.print(""); 
463         }
464
465         GregorianCalendar cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40); 
466         /*
467          * cal2.set( Calendar.YEAR, 1997 ); cal2.set( Calendar.MONTH, 10 );
468          * cal2.set( Calendar.DATE, 11 ); cal2.set( Calendar.HOUR, 10 );
469          * cal2.set( Calendar.MINUTE, 20 ); cal2.set( Calendar.SECOND, 40 );
470          */
471
472         logln( " Cal2 = " + cal2.getTime().getTime() ); 
473         logln( " Cal2 time in ms = " + cal2.get(Calendar.MILLISECOND) ); 
474         if( !cal1.equals( cal2 ) ) 
475             errln("Fail: Milliseconds randomized");
476     }
477
478     public void Test4095407() {
479         GregorianCalendar a = new GregorianCalendar(1997,Calendar.NOVEMBER, 13);
480         int dow = a.get(Calendar.DAY_OF_WEEK);
481         if (dow != Calendar.THURSDAY)
482             errln("Fail: Want THURSDAY Got " + dow);
483     }
484
485     public void Test4096231() {
486         TimeZone GMT = TimeZone.getTimeZone("GMT");
487         TimeZone PST = TimeZone.getTimeZone("PST");
488         int sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997;
489                             
490         Calendar cal1 = new GregorianCalendar(PST);
491         cal1.setTime(new Date(880698639000L));
492         int p;
493         logln("PST 1 is: " + (p=cal1.get(Calendar.HOUR_OF_DAY)));
494         cal1.setTimeZone(GMT);
495         // Issue 1: Changing the timezone doesn't change the
496         //          represented time.
497         int h1,h2;
498         logln("GMT 1 is: " + (h1=cal1.get(Calendar.HOUR_OF_DAY)));
499         cal1.setTime(new Date(880698639000L));
500         logln("GMT 2 is: " + (h2=cal1.get(Calendar.HOUR_OF_DAY)));
501         // Note: This test had a bug in it. It wanted h1!=h2, when
502         // what was meant was h1!=p. Fixed this concurrent with fix
503         // to 4177484.
504         if (p == h1 || h1 != h2)
505             errln("Fail: Hour same in different zones");
506
507         Calendar cal2 = new GregorianCalendar(GMT);
508         Calendar cal3 = new GregorianCalendar(PST);
509         cal2.set(Calendar.MILLISECOND, 0);
510         cal3.set(Calendar.MILLISECOND, 0);
511
512         cal2.set(cal1.get(Calendar.YEAR),
513                  cal1.get(Calendar.MONTH),
514                  cal1.get(Calendar.DAY_OF_MONTH),
515                  cal1.get(Calendar.HOUR_OF_DAY),
516                  cal1.get(Calendar.MINUTE),
517                  cal1.get(Calendar.SECOND));
518
519         long t1,t2,t3,t4;
520         logln("RGMT 1 is: " + (t1=cal2.getTime().getTime()));
521         cal3.set(year, month, day, hr, min, sec);
522         logln("RPST 1 is: " + (t2=cal3.getTime().getTime()));
523         cal3.setTimeZone(GMT);
524         logln("RGMT 2 is: " + (t3=cal3.getTime().getTime()));
525         cal3.set(cal1.get(Calendar.YEAR),
526                  cal1.get(Calendar.MONTH),
527                  cal1.get(Calendar.DAY_OF_MONTH),
528                  cal1.get(Calendar.HOUR_OF_DAY),
529                  cal1.get(Calendar.MINUTE),
530                  cal1.get(Calendar.SECOND));
531         // Issue 2: Calendar continues to use the timezone in its
532         //          constructor for set() conversions, regardless
533         //          of calls to setTimeZone()
534         logln("RGMT 3 is: " + (t4=cal3.getTime().getTime()));
535         if (t1 == t2 ||
536             t1 != t4 ||
537             t2 != t3)
538             errln("Fail: Calendar zone behavior faulty");
539     }
540
541     public void Test4096539() {
542         int[] y = {31,28,31,30,31,30,31,31,30,31,30,31};
543
544         for (int x=0;x<12;x++) {
545             GregorianCalendar gc = new 
546                 GregorianCalendar(1997,x,y[x]);
547             int m1,m2;
548             log((m1=gc.get(Calendar.MONTH)+1)+"/"+
549                              gc.get(Calendar.DATE)+"/"+gc.get(Calendar.YEAR)+
550                              " + 1mo = ");
551
552             gc.add(Calendar.MONTH, 1);
553             logln((m2=gc.get(Calendar.MONTH)+1)+"/"+
554                                gc.get(Calendar.DATE)+"/"+gc.get(Calendar.YEAR)
555                                );
556             int m = (m1 % 12) + 1;
557             if (m2 != m)
558                 errln("Fail: Want " + m + " Got " + m2);
559         }
560         
561     }
562
563     public void Test4100311() {
564         GregorianCalendar cal = (GregorianCalendar)Calendar.getInstance();
565         cal.set(Calendar.YEAR, 1997);
566         cal.set(Calendar.DAY_OF_YEAR, 1);
567         Date d = cal.getTime();             // Should be Jan 1
568         logln(d.toString());
569         if (cal.get(Calendar.DAY_OF_YEAR) != 1)
570             errln("Fail: DAY_OF_YEAR not set");
571     }
572
573     public void Test4103271() {
574         SimpleDateFormat sdf = new SimpleDateFormat(); 
575         int numYears=40, startYear=1997, numDays=15; 
576         String output, testDesc; 
577         GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance(); 
578         testCal.clear();
579         sdf.setCalendar(testCal); 
580         sdf.applyPattern("d MMM yyyy"); 
581         boolean fail = false;
582         for (int firstDay=1; firstDay<=2; firstDay++) { 
583             for (int minDays=1; minDays<=7; minDays++) { 
584                 testCal.setMinimalDaysInFirstWeek(minDays); 
585                 testCal.setFirstDayOfWeek(firstDay); 
586                 testDesc = ("Test" + String.valueOf(firstDay) + String.valueOf(minDays)); 
587                 logln(testDesc + " => 1st day of week=" +
588                                    String.valueOf(firstDay) +
589                                    ", minimum days in first week=" +
590                                    String.valueOf(minDays)); 
591                 for (int j=startYear; j<=startYear+numYears; j++) { 
592                     testCal.set(j,11,25); 
593                     for(int i=0; i<numDays; i++) { 
594                         testCal.add(Calendar.DATE,1); 
595                         String calWOY; 
596                         int actWOY = testCal.get(Calendar.WEEK_OF_YEAR);
597                         if (actWOY < 1 || actWOY > 53) {
598                             Date d = testCal.getTime(); 
599                             calWOY = String.valueOf(actWOY); 
600                             output = testDesc + " - " + sdf.format(d) + "\t"; 
601                             output = output + "\t" + calWOY; 
602                             logln(output); 
603                             fail = true;
604                         }
605                     } 
606                 } 
607             } 
608         } 
609
610         int[] DATA = {
611             3, 52, 52, 52, 52, 52, 52, 52,
612                 1,  1,  1,  1,  1,  1,  1,
613                 2,  2,  2,  2,  2,  2,  2,
614             4, 52, 52, 52, 52, 52, 52, 52,
615                53, 53, 53, 53, 53, 53, 53,
616                 1,  1,  1,  1,  1,  1,  1,
617         };
618         testCal.setFirstDayOfWeek(Calendar.SUNDAY);
619         for (int j=0; j<DATA.length; j+=22) {
620             logln("Minimal days in first week = " + DATA[j] +
621                                "  Week starts on Sunday");
622             testCal.setMinimalDaysInFirstWeek(DATA[j]);
623             testCal.set(1997, Calendar.DECEMBER, 21);
624             for (int i=0; i<21; ++i) {
625                 int woy = testCal.get(Calendar.WEEK_OF_YEAR);
626                 log(testCal.getTime() + " " + woy);
627                 if (woy != DATA[j + 1 + i]) {
628                     log(" ERROR");
629                     fail = true;
630                 }
631                 //logln();
632                 
633                 // Now compute the time from the fields, and make sure we
634                 // get the same answer back. This is a round-trip test.
635                 Date save = testCal.getTime();
636                 testCal.clear();
637                 testCal.set(Calendar.YEAR, DATA[j+1+i] < 25 ? 1998 : 1997);
638                 testCal.set(Calendar.WEEK_OF_YEAR, DATA[j+1+i]);
639                 testCal.set(Calendar.DAY_OF_WEEK, (i%7) + Calendar.SUNDAY);
640                 if (!testCal.getTime().equals(save)) {
641                     logln("  Parse failed: " + testCal.getTime());
642                     fail= true;
643                 }
644
645                 testCal.setTime(save);
646                 testCal.add(Calendar.DAY_OF_MONTH, 1);
647             }
648         }
649
650         Date d[] = new Date[8];
651         java.util.Calendar tempcal = java.util.Calendar.getInstance();
652         tempcal.clear();
653         tempcal.set(1997, Calendar.DECEMBER, 28);
654         d[0] = tempcal.getTime();
655         tempcal.set(1998, Calendar.JANUARY, 10);
656         d[1] = tempcal.getTime();
657         tempcal.set(1998, Calendar.DECEMBER, 31);
658         d[2] = tempcal.getTime();
659         tempcal.set(1999, Calendar.JANUARY, 1);
660         d[3] = tempcal.getTime();
661         // Test field disambiguation with a few special hard-coded cases.
662         // This shouldn't fail if the above cases aren't failing.
663         Object[] DISAM = {
664             new Integer(1998), new Integer(1), new Integer(Calendar.SUNDAY),
665                 d[0],
666             new Integer(1998), new Integer(2), new Integer(Calendar.SATURDAY),
667                 d[1],
668             new Integer(1998), new Integer(53), new Integer(Calendar.THURSDAY),
669                 d[2],
670             new Integer(1998), new Integer(53), new Integer(Calendar.FRIDAY),
671                 d[3],
672         };
673         testCal.setMinimalDaysInFirstWeek(3);
674         testCal.setFirstDayOfWeek(Calendar.SUNDAY);
675         for (int i=0; i<DISAM.length; i+=4) {
676             int y = ((Integer)DISAM[i]).intValue();
677             int woy = ((Integer)DISAM[i+1]).intValue();
678             int dow = ((Integer)DISAM[i+2]).intValue();
679             Date exp = (Date)DISAM[i+3];
680             testCal.clear();
681             testCal.set(Calendar.YEAR, y);
682             testCal.set(Calendar.WEEK_OF_YEAR, woy);
683             testCal.set(Calendar.DAY_OF_WEEK, dow);
684             log(y + "-W" + woy +
685                              "-DOW" + dow + " expect:" + exp +
686                              " got:" + testCal.getTime());
687             if (!testCal.getTime().equals(exp)) {
688                 log("  FAIL");
689                 fail = true;
690             }
691             //logln();
692         }
693
694         // Now try adding and rolling
695         Object ADD = new Object();
696         Object ROLL = new Object();
697         tempcal.set(1998, Calendar.DECEMBER, 25);
698         d[0] = tempcal.getTime();
699         tempcal.set(1999, Calendar.JANUARY, 1);
700         d[1] = tempcal.getTime();
701         tempcal.set(1997, Calendar.DECEMBER, 28);
702         d[2] = tempcal.getTime();
703         tempcal.set(1998, Calendar.JANUARY, 4);
704         d[3] = tempcal.getTime();
705         tempcal.set(1998, Calendar.DECEMBER, 27);
706         d[4] = tempcal.getTime();
707         tempcal.set(1997, Calendar.DECEMBER, 28);
708         d[5] = tempcal.getTime();
709         tempcal.set(1999, Calendar.JANUARY, 2);
710         d[6] = tempcal.getTime();
711         tempcal.set(1998, Calendar.JANUARY, 3);
712         d[7] = tempcal.getTime();
713         
714         Object[] ADDROLL = {
715             ADD, new Integer(1), d[0], d[1],
716             ADD, new Integer(1), d[2], d[3],
717             ROLL, new Integer(1), d[4], d[5],
718             ROLL, new Integer(1), d[6], d[7],
719         };
720         testCal.setMinimalDaysInFirstWeek(3);
721         testCal.setFirstDayOfWeek(Calendar.SUNDAY);
722         for (int i=0; i<ADDROLL.length; i+=4) {
723             int amount = ((Integer)ADDROLL[i+1]).intValue();
724             Date before = (Date)ADDROLL[i+2];
725             Date after = (Date)ADDROLL[i+3];
726
727             testCal.setTime(before);
728             if (ADDROLL[i] == ADD) testCal.add(Calendar.WEEK_OF_YEAR, amount);
729             else testCal.roll(Calendar.WEEK_OF_YEAR, amount);
730             log((ADDROLL[i]==ADD?"add(WOY,":"roll(WOY,") +
731                              amount + ") " + before + " => " +
732                              testCal.getTime());
733             if (!after.equals(testCal.getTime())) {
734                 logln("  exp:" + after + "  FAIL");
735                 fail = true;
736             }
737             else logln(" ok");
738
739             testCal.setTime(after);
740             if (ADDROLL[i] == ADD) testCal.add(Calendar.WEEK_OF_YEAR, -amount);
741             else testCal.roll(Calendar.WEEK_OF_YEAR, -amount);
742             log((ADDROLL[i]==ADD?"add(WOY,":"roll(WOY,") +
743                              (-amount) + ") " + after + " => " +
744                              testCal.getTime());
745             if (!before.equals(testCal.getTime())) {
746                 logln("  exp:" + before + "  FAIL");
747                 fail = true;
748             }
749             else logln(" ok");
750         }
751
752         if (fail) errln("Fail: Week of year misbehaving");
753     } 
754
755     public void Test4106136() {
756         Locale saveLocale = Locale.getDefault();
757         String[] names = { "Calendar", "DateFormat", "NumberFormat" };
758         try {
759             Locale[] locales = { Locale.CHINESE, Locale.CHINA };
760             for (int i=0; i<locales.length; ++i) {
761                 Locale.setDefault(locales[i]);
762                 int[] n = {
763                     Calendar.getAvailableLocales().length,
764                     DateFormat.getAvailableLocales().length,
765                     NumberFormat.getAvailableLocales().length
766                 };
767                 for (int j=0; j<n.length; ++j) {
768                     if (n[j] == 0)
769                         errln("Fail: " + names[j] + " has no locales for " + locales[i]);
770                 }
771             }
772         }
773         finally {
774             Locale.setDefault(saveLocale);
775         }
776     }
777
778     public void Test4108764() {
779         java.util.Calendar tempcal = java.util.Calendar.getInstance();
780         tempcal.clear();
781         tempcal.set(1997, Calendar.FEBRUARY, 15, 12, 00, 00);
782         Date d00 = tempcal.getTime();
783         tempcal.set(1997, Calendar.FEBRUARY, 15, 12, 00, 56);
784         Date d01 = tempcal.getTime();
785         tempcal.set(1997, Calendar.FEBRUARY, 15, 12, 34, 00);
786         Date d10 = tempcal.getTime();
787         tempcal.set(1997, Calendar.FEBRUARY, 15, 12, 34, 56);
788         Date d11 = tempcal.getTime();
789         tempcal.set(1997, Calendar.JANUARY, 15, 12, 34, 56);
790         Date dM  = tempcal.getTime();
791         tempcal.clear();
792         tempcal.set(1970, Calendar.JANUARY, 1);
793         Date epoch = tempcal.getTime();
794
795         Calendar cal = Calendar.getInstance(); 
796         cal.setTime(d11);
797
798         cal.clear( Calendar.MINUTE ); 
799         logln(cal.getTime().toString()); 
800         if (!cal.getTime().equals(d01)) {
801             errln("Fail: " + d11 + " clear(MINUTE) => expect " +
802                   d01 + ", got " + cal.getTime());
803         }
804
805         cal.set( Calendar.SECOND, 0 ); 
806         logln(cal.getTime().toString()); 
807         if (!cal.getTime().equals(d00))
808             errln("Fail: set(SECOND, 0) broken");
809
810         cal.setTime(d11);
811         cal.set( Calendar.SECOND, 0 ); 
812         logln(cal.getTime().toString()); 
813         if (!cal.getTime().equals(d10))
814             errln("Fail: set(SECOND, 0) broken #2");
815
816         cal.clear( Calendar.MINUTE ); 
817         logln(cal.getTime().toString()); 
818         if (!cal.getTime().equals(d00))
819             errln("Fail: clear(MINUTE) broken #2");
820
821         cal.clear();
822         logln(cal.getTime().toString());
823         if (!cal.getTime().equals(epoch))
824             errln("Fail: after clear() expect " + epoch + ", got " + cal.getTime());
825
826         cal.setTime(d11);
827         cal.clear( Calendar.MONTH ); 
828         logln(cal.getTime().toString()); 
829         if (!cal.getTime().equals(dM)) {
830             errln("Fail: " + d11 + " clear(MONTH) => expect " +
831                   dM + ", got " + cal.getTime());
832         }
833     }
834
835     public void Test4114578() {
836         int ONE_HOUR = 60*60*1000;
837         Calendar cal = Calendar.getInstance();
838         cal.setTimeZone(TimeZone.getTimeZone("PST"));
839         
840         java.util.Calendar tempcal = java.util.Calendar.getInstance();
841         tempcal.clear();
842         tempcal.set(1998, Calendar.APRIL, 5, 1, 0);
843         long onset = tempcal.getTime().getTime() + ONE_HOUR;
844         tempcal.set(1998, Calendar.OCTOBER, 25, 0, 0);
845         long cease = tempcal.getTime().getTime() + 2*ONE_HOUR;
846
847         boolean fail = false;
848         
849         final int ADD = 1;
850         final int ROLL = 2;
851
852         long[] DATA = {
853             // Start Action Amt Expected_change
854             onset - ONE_HOUR,   ADD,      1,     ONE_HOUR,
855             onset,              ADD,     -1,    -ONE_HOUR,
856             onset - ONE_HOUR,   ROLL,     1,     ONE_HOUR,
857             onset,              ROLL,    -1,    -ONE_HOUR,
858             cease - ONE_HOUR,   ADD,      1,     ONE_HOUR,
859             cease,              ADD,     -1,    -ONE_HOUR,
860             cease - ONE_HOUR,   ROLL,     1,     ONE_HOUR,
861             cease,              ROLL,    -1,    -ONE_HOUR,
862         };
863
864         for (int i=0; i<DATA.length; i+=4) {
865             Date date = new Date(DATA[i]);
866             int amt = (int) DATA[i+2];
867             long expectedChange = DATA[i+3];
868             
869             log(date.toString());
870             cal.setTime(date);
871
872             switch ((int) DATA[i+1]) {
873             case ADD:
874                 log(" add (HOUR," + (amt<0?"":"+")+amt + ")= ");
875                 cal.add(Calendar.HOUR, amt);
876                 break;
877             case ROLL:
878                 log(" roll(HOUR," + (amt<0?"":"+")+amt + ")= ");
879                 cal.roll(Calendar.HOUR, amt);
880                 break;
881             }
882
883             log(cal.getTime().toString());
884
885             long change = cal.getTime().getTime() - date.getTime();
886             if (change != expectedChange) {
887                 fail = true;
888                 logln(" FAIL");
889             }
890             else logln(" OK");
891         }
892
893         if (fail) errln("Fail: roll/add misbehaves around DST onset/cease");
894     }
895
896     /**
897      * Make sure maximum for HOUR field is 11, not 12.
898      */
899     public void Test4118384() {
900         Calendar cal = Calendar.getInstance();
901         if (cal.getMaximum(Calendar.HOUR) != 11 ||
902             cal.getLeastMaximum(Calendar.HOUR) != 11 ||
903             cal.getActualMaximum(Calendar.HOUR) != 11)
904             errln("Fail: maximum of HOUR field should be 11");
905     }
906
907     /**
908      * Check isLeapYear for BC years.
909      */
910     public void Test4125881() {
911         GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
912         DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
913         cal.clear();
914         for (int y=-20; y<=10; ++y) {
915             cal.set(Calendar.ERA, y < 1 ? GregorianCalendar.BC : GregorianCalendar.AD);
916             cal.set(Calendar.YEAR, y < 1 ? 1 - y : y);
917             logln(y + " = " + fmt.format(cal.getTime()) + " " +
918                                cal.isLeapYear(y));
919             if (cal.isLeapYear(y) != ((y+40)%4 == 0))
920                 errln("Leap years broken");
921         }
922     }
923
924     // I am disabling this test -- it is currently failing because of a bug
925     // in Sun's latest change to STZ.getOffset(). I have filed a Sun bug
926     // against this problem.
927
928     // Re-enabled after 'porting' TZ and STZ from java.util to com.ibm.icu.util.
929     /**
930      * Prove that GregorianCalendar is proleptic (it used to cut off at 45 BC,
931      * and not have leap years before then).
932      */
933     public void Test4125892() {
934         GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
935         //DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
936         //fmt = null;
937         cal.clear();
938         cal.set(Calendar.ERA, GregorianCalendar.BC);
939         cal.set(Calendar.YEAR, 81); // 81 BC is a leap year (proleptically)
940         cal.set(Calendar.MONTH, Calendar.FEBRUARY);
941         cal.set(Calendar.DATE, 28);
942         cal.add(Calendar.DATE, 1);
943         if (cal.get(Calendar.DATE) != 29 ||
944             !cal.isLeapYear(-80)) // -80 == 81 BC
945             errln("Calendar not proleptic");
946     }
947
948     /**
949      * Calendar and GregorianCalendar hashCode() methods need improvement.
950      * Calendar needs a good implementation that subclasses can override, and
951      * GregorianCalendar should use that implementation.
952      */
953     public void Test4136399() {
954         /*
955          * Note: This test is actually more strict than it has to be.
956          * Technically, there is no requirement that unequal objects have
957          * unequal hashes. We only require equal objects to have equal hashes.
958          * It is desirable for unequal objects to have distributed hashes, but
959          * there is no hard requirement here.
960          * 
961          * In this test we make assumptions about certain attributes of calendar
962          * objects getting represented in the hash, which need not always be the
963          * case (although it does work currently with the given test).
964          */
965         Calendar a = Calendar.getInstance();
966         Calendar b = (Calendar)a.clone();
967         if (a.hashCode() != b.hashCode()) {
968             errln("Calendar hash code unequal for cloned objects");
969         }
970         TimeZone atz1 = a.getTimeZone();
971         TimeZone atz2 = (TimeZone)atz1.clone();
972         if(!atz1.equals(atz2)){
973             errln("The clone timezones are not equal");
974         }
975         if(atz1.hashCode()!=atz2.hashCode()){
976             errln("TimeZone hash code unequal for cloned objects");
977         }
978         b.setMinimalDaysInFirstWeek(7 - a.getMinimalDaysInFirstWeek());
979         if (a.hashCode() == b.hashCode()) {
980             errln("Calendar hash code ignores minimal days in first week");
981         }
982         b.setMinimalDaysInFirstWeek(a.getMinimalDaysInFirstWeek());
983
984         b.setFirstDayOfWeek((a.getFirstDayOfWeek() % 7) + 1); // Next day
985         if (a.hashCode() == b.hashCode()) {
986             errln("Calendar hash code ignores first day of week");
987         }
988         b.setFirstDayOfWeek(a.getFirstDayOfWeek());
989
990         b.setLenient(!a.isLenient());
991         if (a.hashCode() == b.hashCode()) {
992             errln("Calendar hash code ignores lenient setting");
993         }
994         b.setLenient(a.isLenient());
995         
996         // Assume getTimeZone() returns a reference, not a clone
997         // of a reference -- this is true as of this writing
998         TimeZone atz = a.getTimeZone();
999         TimeZone btz = b.getTimeZone();
1000
1001         btz.setRawOffset(atz.getRawOffset() + 60*60*1000);
1002         if(atz.hashCode()== btz.hashCode()){
1003             errln(atz.hashCode()+"=="+btz.hashCode());
1004         }
1005         if (a.getTimeZone()!= b.getTimeZone() && a.hashCode() == b.hashCode()) {
1006             errln("Calendar hash code ignores zone");
1007         }
1008         b.getTimeZone().setRawOffset(a.getTimeZone().getRawOffset());
1009
1010         GregorianCalendar c = new GregorianCalendar();
1011         GregorianCalendar d = (GregorianCalendar)c.clone();
1012         if (c.hashCode() != d.hashCode()) {
1013             errln("GregorianCalendar hash code unequal for clones objects");
1014         }
1015         Date cutover = c.getGregorianChange();
1016         d.setGregorianChange(new Date(cutover.getTime() + 24*60*60*1000));
1017         if (c.hashCode() == d.hashCode()) {
1018             errln("GregorianCalendar hash code ignores cutover");
1019         }        
1020     }
1021
1022     /**
1023      * GregorianCalendar.equals() ignores cutover date
1024      */
1025     public void Test4141665() {
1026         GregorianCalendar cal = new GregorianCalendar();
1027         GregorianCalendar cal2 = (GregorianCalendar)cal.clone();
1028         Date cut = cal.getGregorianChange();
1029         Date cut2 = new Date(cut.getTime() + 100*24*60*60*1000L); // 100 days
1030                                                                   // later
1031         if (!cal.equals(cal2)) {
1032             errln("Cloned GregorianCalendars not equal");
1033         }
1034         cal2.setGregorianChange(cut2);
1035         if (cal.equals(cal2)) {
1036             errln("GregorianCalendar.equals() ignores cutover");
1037         }
1038     }
1039     
1040     /**
1041      * Bug states that ArrayIndexOutOfBoundsException is thrown by
1042      * GregorianCalendar.roll() when IllegalArgumentException should be.
1043      */
1044     public void Test4142933() {
1045         GregorianCalendar calendar = new GregorianCalendar();
1046         try {
1047             calendar.roll(-1, true);
1048             errln("Test failed, no exception trown");
1049         }
1050         catch (IllegalArgumentException e) {
1051             // OK: Do nothing
1052             // logln("Test passed");
1053             System.out.print("");
1054         }
1055         catch (Exception e) {
1056             errln("Test failed. Unexpected exception is thrown: " + e);
1057             e.printStackTrace();
1058         } 
1059     }
1060
1061     /**
1062      * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1063      * confusing; unless the time zone has a raw offset of zero, one or the
1064      * other of these will wrap. We've modified the test given in the bug report
1065      * to therefore only check the behavior of a calendar with a zero raw offset
1066      * zone.
1067      */
1068     public void Test4145158() {
1069         GregorianCalendar calendar = new GregorianCalendar();
1070
1071         calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
1072
1073         calendar.setTime(new Date(Long.MIN_VALUE));
1074         int year1 = calendar.get(Calendar.YEAR);
1075         int era1 = calendar.get(Calendar.ERA);
1076         
1077         calendar.setTime(new Date(Long.MAX_VALUE));
1078         int year2 = calendar.get(Calendar.YEAR);
1079         int era2 = calendar.get(Calendar.ERA);
1080         
1081         if (year1 == year2 && era1 == era2) {
1082             errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1083         }
1084     }
1085
1086     /**
1087      * Maximum value for YEAR field wrong.
1088      */
1089     public void Test4145983() {
1090         GregorianCalendar calendar = new GregorianCalendar();
1091         calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
1092         Date[] DATES = { new Date(Long.MAX_VALUE), new Date(Long.MIN_VALUE) };
1093         for (int i=0; i<DATES.length; ++i) {
1094             calendar.setTime(DATES[i]);
1095             int year = calendar.get(Calendar.YEAR);
1096             int maxYear = calendar.getMaximum(Calendar.YEAR);
1097             if (year > maxYear) {
1098                 errln("Failed for "+DATES[i].getTime()+" ms: year=" +
1099                       year + ", maxYear=" + maxYear);
1100             }
1101         }
1102     }
1103
1104     /**
1105      * This is a bug in the validation code of GregorianCalendar. As reported,
1106      * the bug seems worse than it really is, due to a bug in the way the bug
1107      * report test was written. In reality the bug is restricted to the
1108      * DAY_OF_YEAR field. - liu 6/29/98
1109      */
1110     public void Test4147269() {
1111         GregorianCalendar calendar = new GregorianCalendar();
1112         calendar.setLenient(false);
1113         java.util.Calendar tempcal = java.util.Calendar.getInstance();
1114         tempcal.clear();
1115         tempcal.set(1996, Calendar.JANUARY, 3); // Arbitrary date
1116         Date date = tempcal.getTime(); 
1117         for (int field = 0; field < calendar.getFieldCount(); field++) {
1118             calendar.setTime(date);
1119             // Note: In the bug report, getActualMaximum() was called instead
1120             // of getMaximum() -- this was an error. The validation code doesn't
1121             // use getActualMaximum(), since that's too costly.
1122             int max = calendar.getMaximum(field);
1123             int value = max+1;
1124             calendar.set(field, value); 
1125             try {
1126                 calendar.getTime(); // Force time computation
1127                 // We expect an exception to be thrown. If we fall through
1128                 // to the next line, then we have a bug.
1129                 errln("Test failed with field " + FIELD_NAME[field] +
1130                       ", date before: " + date +
1131                       ", date after: " + calendar.getTime() +
1132                       ", value: " + value + " (max = " + max +")");
1133             } catch (IllegalArgumentException e) {
1134                 System.out.print("");
1135             } 
1136         }
1137     }
1138
1139     /**
1140      * Reported bug is that a GregorianCalendar with a cutover of
1141      * Date(Long.MAX_VALUE) doesn't behave as a pure Julian calendar. CANNOT
1142      * REPRODUCE THIS BUG
1143      */
1144     public void Test4149677() {
1145         TimeZone[] zones = { TimeZone.getTimeZone("GMT"),
1146                              TimeZone.getTimeZone("PST"),
1147                              TimeZone.getTimeZone("EAT") };
1148         for (int i=0; i<zones.length; ++i) {
1149             GregorianCalendar calendar = new GregorianCalendar(zones[i]);
1150
1151             // Make sure extreme values don't wrap around
1152             calendar.setTime(new Date(Long.MIN_VALUE));
1153             if (calendar.get(Calendar.ERA) != GregorianCalendar.BC) {
1154                 errln("Fail: Long.MIN_VALUE ms has an AD year");
1155             }
1156             calendar.setTime(new Date(Long.MAX_VALUE));
1157             if (calendar.get(Calendar.ERA) != GregorianCalendar.AD) {
1158                 errln("Fail: Long.MAX_VALUE ms has a BC year");
1159             }
1160
1161             calendar.setGregorianChange(new Date(Long.MAX_VALUE));
1162             // to obtain a pure Julian calendar
1163             
1164             boolean is100Leap = calendar.isLeapYear(100);
1165             if (!is100Leap) {
1166                 errln("test failed with zone " + zones[i].getID());
1167                 errln(" cutover date is Calendar.MAX_DATE");
1168                 errln(" isLeapYear(100) returns: " + is100Leap);
1169             }
1170         }
1171     }
1172
1173     /**
1174      * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar and Date
1175      * classes will misbehave.
1176      */
1177     public void Test4162587() {
1178         TimeZone tz = TimeZone.getTimeZone("PST");
1179         TimeZone.setDefault(tz);
1180         GregorianCalendar cal = new GregorianCalendar(tz);
1181         Date d;
1182         
1183         for (int i=0; i<5; ++i) {
1184             if (i>0) logln("---");
1185
1186             cal.clear();
1187             cal.set(1998, Calendar.APRIL, 5, i, 0);
1188             d = cal.getTime();
1189             String s0 = d.toString();
1190             logln("0 " + i + ": " + s0);
1191
1192             cal.clear();
1193             cal.set(1998, Calendar.APRIL, 4, i+24, 0);
1194             d = cal.getTime();
1195             String sPlus = d.toString();
1196             logln("+ " + i + ": " + sPlus);
1197
1198             cal.clear();
1199             cal.set(1998, Calendar.APRIL, 6, i-24, 0);
1200             d = cal.getTime();
1201             String sMinus = d.toString();
1202             logln("- " + i + ": " + sMinus);
1203
1204             if (!s0.equals(sPlus) || !s0.equals(sMinus)) {
1205                 errln("Fail: All three lines must match");
1206             }
1207         }
1208     }
1209
1210     /**
1211      * Adding 12 months behaves differently from adding 1 year
1212      */
1213     public void Test4165343() {
1214         GregorianCalendar calendar = new GregorianCalendar(1996, Calendar.FEBRUARY, 29);
1215         Date start = calendar.getTime();
1216         logln("init date: " + start);
1217         calendar.add(Calendar.MONTH, 12); 
1218         Date date1 = calendar.getTime();
1219         logln("after adding 12 months: " + date1);
1220         calendar.setTime(start);
1221         calendar.add(Calendar.YEAR, 1);
1222         Date date2 = calendar.getTime();
1223         logln("after adding one year : " + date2);
1224         if (date1.equals(date2)) {
1225             logln("Test passed");
1226         } else {
1227             errln("Test failed");
1228         }
1229     }
1230
1231     /**
1232      * GregorianCalendar.getActualMaximum() does not account for first day of
1233      * week.
1234      */
1235     public void Test4166109() {
1236         /*
1237          * Test month:
1238          * 
1239          * March 1998 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1240          * 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
1241          */
1242         boolean passed = true;
1243         int field = Calendar.WEEK_OF_MONTH;
1244
1245         GregorianCalendar calendar = new GregorianCalendar(Locale.US);
1246         calendar.set(1998, Calendar.MARCH, 1);
1247         calendar.setMinimalDaysInFirstWeek(1);
1248         logln("Date:  " + calendar.getTime());
1249
1250         int firstInMonth = calendar.get(Calendar.DAY_OF_MONTH);
1251
1252         for (int firstInWeek = Calendar.SUNDAY; firstInWeek <= Calendar.SATURDAY; firstInWeek++) {
1253             calendar.setFirstDayOfWeek(firstInWeek);
1254             int returned = calendar.getActualMaximum(field);
1255             int expected = (31 + ((firstInMonth - firstInWeek + 7)% 7) + 6) / 7;
1256
1257             logln("First day of week = " + firstInWeek +
1258                   "  getActualMaximum(WEEK_OF_MONTH) = " + returned +
1259                   "  expected = " + expected +
1260                   ((returned == expected) ? "  ok" : "  FAIL"));
1261
1262             if (returned != expected) {
1263                 passed = false;
1264             }
1265         }
1266         if (!passed) {
1267             errln("Test failed");
1268         }
1269     }
1270
1271     /**
1272      * Calendar.getActualMaximum(YEAR) works wrong.
1273      */
1274     public void Test4167060() {
1275         int field = Calendar.YEAR;
1276         DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy G",
1277                                                  Locale.US);
1278
1279         GregorianCalendar calendars[] = {
1280             new GregorianCalendar(100, Calendar.NOVEMBER, 1),
1281             new GregorianCalendar(-99 /* 100BC */, Calendar.JANUARY, 1),
1282             new GregorianCalendar(1996, Calendar.FEBRUARY, 29),
1283         };
1284
1285         String[] id = { "Hybrid", "Gregorian", "Julian" };
1286
1287         for (int k=0; k<3; ++k) {
1288             logln("--- " + id[k] + " ---");
1289
1290             for (int j=0; j<calendars.length; ++j) {
1291                 GregorianCalendar calendar = calendars[j];
1292                 if (k == 1) {
1293                     calendar.setGregorianChange(new Date(Long.MIN_VALUE));
1294                 } else if (k == 2) {
1295                     calendar.setGregorianChange(new Date(Long.MAX_VALUE));
1296                 }
1297
1298                 format.setCalendar((Calendar)calendar.clone());
1299
1300                 Date dateBefore = calendar.getTime();
1301
1302                 int maxYear = calendar.getActualMaximum(field);
1303                 logln("maxYear: " + maxYear + " for " + format.format(calendar.getTime()));
1304                 logln("date before: " + format.format(dateBefore));
1305
1306                 int years[] = {2000, maxYear-1, maxYear, maxYear+1};
1307
1308                 for (int i = 0; i < years.length; i++) {
1309                     boolean valid = years[i] <= maxYear;
1310                     calendar.set(field, years[i]);
1311                     Date dateAfter = calendar.getTime();
1312                     int newYear = calendar.get(field);
1313                     calendar.setTime(dateBefore); // restore calendar for next
1314                                                   // use
1315
1316                     logln(" Year " + years[i] + (valid? " ok " : " bad") +
1317                           " => " + format.format(dateAfter));
1318                     if (valid && newYear != years[i]) {
1319                         errln("  FAIL: " + newYear + " should be valid; date, month and time shouldn't change");
1320                     } else if (!valid && newYear == years[i]) {
1321                         // We no longer require strict year maxima. That is, the
1322                         // calendar
1323                         // algorithm may work for values > the stated maximum.
1324                         //errln(" FAIL: " + newYear + " should be invalid");
1325                         logln("  Note: " + newYear + " > maximum, but still valid");
1326                     }
1327                 }
1328             }
1329         }
1330     }
1331
1332     /**
1333      * Calendar.roll broken This bug relies on the TimeZone bug 4173604 to also
1334      * be fixed.
1335      */
1336     public void Test4173516() {
1337         int fieldsList[][] = {
1338             { 1997, Calendar.FEBRUARY,  1, 10, 45, 15, 900 },
1339             { 1999, Calendar.DECEMBER, 22, 23, 59, 59, 999 }
1340         };
1341         int limit = 40;
1342         GregorianCalendar cal = new GregorianCalendar();
1343
1344         cal.setTime(new Date(0));
1345         cal.roll(Calendar.HOUR,  0x7F000000);
1346         cal.roll(Calendar.HOUR, -0x7F000000);
1347         if (cal.getTime().getTime() != 0) {
1348             errln("Hour rolling broken");
1349         }
1350
1351         for (int op=0; op<2; ++op) {
1352             logln("Testing GregorianCalendar " +
1353                   (op==0 ? "add" : "roll"));
1354             for (int field=0; field < cal.getFieldCount(); ++field) {
1355                 if (field != Calendar.ZONE_OFFSET &&
1356                     field != Calendar.DST_OFFSET &&
1357                     field != Calendar.IS_LEAP_MONTH ) {
1358                     for (int j=0; j<fieldsList.length; ++j) {
1359                         int fields[] = fieldsList[j];
1360                         cal.clear();
1361                         cal.set(fields[0], fields[1], fields[2],
1362                                 fields[3], fields[4], fields[5]);
1363                         cal.set(Calendar.MILLISECOND, fields[6]);
1364                         cal.setMinimalDaysInFirstWeek(1);
1365                         for (int i = 0; i < 2*limit; i++) {
1366                             if (op == 0) {
1367                                 cal.add(field, i < limit ? 1 : -1);
1368                             } else {
1369                                 cal.roll(field, i < limit ? 1 : -1);
1370                             }
1371                         }
1372                         if (cal.get(Calendar.YEAR) != fields[0] ||
1373                             cal.get(Calendar.MONTH) != fields[1] ||
1374                             cal.get(Calendar.DATE) != fields[2] ||
1375                             cal.get(Calendar.HOUR_OF_DAY) != fields[3] ||
1376                             cal.get(Calendar.MINUTE) != fields[4] ||
1377                             cal.get(Calendar.SECOND) != fields[5] ||
1378                             cal.get(Calendar.MILLISECOND) != fields[6]) {
1379                             errln("Field " + field +
1380                                   " (" + FIELD_NAME[field] +
1381                                   ") FAIL, expected " +
1382                                   fields[0] +
1383                                   "/" + (fields[1] + 1) +
1384                                   "/" + fields[2] +
1385                                   " " + fields[3] +
1386                                   ":" + fields[4] +
1387                                   ":" + fields[5] +
1388                                   "." + fields[6] +
1389                                   ", got " + cal.get(Calendar.YEAR) +
1390                                   "/" + (cal.get(Calendar.MONTH) + 1) +
1391                                   "/" + cal.get(Calendar.DATE) +
1392                                   " " + cal.get(Calendar.HOUR_OF_DAY) +
1393                                   ":" + cal.get(Calendar.MINUTE) +
1394                                   ":" + cal.get(Calendar.SECOND) +
1395                                   "." + cal.get(Calendar.MILLISECOND));
1396                             cal.clear();
1397                             cal.set(fields[0], fields[1], fields[2],
1398                                     fields[3], fields[4], fields[5]);
1399                             cal.set(Calendar.MILLISECOND, fields[6]);
1400                             logln("Start date: " + cal.get(Calendar.YEAR) +
1401                                   "/" + (cal.get(Calendar.MONTH) + 1) +
1402                                   "/" + cal.get(Calendar.DATE) +
1403                                   " " + cal.get(Calendar.HOUR_OF_DAY) +
1404                                   ":" + cal.get(Calendar.MINUTE) +
1405                                   ":" + cal.get(Calendar.SECOND) +
1406                                   "." + cal.get(Calendar.MILLISECOND));
1407                             long prev = cal.getTime().getTime();
1408                             for (int i = 0; i < 2*limit; i++) {
1409                                 if (op == 0) {
1410                                     cal.add(field, i < limit ? 1 : -1);
1411                                 } else {
1412                                     cal.roll(field, i < limit ? 1 : -1);
1413                                 }
1414                                 long t = cal.getTime().getTime();
1415                                 long delta = t - prev;
1416                                 prev = t;
1417                                 logln((op == 0 ? "add(" : "roll(") + FIELD_NAME[field] +
1418                                       (i < limit ? ", +1) => " : ", -1) => ") +
1419                                       cal.get(Calendar.YEAR) +
1420                                       "/" + (cal.get(Calendar.MONTH) + 1) +
1421                                       "/" + cal.get(Calendar.DATE) +
1422                                       " " + cal.get(Calendar.HOUR_OF_DAY) +
1423                                       ":" + cal.get(Calendar.MINUTE) +
1424                                       ":" + cal.get(Calendar.SECOND) +
1425                                       "." + cal.get(Calendar.MILLISECOND) +
1426                                       " delta=" + delta + " ms");
1427                             }
1428                         }
1429                     }
1430                 }
1431             }
1432         }
1433     }
1434
1435     public void Test4174361() {
1436         GregorianCalendar calendar = new GregorianCalendar(1996, 1, 29);
1437
1438         calendar.add(Calendar.MONTH, 10); 
1439         //Date date1 = calendar.getTime();
1440         //date1 = null;
1441         int d1 = calendar.get(Calendar.DAY_OF_MONTH);
1442
1443         calendar = new GregorianCalendar(1996, 1, 29);
1444         calendar.add(Calendar.MONTH, 11); 
1445         //Date date2 = calendar.getTime();
1446         //date2 = null;
1447         int d2 = calendar.get(Calendar.DAY_OF_MONTH);
1448
1449         if (d1 != d2) {
1450             errln("adding months to Feb 29 broken");
1451         }
1452     }
1453
1454     /**
1455      * Calendar does not update field values when setTimeZone is called.
1456      */
1457     public void Test4177484() {
1458         TimeZone PST = TimeZone.getTimeZone("PST");
1459         TimeZone EST = TimeZone.getTimeZone("EST");
1460
1461         Calendar cal = Calendar.getInstance(PST, Locale.US);
1462         cal.clear();
1463         cal.set(1999, 3, 21, 15, 5, 0); // Arbitrary
1464         int h1 = cal.get(Calendar.HOUR_OF_DAY);
1465         cal.setTimeZone(EST);
1466         int h2 = cal.get(Calendar.HOUR_OF_DAY);
1467         if (h1 == h2) {
1468             errln("FAIL: Fields not updated after setTimeZone");
1469         }
1470
1471         // getTime() must NOT change when time zone is changed.
1472         // getTime() returns zone-independent time in ms.
1473         cal.clear();
1474         cal.setTimeZone(PST);
1475         cal.set(Calendar.HOUR_OF_DAY, 10);
1476         Date pst10 = cal.getTime();
1477         cal.setTimeZone(EST);
1478         Date est10 = cal.getTime();
1479         if (!pst10.equals(est10)) {
1480             errln("FAIL: setTimeZone changed time");
1481         }
1482     }
1483
1484     /**
1485      * Week of year is wrong at the start and end of the year.
1486      */
1487     public void Test4197699() {
1488         GregorianCalendar cal = new GregorianCalendar();
1489         cal.setFirstDayOfWeek(Calendar.MONDAY);
1490         cal.setMinimalDaysInFirstWeek(4);
1491         DateFormat fmt = new SimpleDateFormat("E dd MMM yyyy  'DOY='D 'WOY='w");
1492         fmt.setCalendar(cal);
1493
1494         int[] DATA = {
1495             2000,  Calendar.JANUARY,   1,   52,
1496             2001,  Calendar.DECEMBER,  31,  1,
1497         };
1498
1499         for (int i=0; i<DATA.length; ) {
1500             cal.set(DATA[i++], DATA[i++], DATA[i++]);
1501             int expWOY = DATA[i++];
1502             int actWOY = cal.get(Calendar.WEEK_OF_YEAR);
1503             if (expWOY == actWOY) {
1504                 logln("Ok: " + fmt.format(cal.getTime()));
1505             } else {
1506                 errln("FAIL: " + fmt.format(cal.getTime())
1507                       + ", expected WOY=" + expWOY);
1508                 cal.add(Calendar.DATE, -8);
1509                 for (int j=0; j<14; ++j) {
1510                     cal.add(Calendar.DATE, 1);
1511                     logln(fmt.format(cal.getTime()));
1512                 }
1513             }
1514         }
1515     }
1516
1517     /**
1518      * Calendar DAY_OF_WEEK_IN_MONTH fields->time broken. The problem is in the
1519      * field disambiguation code in GregorianCalendar. This code is supposed to
1520      * choose the most recent set of fields among the following:
1521      * 
1522      * MONTH + DAY_OF_MONTH MONTH + WEEK_OF_MONTH + DAY_OF_WEEK MONTH +
1523      * DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK DAY_OF_YEAR WEEK_OF_YEAR + DAY_OF_WEEK
1524      */
1525     public void Test4209071() {
1526         Calendar cal = Calendar.getInstance(Locale.US);
1527
1528         // General field setting test
1529         int Y = 1995;
1530         
1531         Date d[] = new Date[13];
1532         java.util.Calendar tempcal = java.util.Calendar.getInstance();
1533         tempcal.clear();
1534         tempcal.set(Y, Calendar.JANUARY, 1);
1535         d[0] = tempcal.getTime();
1536         tempcal.set(Y, Calendar.MARCH, 1);
1537         d[1] = tempcal.getTime();
1538         tempcal.set(Y, Calendar.JANUARY, 4);
1539         d[2] = tempcal.getTime();
1540         tempcal.set(Y, Calendar.JANUARY, 18);
1541         d[3] = tempcal.getTime();
1542         tempcal.set(Y, Calendar.JANUARY, 18);
1543         d[4] = tempcal.getTime();
1544         tempcal.set(Y-1, Calendar.DECEMBER, 22);
1545         d[5] = tempcal.getTime();
1546         tempcal.set(Y, Calendar.JANUARY, 26);
1547         d[6] = tempcal.getTime();
1548         tempcal.set(Y, Calendar.JANUARY, 26);
1549         d[7] = tempcal.getTime();
1550         tempcal.set(Y, Calendar.MARCH, 1);
1551         d[8] = tempcal.getTime();
1552         tempcal.set(Y, Calendar.OCTOBER, 6);
1553         d[9] = tempcal.getTime();
1554         tempcal.set(Y, Calendar.OCTOBER, 13);
1555         d[10] = tempcal.getTime();
1556         tempcal.set(Y, Calendar.AUGUST, 10);
1557         d[11] = tempcal.getTime();
1558         tempcal.set(Y, Calendar.DECEMBER, 7);
1559         d[12] = tempcal.getTime();
1560
1561         Object[] FIELD_DATA = {
1562             // Add new test cases as needed.
1563
1564             // 0
1565             new int[] {}, d[0],
1566             // 1
1567             new int[] { Calendar.MONTH, Calendar.MARCH }, d[1],
1568             // 2
1569             new int[] { Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY }, d[2],
1570             // 3
1571             new int[] { Calendar.DAY_OF_WEEK, Calendar.THURSDAY,
1572                         Calendar.DAY_OF_MONTH, 18, }, d[3],
1573             // 4
1574             new int[] { Calendar.DAY_OF_MONTH, 18,
1575                         Calendar.DAY_OF_WEEK, Calendar.THURSDAY, }, d[4],
1576             // 5 (WOM -1 is in previous month)
1577             new int[] { Calendar.DAY_OF_MONTH, 18,
1578                         Calendar.WEEK_OF_MONTH, -1,
1579                         Calendar.DAY_OF_WEEK, Calendar.THURSDAY, }, d[5],
1580             // 6
1581             new int[] { Calendar.DAY_OF_MONTH, 18,
1582                         Calendar.WEEK_OF_MONTH, 4,
1583                         Calendar.DAY_OF_WEEK, Calendar.THURSDAY, }, d[6],
1584             // 7 (DIM -1 is in same month)
1585             new int[] { Calendar.DAY_OF_MONTH, 18,
1586                         Calendar.DAY_OF_WEEK_IN_MONTH, -1,
1587                         Calendar.DAY_OF_WEEK, Calendar.THURSDAY, }, d[7],
1588             // 8
1589             new int[] { Calendar.WEEK_OF_YEAR, 9,
1590                         Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY, }, d[8],
1591             // 9
1592             new int[] { Calendar.MONTH, Calendar.OCTOBER,
1593                         Calendar.DAY_OF_WEEK_IN_MONTH, 1,
1594                         Calendar.DAY_OF_WEEK, Calendar.FRIDAY, }, d[9],
1595             // 10
1596             new int[] { Calendar.MONTH, Calendar.OCTOBER,
1597                         Calendar.WEEK_OF_MONTH, 2,
1598                         Calendar.DAY_OF_WEEK, Calendar.FRIDAY, }, d[10],
1599             // 11
1600             new int[] { Calendar.MONTH, Calendar.OCTOBER,
1601                         Calendar.DAY_OF_MONTH, 15,
1602                         Calendar.DAY_OF_YEAR, 222, }, d[11],
1603             // 12
1604             new int[] { Calendar.DAY_OF_WEEK, Calendar.THURSDAY,
1605                         Calendar.MONTH, Calendar.DECEMBER, }, d[12],
1606         };
1607
1608         for (int i=0; i<FIELD_DATA.length; i+=2) {
1609             int[] fields = (int[]) FIELD_DATA[i];
1610             Date exp = (Date) FIELD_DATA[i+1];
1611             
1612             cal.clear();
1613             cal.set(Calendar.YEAR, Y);
1614             for (int j=0; j<fields.length; j+=2) {
1615                 cal.set(fields[j], fields[j+1]);
1616             }
1617             
1618             Date act = cal.getTime();
1619             if (!act.equals(exp)) {
1620                 errln("FAIL: Test " + (i/2) + " got " + act +
1621                       ", want " + exp +
1622                       " (see test/java/util/Calendar/CalendarRegression.java");
1623             }
1624         }
1625
1626         tempcal.set(1997, Calendar.JANUARY, 5);
1627         d[0] = tempcal.getTime();
1628         tempcal.set(1997, Calendar.JANUARY, 26);
1629         d[1] = tempcal.getTime();
1630         tempcal.set(1997, Calendar.FEBRUARY, 23);
1631         d[2] = tempcal.getTime();
1632         tempcal.set(1997, Calendar.JANUARY, 26);
1633         d[3] = tempcal.getTime();
1634         tempcal.set(1997, Calendar.JANUARY, 5);
1635         d[4] = tempcal.getTime();
1636         tempcal.set(1996, Calendar.DECEMBER, 8);
1637         d[5] = tempcal.getTime();
1638         // Test specific failure reported in bug
1639         Object[] DATA = { 
1640             new Integer(1), d[0], new Integer(4), d[1],
1641             new Integer(8), d[2], new Integer(-1), d[3],
1642             new Integer(-4), d[4], new Integer(-8), d[5],
1643         };
1644         for (int i=0; i<DATA.length; i+=2) {
1645             cal.clear();
1646             cal.set(Calendar.DAY_OF_WEEK_IN_MONTH,
1647                     ((Number) DATA[i]).intValue());
1648             cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
1649             cal.set(Calendar.MONTH, Calendar.JANUARY);
1650             cal.set(Calendar.YEAR, 1997);
1651             Date actual = cal.getTime();
1652             if (!actual.equals(DATA[i+1])) {
1653                 errln("FAIL: Sunday " + DATA[i] +
1654                       " of Jan 1997 -> " + actual +
1655                       ", want " + DATA[i+1]);
1656             }
1657         }
1658     }
1659
1660     /**
1661      * WEEK_OF_YEAR computed incorrectly. A failure of this test can indicate a problem in several different places in
1662      * the
1663      */
1664     public void Test4288792() throws Exception {
1665         TimeZone savedTZ = TimeZone.getDefault();
1666         TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
1667         GregorianCalendar cal = new GregorianCalendar();
1668
1669         for (int i = 1900; i < 2100; i++) {
1670             for (int j1 = 1; j1 <= 7; j1++) {
1671                 // Loop for MinimalDaysInFirstWeek: 1..7
1672                 for (int j = Calendar.SUNDAY; j <= Calendar.SATURDAY; j++) {
1673                     // Loop for FirstDayOfWeek: SUNDAY..SATURDAY
1674                     cal.clear();
1675                     cal.setMinimalDaysInFirstWeek(j1);
1676                     cal.setFirstDayOfWeek(j);
1677                     // Set the calendar to the first day of the last week
1678                     // of the year. This may overlap some of the start of
1679                     // the next year; that is, the last week of 1999 may
1680                     // include some of January 2000. Use the add() method
1681                     // to advance through the week. For each day, call
1682                     // get(WEEK_OF_YEAR). The result should be the same
1683                     // for the whole week. Note that a bug in
1684                     // getActualMaximum() will break this test.
1685
1686                     // Set date to the mid year first before getActualMaximum(WEEK_OF_YEAR).
1687                     // getActualMaximum(WEEK_OF_YEAR) is based on the current calendar's
1688                     // year of week of year. After clear(), calendar is set to January 1st,
1689                     // which may belongs to previous year of week of year.
1690                     cal.set(i, Calendar.JULY, 1);
1691                     int maxWeek = cal.getActualMaximum(Calendar.WEEK_OF_YEAR);
1692                     cal.set(Calendar.WEEK_OF_YEAR, maxWeek);
1693                     cal.set(Calendar.DAY_OF_WEEK, j);
1694                     for (int k = 1; k < 7; k++) {
1695                         cal.add(Calendar.DATE, 1);
1696                         int WOY = cal.get(Calendar.WEEK_OF_YEAR);
1697                         if (WOY != maxWeek) {
1698                             errln(cal.getTime() + ",got=" + WOY + ",expected=" + maxWeek + ",min=" + j1 + ",first=" + j);
1699                         }
1700                     }
1701                     // Now advance the calendar one more day. This should
1702                     // put it at the first day of week 1 of the next year.
1703                     cal.add(Calendar.DATE, 1);
1704                     int WOY = cal.get(Calendar.WEEK_OF_YEAR);
1705                     if (WOY != 1) {
1706                         errln(cal.getTime() + ",got=" + WOY + ",expected=1,min=" + j1 + ",first" + j);
1707                     }
1708                 }
1709             }
1710         }
1711         TimeZone.setDefault(savedTZ);
1712     }
1713
1714     /**
1715      * Test fieldDifference().
1716      */
1717     public void TestJ438() throws Exception {
1718         int DATA[] = {
1719             2000, Calendar.JANUARY, 20,   2010, Calendar.JUNE, 15,
1720             2010, Calendar.JUNE, 15,      2000, Calendar.JANUARY, 20,
1721             1964, Calendar.SEPTEMBER, 7,  1999, Calendar.JUNE, 4,
1722             1999, Calendar.JUNE, 4,       1964, Calendar.SEPTEMBER, 7,
1723         };
1724         Calendar cal = Calendar.getInstance(Locale.US);
1725         for (int i=0; i<DATA.length; i+=6) {
1726             int y1 = DATA[i];
1727             int m1 = DATA[i+1];
1728             int d1 = DATA[i+2];
1729             int y2 = DATA[i+3];
1730             int m2 = DATA[i+4];
1731             int d2 = DATA[i+5];
1732
1733             cal.clear();
1734             cal.set(y1, m1, d1);
1735             Date date1 = cal.getTime();
1736             cal.set(y2, m2, d2);
1737             Date date2 = cal.getTime();
1738
1739             cal.setTime(date1);
1740             int dy = cal.fieldDifference(date2, Calendar.YEAR);
1741             int dm = cal.fieldDifference(date2, Calendar.MONTH);
1742             int dd = cal.fieldDifference(date2, Calendar.DATE);
1743
1744             logln("" + date2 + " - " + date1 + " = " +
1745                   dy + "y " + dm + "m " + dd + "d");
1746
1747             cal.setTime(date1);
1748             cal.add(Calendar.YEAR, dy);
1749             cal.add(Calendar.MONTH, dm);
1750             cal.add(Calendar.DATE, dd);
1751             Date date22 = cal.getTime();
1752             if (!date2.equals(date22)) {
1753                 errln("FAIL: " + date1 + " + " +
1754                       dy + "y " + dm + "m " + dd + "d = " +
1755                       date22 + ", exp " + date2);
1756             } else {
1757                 logln("Ok: " + date1 + " + " +
1758                       dy + "y " + dm + "m " + dd + "d = " +
1759                       date22);
1760             }
1761         }
1762     }
1763     
1764     public void TestT5555() throws Exception
1765     {
1766         Calendar cal = Calendar.getInstance();
1767         
1768         // Set date to Wednesday, February 21, 2007
1769         cal.set(2007, Calendar.FEBRUARY, 21);
1770
1771         try {
1772             // Advance month by three years
1773             cal.add(Calendar.MONTH, 36);
1774             
1775             // Move to last Wednesday of month.
1776             cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1);
1777             
1778             cal.getTime();
1779         } catch (Exception e) {
1780             errln("Got an exception calling getTime().");
1781         }
1782         
1783         int yy, mm, dd, ee;
1784         
1785         yy = cal.get(Calendar.YEAR);
1786         mm = cal.get(Calendar.MONTH);
1787         dd = cal.get(Calendar.DATE);
1788         ee = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
1789         
1790         if (yy != 2010 || mm != Calendar.FEBRUARY || dd != 24 || ee != Calendar.WEDNESDAY) {
1791             errln("Got date " + yy + "/" + (mm + 1) + "/" + dd + ", expected 2010/2/24");
1792         }
1793     }
1794
1795     /**
1796      * Set behavior of DST_OFFSET field. ICU4J Jitterbug 9.
1797      */
1798     public void TestJ9() {
1799         int HOURS = 60*60*1000;
1800         Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("PST"),
1801                                              Locale.US);
1802
1803         final int END_FIELDS = 0x1234;
1804
1805         int[] DATA = {
1806             // With no explicit ZONE/DST expect 12:00 am
1807             Calendar.MONTH, Calendar.JUNE,
1808             END_FIELDS,
1809             0, 0, // expected hour, min
1810
1811             // Normal ZONE/DST for June 1 Pacific is 8:00/1:00
1812             Calendar.MONTH, Calendar.JUNE,
1813             Calendar.ZONE_OFFSET, -8*HOURS,
1814             Calendar.DST_OFFSET, HOURS,
1815             END_FIELDS,
1816             0, 0, // expected hour, min
1817
1818             // With ZONE/DST of 8:00/0:30 expect time of 12:30 am
1819             Calendar.MONTH, Calendar.JUNE,
1820             Calendar.ZONE_OFFSET, -8*HOURS,
1821             Calendar.DST_OFFSET, HOURS/2,
1822             END_FIELDS,
1823             0, 30, // expected hour, min
1824
1825             // With ZONE/DST of 8:00/UNSET expect time of 1:00 am
1826             Calendar.MONTH, Calendar.JUNE,
1827             Calendar.ZONE_OFFSET, -8*HOURS,
1828             END_FIELDS,
1829             1, 0, // expected hour, min
1830
1831             // With ZONE/DST of UNSET/0:30 expect 4:30 pm (day before)
1832             Calendar.MONTH, Calendar.JUNE,
1833             Calendar.DST_OFFSET, HOURS/2,
1834             END_FIELDS,
1835             16, 30, // expected hour, min
1836         };
1837
1838         for (int i=0; i<DATA.length; ) {
1839             int start = i;
1840             cal.clear();
1841
1842             // Set fields
1843             while (DATA[i] != END_FIELDS) {
1844                 cal.set(DATA[i++], DATA[i++]);
1845             }
1846             ++i; // skip over END_FIELDS
1847
1848             // Get hour/minute
1849             int h = cal.get(Calendar.HOUR_OF_DAY);
1850             int m = cal.get(Calendar.MINUTE);
1851
1852             // Check
1853             if (h != DATA[i] || m != DATA[i+1]) {
1854                 errln("Fail: expected " + DATA[i] + ":" + DATA[i+1] +
1855                       ", got " + h + ":" + m + " after:");
1856                 while (DATA[start] != END_FIELDS) {
1857                     logln("set(" + FIELD_NAME[DATA[start++]] +
1858                           ", " + DATA[start++] + ");");
1859                 }
1860             }
1861
1862             i += 2; // skip over expected hour, min
1863         }
1864     }
1865
1866     /**
1867      * DateFormat class mistakes date style and time style as follows: -
1868      * DateFormat.getDateTimeInstance takes date style as time style, and time
1869      * style as date style - If a Calendar is passed to
1870      * DateFormat.getDateInstance, it returns time instance - If a Calendar is
1871      * passed to DateFormat.getTimeInstance, it returns date instance
1872      */
1873     public void TestDateFormatFactoryJ26() {
1874         TimeZone zone = TimeZone.getDefault();
1875         try {
1876             Locale loc = Locale.US;
1877             TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
1878             java.util.Calendar tempcal = java.util.Calendar.getInstance();
1879             tempcal.set(2001, Calendar.APRIL, 5, 17, 43, 53);
1880             Date date = tempcal.getTime();
1881             Calendar cal = Calendar.getInstance(loc);
1882             Object[] DATA = {
1883                 DateFormat.getDateInstance(DateFormat.SHORT, loc),
1884                 "DateFormat.getDateInstance(DateFormat.SHORT, loc)",
1885                 "4/5/01",
1886
1887                 DateFormat.getTimeInstance(DateFormat.SHORT, loc),
1888                 "DateFormat.getTimeInstance(DateFormat.SHORT, loc)",
1889                 "5:43 PM",
1890
1891                 DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, loc),
1892                 "DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, loc)",
1893                 "Thursday, April 5, 2001 5:43 PM",
1894
1895                 DateFormat.getDateInstance(cal, DateFormat.SHORT, loc),
1896                 "DateFormat.getDateInstance(cal, DateFormat.SHORT, loc)",
1897                 "4/5/01",
1898
1899                 DateFormat.getTimeInstance(cal, DateFormat.SHORT, loc),
1900                 "DateFormat.getTimeInstance(cal, DateFormat.SHORT, loc)",
1901                 "5:43 PM",
1902
1903                 DateFormat.getDateTimeInstance(cal, DateFormat.FULL, DateFormat.SHORT, loc),
1904                 "DateFormat.getDateTimeInstance(cal, DateFormat.FULL, DateFormat.SHORT, loc)",
1905                 "Thursday, April 5, 2001 5:43 PM",
1906             
1907                 cal.getDateTimeFormat(DateFormat.SHORT, DateFormat.FULL, loc),
1908                 "cal.getDateTimeFormat(DateFormat.SHORT, DateFormat.FULL, loc)",
1909                 "4/5/01 5:43:53 PM Pacific Daylight Time",
1910
1911                 cal.getDateTimeFormat(DateFormat.FULL, DateFormat.SHORT, loc),
1912                 "cal.getDateTimeFormat(DateFormat.FULL, DateFormat.SHORT, loc)",
1913                 "Thursday, April 5, 2001 5:43 PM",
1914             };
1915             for (int i=0; i<DATA.length; i+=3) {
1916                 DateFormat df = (DateFormat) DATA[i];
1917                 String desc = (String) DATA[i+1];
1918                 String exp = (String) DATA[i+2];
1919                 String got = df.format(date);
1920                 if (got.equals(exp)) {
1921                     logln("Ok: " + desc + " => " + got);
1922                 } else {
1923                     errln("FAIL: " + desc + " => " + got + ", expected " + exp);
1924                 }
1925             }
1926         } finally {
1927             TimeZone.setDefault(zone);
1928         }
1929     }
1930
1931     public void TestRegistration() {
1932         /*
1933          * Set names = Calendar.getCalendarFactoryNames();
1934          * 
1935          * TimeZone tz = TimeZone.getDefault(); Locale loc =
1936          * Locale.getDefault(); Iterator iter = names.iterator(); while
1937          * (iter.hasNext()) { String name = (String)iter.next(); logln("Testing
1938          * factory: " + name);
1939          * 
1940          * Calendar cal = Calendar.getInstance(tz, loc, name); logln("Calendar
1941          * class: " + cal.getClass());
1942          * 
1943          * DateFormat fmt = cal.getDateTimeFormat(DateFormat.LONG,
1944          * DateFormat.LONG, loc);
1945          * 
1946          * logln("Date: " + fmt.format(cal.getTime())); }
1947          *  // register new default for our locale logln("\nTesting
1948          * registration"); loc = new Locale("en", "US"); Object key =
1949          * Calendar.register(JapaneseCalendar.factory(), loc, true);
1950          * 
1951          * loc = new Locale("en", "US", "TEST"); Calendar cal =
1952          * Calendar.getInstance(loc); logln("Calendar class: " +
1953          * cal.getClass()); DateFormat fmt =
1954          * cal.getDateTimeFormat(DateFormat.LONG, DateFormat.LONG, loc);
1955          * logln("Date: " + fmt.format(cal.getTime()));
1956          *  // force to use other default anyway logln("\nOverride
1957          * registration"); cal = Calendar.getInstance(tz, loc, "Gregorian"); fmt =
1958          * cal.getDateTimeFormat(DateFormat.LONG, DateFormat.LONG, loc);
1959          * logln("Date: " + fmt.format(cal.getTime()));
1960          *  // unregister default logln("\nUnregistration"); logln("Unregister
1961          * returned: " + Calendar.unregister(key)); cal =
1962          * Calendar.getInstance(tz, loc, "Gregorian"); fmt =
1963          * cal.getDateTimeFormat(DateFormat.LONG, DateFormat.LONG, loc);
1964          * logln("Date: " + fmt.format(cal.getTime()));
1965          */
1966     }
1967
1968     /**
1969      * test serialize-and-modify.
1970      * @throws ClassNotFoundException 
1971      */
1972     public void TestSerialization3474() {
1973         try {
1974             ByteArrayOutputStream icuStream = new ByteArrayOutputStream();
1975     
1976             logln("icu Calendar");
1977             
1978             com.ibm.icu.util.GregorianCalendar icuCalendar =
1979                 new com.ibm.icu.util.GregorianCalendar();
1980             
1981             icuCalendar.setTimeInMillis(1187912555931L);
1982             long expectMillis = 1187912520931L; // with seconds (not ms) cleared.
1983             
1984             logln("instantiated: "+icuCalendar);
1985             logln("getMillis: "+icuCalendar.getTimeInMillis());
1986             icuCalendar.set(com.ibm.icu.util.GregorianCalendar.SECOND, 0);
1987             logln("setSecond=0: "+icuCalendar);
1988             {
1989                 long gotMillis = icuCalendar.getTimeInMillis();
1990                 if(gotMillis != expectMillis) {
1991                     errln("expect millis "+expectMillis+" but got "+gotMillis);
1992                 } else {
1993                     logln("getMillis: "+gotMillis);
1994                 }
1995             }
1996             ObjectOutputStream icuOut =
1997                 new ObjectOutputStream(icuStream);
1998             icuOut.writeObject(icuCalendar);
1999             icuOut.flush();
2000             icuOut.close();
2001             
2002             ObjectInputStream icuIn =
2003                 new ObjectInputStream(new ByteArrayInputStream(icuStream.toByteArray()));
2004             icuCalendar = null;
2005             icuCalendar = (com.ibm.icu.util.GregorianCalendar)icuIn.readObject();
2006             
2007             logln("serialized back in: "+icuCalendar);
2008             {
2009                 long gotMillis = icuCalendar.getTimeInMillis();
2010                 if(gotMillis != expectMillis) {
2011                     errln("expect millis "+expectMillis+" but got "+gotMillis);
2012                 } else {
2013                     logln("getMillis: "+gotMillis);
2014                 }
2015             }
2016             
2017             icuCalendar.set(com.ibm.icu.util.GregorianCalendar.SECOND, 0);
2018                     
2019             logln("setSecond=0: "+icuCalendar);
2020             {
2021                 long gotMillis = icuCalendar.getTimeInMillis();
2022                 if(gotMillis != expectMillis) {
2023                     errln("expect millis "+expectMillis+" after stream and setSecond but got "+gotMillis);
2024                 } else {
2025                     logln("getMillis after stream and setSecond: "+gotMillis);
2026                 }
2027             }
2028         } catch(IOException e) {
2029             errln(e.toString());
2030             e.printStackTrace();
2031         } catch(ClassNotFoundException cnf) {
2032             errln(cnf.toString());
2033             cnf.printStackTrace();
2034         }
2035
2036         // JDK works correctly, etc etc.  
2037 //        ByteArrayOutputStream jdkStream = new ByteArrayOutputStream();
2038
2039 //        logln("\nSUN Calendar");
2040 //        
2041 //        java.util.GregorianCalendar sunCalendar =
2042 //            new java.util.GregorianCalendar();
2043 //        
2044 //        logln("instanzieren: "+sunCalendar);
2045 //        logln("getMillis: "+sunCalendar.getTimeInMillis());
2046 //        sunCalendar.set(java.util.GregorianCalendar.SECOND, 0);
2047 //        logln("setSecond=0: "+sunCalendar);
2048 //        logln("getMillis: "+sunCalendar.getTimeInMillis());
2049 //        
2050 //        ObjectOutputStream sunOut =
2051 //            new ObjectOutputStream(jdkStream);
2052 //        sunOut.writeObject(sunCalendar);
2053 //        sunOut.flush();
2054 //        sunOut.close();
2055 //        
2056 //        ObjectInputStream sunIn =
2057 //            new ObjectInputStream(new ByteArrayInputStream(jdkStream.toByteArray()));
2058 //        sunCalendar = null;
2059 //        sunCalendar = (java.util.GregorianCalendar)sunIn.readObject();
2060 //        
2061 //        logln("serialized: "+sunCalendar);
2062 //        logln("getMillis: "+sunCalendar.getTimeInMillis());
2063 //        
2064 //        sunCalendar.set(java.util.GregorianCalendar.SECOND, 0);
2065 //        logln("setSecond=0: "+sunCalendar);
2066 //        logln("getMillis: "+sunCalendar.getTimeInMillis());
2067         
2068     }
2069
2070     public void TestYearJump3279() {
2071         final long time = 1041148800000L;
2072         Calendar c = new GregorianCalendar();
2073         DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
2074
2075         c.setTimeInMillis(time);
2076         int year1 = c.get(Calendar.YEAR);
2077         
2078         logln("time: " + fmt.format(new Date(c.getTimeInMillis())));
2079
2080         logln("setting DOW to " + c.getFirstDayOfWeek());
2081         c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
2082         logln("week: " + c.getTime());
2083         logln("week adjust: " + fmt.format(new Date(c.getTimeInMillis())));
2084         int year2 = c.get(Calendar.YEAR);
2085         
2086         if(year1 != year2) {
2087             errln("Error: adjusted day of week, and year jumped from " + year1 + " to " + year2);
2088         } else {
2089             logln("Year remained " + year2 + " - PASS.");
2090         }
2091     }
2092     public void TestCalendarType6816() {
2093         Locale loc = new Locale("en", "TH");
2094         Calendar cal = Calendar.getInstance(loc);
2095         String calType = cal.getType();
2096         if ( !calType.equals("buddhist")) {
2097             errln("FAIL: Calendar type for en_TH should still be buddhist");
2098         }
2099     }
2100
2101     public void TestGetKeywordValuesForLocale(){
2102
2103         final String[][] PREFERRED = {
2104             {"root",        "gregorian"},
2105             {"und",         "gregorian"},
2106             {"en_US",       "gregorian"},
2107             {"en_029",      "gregorian"},
2108             {"th_TH",       "buddhist", "gregorian"},
2109             {"und_TH",      "buddhist", "gregorian"},
2110             {"en_TH",       "buddhist", "gregorian"},
2111             {"he_IL",       "gregorian", "hebrew", "islamic", "islamic-civil"},
2112             {"ar_EG",       "gregorian", "coptic", "islamic", "islamic-civil"},
2113             {"ja",          "gregorian", "japanese"},
2114             {"ps_Guru_IN",  "gregorian", "indian"},
2115             {"th@calendar=gregorian",   "buddhist", "gregorian"},
2116             {"en@calendar=islamic",     "gregorian"},
2117             {"zh_TW",       "gregorian", "roc", "chinese"},
2118             {"ar_IR",       "gregorian", "persian", "islamic", "islamic-civil"},
2119         };
2120
2121         String[] ALL = Calendar.getKeywordValuesForLocale("calendar", ULocale.getDefault(), false);
2122         HashSet ALLSET = new HashSet();
2123         for (int i = 0; i < ALL.length; i++) {
2124             ALLSET.add(ALL[i]);
2125         }
2126
2127         for (int i = 0; i < PREFERRED.length; i++) {
2128             ULocale loc = new ULocale(PREFERRED[i][0]);
2129             String[] expected = new String[PREFERRED[i].length - 1];
2130             System.arraycopy(PREFERRED[i], 1, expected, 0, expected.length);
2131
2132             String[] pref = Calendar.getKeywordValuesForLocale("calendar", loc, true);
2133             boolean matchPref = false;
2134             if (pref.length == expected.length) {
2135                 matchPref = true;
2136                 for (int j = 0; j < pref.length; j++) {
2137                     if (!pref[j].equals(expected[j])) {
2138                         matchPref = false;
2139                     }
2140                 }
2141             }
2142             if (!matchPref) {
2143                 errln("FAIL: Preferred values for locale " + loc 
2144                         + " got:" + Arrays.toString(pref) + " expected:" + Arrays.toString(expected));
2145             }
2146
2147             String[] all = Calendar.getKeywordValuesForLocale("calendar", loc, false);
2148             boolean matchAll = false;
2149             if (all.length == ALLSET.size()) {
2150                 matchAll = true;
2151                 for (int j = 0; j < all.length; j++) {
2152                     if (!ALLSET.contains(all[j])) {
2153                         matchAll = false;
2154                         break;
2155                     }
2156                 }
2157             }
2158             if (!matchAll) {
2159                 errln("FAIL: All values for locale " + loc
2160                         + " got:" + Arrays.toString(all)); 
2161             }
2162         }
2163     }
2164     
2165     public void TestTimeStamp() {
2166         long start = 0, time;
2167
2168         // Create a new Gregorian Calendar.
2169         Calendar cal = Calendar.getInstance(Locale.US);
2170         
2171         for (int i = 0; i < 20000; i++) {
2172             cal.set(2009, Calendar.JULY, 3, 0, 49, 46);
2173             
2174             time = cal.getTime().getTime();
2175             
2176             if (i == 0) {
2177                 start = time;
2178             } else {
2179                 if (start != time) {
2180                     errln("start and time not equal");
2181                     return;
2182                 }
2183             }
2184         }
2185     }
2186
2187     /*
2188      * Test case for add/roll with non-lenient calendar reported by ticket#8057.
2189      * Calendar#add may result internal fields out of valid range. ICU used to
2190      * trigger field range validation also for internal field changes triggered
2191      * by add/roll, then throws IllegalArgumentException. The field value range
2192      * validation should be done only for fields set by user code explicitly
2193      * in non-lenient mode.
2194      */
2195     public void TestT8057() {
2196         // Set the calendar to the last day in a leap year
2197         GregorianCalendar cal = new GregorianCalendar();
2198         cal.setLenient(false);
2199         cal.clear();
2200         cal.set(2008, Calendar.DECEMBER, 31);
2201
2202         // Force calculating then fields once.
2203         long t = cal.getTimeInMillis();
2204
2205         long expected = 1262246400000L; // 2009-12-31 00:00 PST
2206
2207         try {
2208             cal.add(Calendar.YEAR, 1);
2209             t = cal.getTimeInMillis();
2210             if (t != expected) {
2211                 errln("FAIL: wrong date after add: expected=" + expected + " returned=" + t);
2212             }
2213         } catch (IllegalArgumentException e) {
2214             errln("FAIL: add method should not throw IllegalArgumentException");
2215         }
2216     }
2217
2218     /*
2219      * Test case for ticket#8596.
2220      * Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR)
2221      * may result wrong maximum week.
2222      */
2223     public void TestT8596() {
2224         GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("Etc/GMT"));
2225         gc.setFirstDayOfWeek(Calendar.MONDAY);
2226         gc.setMinimalDaysInFirstWeek(4);
2227
2228         // Force the calender to resolve the fields once.
2229         // The maximum week number in 2011 is 52.
2230         gc.set(Calendar.YEAR, 2011);
2231         gc.get(Calendar.YEAR);
2232
2233         // Set a date in year 2009, but not calling get to resolve
2234         // the calendar's internal field yet.
2235         gc.set(2009, Calendar.JULY, 1);
2236
2237         // Then call getActuamMaximum for week of year.
2238         // #8596 was caused by conflict between year set
2239         // above and internal work calendar field resolution.
2240         int maxWeeks = gc.getActualMaximum(Calendar.WEEK_OF_YEAR);
2241         if (maxWeeks != 53) {
2242             errln("FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks);
2243         }
2244     }
2245 }
2246
2247 //eof