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