]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/format/DateFormatTest.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / format / DateFormatTest.java
1 //##header J2SE15
2 /*
3  *******************************************************************************
4  * Copyright (C) 2001-2009, International Business Machines Corporation and    *
5  * others. All Rights Reserved.                                                *
6  *******************************************************************************
7  */
8
9 /** 
10  * Port From:   ICU4C v1.8.1 : format : DateFormatTest
11  * Source File: $ICU4CRoot/source/test/intltest/dtfmttst.cpp
12  **/
13
14 package com.ibm.icu.dev.test.format;
15
16 import java.text.AttributedCharacterIterator;
17 import java.text.CharacterIterator;
18 import java.text.FieldPosition;
19 import java.text.ParseException;
20 import java.text.ParsePosition;
21 import java.util.Date;
22 import java.util.Iterator;
23 import java.util.Locale;
24 import java.util.Map;
25 import java.util.ResourceBundle;
26 import java.util.Set;
27
28 import com.ibm.icu.impl.ICUResourceBundle;
29 import com.ibm.icu.text.ChineseDateFormat;
30 import com.ibm.icu.text.ChineseDateFormatSymbols;
31 import com.ibm.icu.text.DateFormat;
32 import com.ibm.icu.text.DateFormatSymbols;
33 import com.ibm.icu.text.NumberFormat;
34 import com.ibm.icu.text.SimpleDateFormat;
35 import com.ibm.icu.util.BuddhistCalendar;
36 import com.ibm.icu.util.Calendar;
37 import com.ibm.icu.util.ChineseCalendar;
38 import com.ibm.icu.util.GregorianCalendar;
39 import com.ibm.icu.util.HebrewCalendar;
40 import com.ibm.icu.util.IslamicCalendar;
41 import com.ibm.icu.util.JapaneseCalendar;
42 import com.ibm.icu.util.TimeZone;
43 import com.ibm.icu.util.ULocale;
44 import com.ibm.icu.util.UResourceBundle;
45 import com.ibm.icu.util.VersionInfo;
46
47 public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
48     
49     public static void main(String[] args) throws Exception {
50         new DateFormatTest().run(args);
51     }
52
53     /**
54      * Verify that patterns have the correct values and could produce the 
55      * the DateFormat instances that contain the correct localized patterns.
56      */
57     public void TestPatterns() {
58         final String[][] EXPECTED = {
59                 {DateFormat.MINUTE_SECOND, "ms", "en", "m:s"},
60                 {DateFormat.HOUR24_MINUTE, "Hm", "en", "H:m"},
61                 {DateFormat.HOUR24_MINUTE_SECOND, "Hms","en","H:m:s"},
62                 {DateFormat.HOUR_MINUTE, "hm","en","h:m a"},
63                 {DateFormat.HOUR_MINUTE_SECOND, "hms","en","h:m:s a"},
64                 {DateFormat.DAY, "d","en","d"},
65                 {DateFormat.STANDALONE_MONTH, "LLLL","en","LLLL"},
66                 {DateFormat.ABBR_STANDALONE_MONTH, "LLL","en","LLL"},
67                 {DateFormat.YEAR, "y","en","y"},
68                 {DateFormat.MONTH_DAY, "MMMMd","en","MMMM d"},
69                 {DateFormat.ABBR_MONTH_DAY, "MMMd","en","MMM d"},
70                 {DateFormat.NUM_MONTH_DAY, "Md","en","M/d"},
71                 {DateFormat.MONTH_WEEKDAY_DAY, "MMMMEEEEd","en","EEEE, MMMM d"},
72                 {DateFormat.ABBR_MONTH_WEEKDAY_DAY, "MMMEd","en","E, MMM d"},
73                 {DateFormat.NUM_MONTH_WEEKDAY_DAY, "MEd","en","E, M/d"},
74                 {DateFormat.YEAR_MONTH, "yMMMM","en","MMMM y"},
75                 {DateFormat.YEAR_ABBR_MONTH, "yMMM","en","MMM y"},
76                 {DateFormat.YEAR_NUM_MONTH, "yM","en","M/y"}, 
77                 {DateFormat.YEAR_ABBR_MONTH_WEEKDAY_DAY, "yMMMEd", "en", "E, MMM d, y"},
78                 {DateFormat.YEAR_NUM_MONTH_WEEKDAY_DAY, "yMEd", "en", "E, M/d/y"},
79                 {DateFormat.YEAR_QUARTER, "yQQQ", "en", "QQQ y"},
80                 {DateFormat.YEAR_ABBR_QUARTER, "yQ", "en", "Q y"}
81         };
82         
83         for (int i = 0; i < EXPECTED.length; i++) {
84             
85             // Verify that patterns have the correct values
86             String actualPattern = EXPECTED[i][0];
87             String expectedPattern = EXPECTED[i][1];
88             ULocale locale = new ULocale(EXPECTED[i][2], "", "");
89             if (!actualPattern.equals(expectedPattern)) {
90                 errln("FAILURE! Expected pattern: " + expectedPattern + 
91                         " but was: " + actualPattern);
92             }
93             
94             // Verify that DataFormat instances produced contain the correct 
95             // localized patterns
96             DateFormat date1 = DateFormat.getPatternInstance(actualPattern, 
97                     locale);
98             DateFormat date2 = DateFormat.getPatternInstance(Calendar.getInstance(locale),
99                     actualPattern, locale);
100             
101             String expectedLocalPattern = EXPECTED[i][3];
102             String actualLocalPattern1 = ((SimpleDateFormat)date1).toLocalizedPattern();
103             String actualLocalPattern2 = ((SimpleDateFormat)date2).toLocalizedPattern();
104             if (!actualLocalPattern1.equals(expectedLocalPattern)) {
105                 errln("FAILURE! Expected local pattern: " + expectedLocalPattern 
106                         + " but was: " + actualLocalPattern1);
107             }       
108             if (!actualLocalPattern2.equals(expectedLocalPattern)) {
109                 errln("FAILURE! Expected local pattern: " + expectedLocalPattern 
110                         + " but was: " + actualLocalPattern2);
111             }      
112         }
113     }
114
115     // Test written by Wally Wedel and emailed to me.
116     public void TestWallyWedel() {
117         /*
118          * Instantiate a TimeZone so we can get the ids.
119          */
120         //TimeZone tz = new SimpleTimeZone(7, ""); //The variable is never used
121         /*
122          * Computational variables.
123          */
124         int offset, hours, minutes, seconds;
125         /*
126          * Instantiate a SimpleDateFormat set up to produce a full time
127          zone name.
128          */
129         SimpleDateFormat sdf = new SimpleDateFormat("zzzz");
130         /*
131          * A String array for the time zone ids.
132          */
133     
134         final String[] ids = TimeZone.getAvailableIDs();
135         int ids_length = ids.length; //when fixed the bug should comment it out
136     
137         /*
138          * How many ids do we have?
139          */
140         logln("Time Zone IDs size:" + ids_length);
141         /*
142          * Column headings (sort of)
143          */
144         logln("Ordinal ID offset(h:m) name");
145         /*
146          * Loop through the tzs.
147          */
148         Date today = new Date();
149         Calendar cal = Calendar.getInstance();
150         for (int i = 0; i < ids_length; i++) {
151             logln(i + " " + ids[i]);
152             TimeZone ttz = TimeZone.getTimeZone(ids[i]);
153             // offset = ttz.getRawOffset();
154             cal.setTimeZone(ttz);
155             cal.setTime(today);
156             offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
157             // logln(i + " " + ids[i] + " offset " + offset);
158             String sign = "+";
159             if (offset < 0) {
160                 sign = "-";
161                 offset = -offset;
162             }
163             hours = offset / 3600000;
164             minutes = (offset % 3600000) / 60000;
165             seconds = (offset % 60000) / 1000;
166             String dstOffset = sign + (hours < 10 ? "0" : "") + hours
167                     + ":" + (minutes < 10 ? "0" : "") + minutes; 
168             if (seconds != 0) {
169                 dstOffset += ":" + (seconds < 10 ? "0" : "") + seconds;
170             }
171             /*
172              * Instantiate a date so we can display the time zone name.
173              */
174             sdf.setTimeZone(ttz);
175             /*
176              * Format the output.
177              */
178             StringBuffer fmtOffset = new StringBuffer("");
179             FieldPosition pos = new FieldPosition(0);
180             
181             try {
182                 fmtOffset = sdf.format(today, fmtOffset, pos);
183             } catch (Exception e) {            
184                 logln("Exception:" + e);
185                 continue;
186             }
187             // UnicodeString fmtOffset = tzS.toString();
188             String fmtDstOffset = null;
189             if (fmtOffset.toString().startsWith("GMT")) {
190                 //fmtDstOffset = fmtOffset.substring(3);
191                 fmtDstOffset = fmtOffset.substring(3, fmtOffset.length());
192             }
193             /*
194              * Show our result.
195              */
196     
197             boolean ok = fmtDstOffset == null || fmtDstOffset.equals("") || fmtDstOffset.equals(dstOffset);
198             if (ok) {
199                 logln(i + " " + ids[i] + " " + dstOffset + " "
200                       + fmtOffset + (fmtDstOffset != null ? " ok" : " ?")); 
201             } else {
202                 errln(i + " " + ids[i] + " " + dstOffset + " " + fmtOffset + " *** FAIL ***");
203             }
204         
205         }
206     }
207     
208     public void TestEquals() {
209         DateFormat fmtA = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL); 
210         DateFormat fmtB = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.FULL); 
211         if (!fmtA.equals(fmtB))
212             errln("FAIL");    
213     }
214     
215     /**
216      * Test the parsing of 2-digit years.
217      */
218     public void TestTwoDigitYearDSTParse() {
219     
220         SimpleDateFormat fullFmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss.SSS zzz yyyy G"); 
221         SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yy h:mm:ss 'o''clock' a z", Locale.ENGLISH); 
222         String s = "03-Apr-04 2:20:47 o'clock AM PST";
223     
224         /*
225          * SimpleDateFormat(pattern, locale) Construct a SimpleDateDateFormat using
226          * the given pattern, the locale and using the TimeZone.getDefault();
227          * So it need to add the timezone offset on hour field. 
228          * ps. the Method Calendar.getTime() used by SimpleDateFormat.parse() always 
229          * return Date value with TimeZone.getDefault() [Richard/GCL]
230          */
231         
232         TimeZone defaultTZ = TimeZone.getDefault();
233         TimeZone PST = TimeZone.getTimeZone("PST");
234         int defaultOffset = defaultTZ.getRawOffset();
235         int PSTOffset = PST.getRawOffset();
236         int hour = 2 + (defaultOffset - PSTOffset) / (60*60*1000);
237         // hour is the expected hour of day, in units of seconds
238         hour = ((hour < 0) ? hour + 24 : hour) * 60*60;
239         try {
240             Date d = fmt.parse(s);
241             Calendar cal = Calendar.getInstance();
242             cal.setTime(d);
243             //DSTOffset
244             hour += defaultTZ.inDaylightTime(d) ? 1 : 0;
245             
246             logln(s + " P> " + ((DateFormat) fullFmt).format(d));
247             // hr is the actual hour of day, in units of seconds
248             // adjust for DST
249             int hr = cal.get(Calendar.HOUR_OF_DAY) * 60*60 -
250                 cal.get(Calendar.DST_OFFSET) / 1000;
251             if (hr != hour)
252                 errln("FAIL: Hour (-DST) = " + hr / (60*60.0)+
253                       "; expected " + hour / (60*60.0));
254         } catch (ParseException e) {
255             errln("Parse Error:" + e.getMessage());
256         }
257     
258     }
259     
260     /**
261      * Verify that returned field position indices are correct.
262      */
263     public void TestFieldPosition() {
264         int i, j, exp;
265         StringBuffer buf = new StringBuffer();
266
267         // Verify data
268         if (VersionInfo.ICU_VERSION.compareTo(VersionInfo.getInstance(3, 7)) >= 0) {
269             DateFormatSymbols rootSyms = new DateFormatSymbols(new Locale("", "", ""));
270             assertEquals("patternChars", PATTERN_CHARS, rootSyms.getLocalPatternChars());
271         }
272         
273         assertTrue("DATEFORMAT_FIELD_NAMES", DATEFORMAT_FIELD_NAMES.length == DateFormat.FIELD_COUNT);
274         if(DateFormat.FIELD_COUNT != PATTERN_CHARS.length()){
275             errln("Did not get the correct value for DateFormat.FIELD_COUNT. Expected:  "+ PATTERN_CHARS.length());
276         }
277
278         // Create test formatters
279         final int COUNT = 4;
280         DateFormat[] dateFormats = new DateFormat[COUNT];
281         dateFormats[0] = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.US);
282         dateFormats[1] = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.FRANCE);
283         // Make the pattern "G y M d..."
284         buf.append(PATTERN_CHARS);
285         for (j=buf.length()-1; j>=0; --j) buf.insert(j, ' ');
286         dateFormats[2] = new SimpleDateFormat(buf.toString(), Locale.US);
287         // Make the pattern "GGGG yyyy MMMM dddd..."
288         for (j=buf.length()-1; j>=0; j-=2) {
289             for (i=0; i<3; ++i) {
290                 buf.insert(j, buf.charAt(j));
291             }
292         }
293         dateFormats[3] = new SimpleDateFormat(buf.toString(), Locale.US);
294
295         Date aug13 = new Date((long) 871508052513.0);
296
297         // Expected output field values for above DateFormats on aug13
298         // Fields are given in order of DateFormat field number
299         final String EXPECTED[] = {
300              "", "1997", "August", "13", "", "", "34", "12", "",
301             "Wednesday", "", "", "", "", "PM", "2", "", "Pacific Daylight Time", "", "", "", "", "", "", "","","","","","",
302
303             "", "1997", "ao\u00FBt", "13", "", "14", "34", "12", "",
304             "mercredi", "", "", "", "", "", "", "", "heure avanc\u00E9e du Pacifique", "", "", "", "", "", "", "","","","","","",
305
306             "AD", "1997", "8", "13", "14", "14", "34", "12", "5",
307             "Wed", "225", "2", "33", "2", "PM", "2", "2", "PDT", "1997", "4", "1997", "2450674", "52452513", "-0700", "PT","4","8","3","3","PDT",
308
309             "Anno Domini", "1997", "August", "0013", "0014", "0014", "0034", "0012", "5130",
310             "Wednesday", "0225", "0002", "0033", "0002", "PM", "0002", "0002", "Pacific Daylight Time", "1997",
311             "Wednesday", "1997", "2450674", "52452513", "GMT-07:00", "Pacific Time","Wednesday","August", "3rd quarter", "3rd quarter","United States (Los Angeles)",
312         };
313
314         assertTrue("data size", EXPECTED.length == COUNT * DateFormat.FIELD_COUNT);
315
316 //#if defined(FOUNDATION10) || defined(J2SE13)
317 //#else
318         final DateFormat.Field[] DTFMT_FIELDS = {
319             DateFormat.Field.AM_PM,
320             DateFormat.Field.DAY_OF_MONTH,
321             DateFormat.Field.DAY_OF_WEEK,
322             DateFormat.Field.DAY_OF_WEEK_IN_MONTH,
323             DateFormat.Field.DAY_OF_YEAR,
324
325             DateFormat.Field.DOW_LOCAL,
326             DateFormat.Field.ERA,
327             DateFormat.Field.EXTENDED_YEAR,
328             DateFormat.Field.HOUR_OF_DAY0,
329             DateFormat.Field.HOUR_OF_DAY1,
330
331             DateFormat.Field.HOUR0,
332             DateFormat.Field.HOUR1,
333             DateFormat.Field.JULIAN_DAY,
334             DateFormat.Field.MILLISECOND,
335             DateFormat.Field.MILLISECONDS_IN_DAY,
336
337             DateFormat.Field.MINUTE,
338             DateFormat.Field.MONTH,
339             DateFormat.Field.QUARTER,
340             DateFormat.Field.SECOND,
341             DateFormat.Field.TIME_ZONE,
342
343             DateFormat.Field.WEEK_OF_MONTH,
344             DateFormat.Field.WEEK_OF_YEAR,
345             DateFormat.Field.YEAR,
346             DateFormat.Field.YEAR_WOY,
347         };
348
349         final String[][] EXPECTED_BY_FIELD = {
350             {"PM", "13", "Wednesday", "", "",
351              "", "", "", "", "",
352              "", "2", "", "", "",
353              "34", "August", "", "12", "Pacific Daylight Time",
354              "", "", "1997", ""},
355
356             {"", "13", "mercredi", "", "",
357              "", "", "", "14", "",
358              "", "", "", "", "",
359              "34", "ao\u00FBt", "", "12", "heure avanc\u00E9e du Pacifique",
360              "", "", "1997", ""},
361
362             {"PM", "13", "Wed", "2", "225",
363              "4", "AD", "1997", "14", "14",
364              "2", "2", "2450674", "5", "52452513",
365              "34", "8", "3", "12", "PDT",
366              "2", "33", "1997", "1997"},
367
368             {"PM", "0013", "Wednesday", "0002", "0225",
369              "Wednesday", "Anno Domini", "1997", "0014", "0014",
370              "0002", "0002", "2450674", "5130", "52452513",
371              "0034", "August", "3rd quarter", "0012", "Pacific Daylight Time",
372              "0002", "0033", "1997", "1997"},
373         };
374 //#endif
375
376         TimeZone PT = TimeZone.getTimeZone("America/Los_Angeles");
377         for (j = 0, exp = 0; j < COUNT; ++j) {
378             //  String str;
379             DateFormat df = dateFormats[j];
380             df.setTimeZone(PT);
381             logln(" Pattern = " + ((SimpleDateFormat) df).toPattern());
382             try {
383                 logln("  Result = " + df.format(aug13));
384             } catch (Exception e) {
385                 errln("FAIL: " + e);
386                 e.printStackTrace();
387                 continue;
388             }
389
390             FieldPosition pos;
391             String field;
392
393             for (i = 0; i < DateFormat.FIELD_COUNT; ++i, ++exp) {
394                 pos = new FieldPosition(i);
395                 buf.setLength(0);
396                 df.format(aug13, buf, pos);    
397                 field = buf.substring(pos.getBeginIndex(), pos.getEndIndex());
398                 assertEquals("pattern#" + j + " field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
399                              EXPECTED[exp], field);
400             }
401
402 //#if defined(FOUNDATION10) || defined(J2SE13)
403 //#else
404             // FieldPostion initialized by DateFormat.Field trac#6089
405             for(i = 0; i < DTFMT_FIELDS.length; i++) {
406                 // The format method only set position for the first occurrence of
407                 // the specified field.
408                 pos = new FieldPosition(DTFMT_FIELDS[i]);
409                 buf.setLength(0);
410                 df.format(aug13, buf, pos);
411                 field = buf.substring(pos.getBeginIndex(), pos.getEndIndex());
412                 assertEquals("pattern#" + j + " " + DTFMT_FIELDS[i].toString(), EXPECTED_BY_FIELD[j][i], field);
413             }
414 //#endif
415         }
416     }
417     /**
418      * This MUST be kept in sync with DateFormatSymbols.patternChars.
419      */
420     static final String PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqV";
421
422 //#if defined(FOUNDATION10) || defined(J2SE13)
423 //#else
424     /**
425      * A list of the DateFormat.Field.
426      * This MUST be kept in sync with PATTERN_CHARS above.
427      */
428     static final DateFormat.Field[] DATEFORMAT_FIELDS = {
429         DateFormat.Field.ERA,           // G
430         DateFormat.Field.YEAR,          // y
431         DateFormat.Field.MONTH,         // M
432         DateFormat.Field.DAY_OF_MONTH,  // d
433         DateFormat.Field.HOUR_OF_DAY1,  // k
434         DateFormat.Field.HOUR_OF_DAY0,  // H
435         DateFormat.Field.MINUTE,        // m
436         DateFormat.Field.SECOND,        // s
437         DateFormat.Field.MILLISECOND,   // S
438         DateFormat.Field.DAY_OF_WEEK,   // E
439         DateFormat.Field.DAY_OF_YEAR,   // D
440         DateFormat.Field.DAY_OF_WEEK_IN_MONTH,  // F
441         DateFormat.Field.WEEK_OF_YEAR,  // w
442         DateFormat.Field.WEEK_OF_MONTH, // W
443         DateFormat.Field.AM_PM,         // a
444         DateFormat.Field.HOUR1,         // h
445         DateFormat.Field.HOUR0,         // K
446         DateFormat.Field.TIME_ZONE,     // z
447         DateFormat.Field.YEAR_WOY,      // Y
448         DateFormat.Field.DOW_LOCAL,     // e
449         DateFormat.Field.EXTENDED_YEAR, // u
450         DateFormat.Field.JULIAN_DAY,    // g
451         DateFormat.Field.MILLISECONDS_IN_DAY,   // A
452         DateFormat.Field.TIME_ZONE,     // Z
453         DateFormat.Field.TIME_ZONE,     // v
454         DateFormat.Field.DAY_OF_WEEK,   // c
455         DateFormat.Field.MONTH,         // L
456         DateFormat.Field.QUARTER,       // Q
457         DateFormat.Field.QUARTER,       // q
458         DateFormat.Field.TIME_ZONE,     // V
459     };
460 //#endif
461
462     /**
463      * A list of the names of all the fields in DateFormat.
464      * This MUST be kept in sync with DateFormat.
465      */
466     static final String DATEFORMAT_FIELD_NAMES[] = {
467         "ERA_FIELD",
468         "YEAR_FIELD",
469         "MONTH_FIELD",
470         "DATE_FIELD",
471         "HOUR_OF_DAY1_FIELD",
472         "HOUR_OF_DAY0_FIELD",
473         "MINUTE_FIELD",
474         "SECOND_FIELD",
475         "MILLISECOND_FIELD",
476         "DAY_OF_WEEK_FIELD",
477         "DAY_OF_YEAR_FIELD",
478         "DAY_OF_WEEK_IN_MONTH_FIELD",
479         "WEEK_OF_YEAR_FIELD",
480         "WEEK_OF_MONTH_FIELD",
481         "AM_PM_FIELD",
482         "HOUR1_FIELD",
483         "HOUR0_FIELD",
484         "TIMEZONE_FIELD",
485         "YEAR_WOY_FIELD",
486         "DOW_LOCAL_FIELD",
487         "EXTENDED_YEAR_FIELD",
488         "JULIAN_DAY_FIELD",
489         "MILLISECONDS_IN_DAY_FIELD",
490         "TIMEZONE_RFC_FIELD",
491         "GENERIC_TIMEZONE_FIELD",
492         "STAND_ALONE_DAY_FIELD",
493         "STAND_ALONE_MONTH_FIELD",
494         "QUARTER_FIELD",
495         "STAND_ALONE_QUARTER_FIELD",
496         "TIMEZONE_SPECIAL_FIELD",
497     };
498
499     /**
500      * General parse/format tests.  Add test cases as needed.
501      */
502     public void TestGeneral() {
503         
504         String DATA[] = {
505             "yyyy MM dd HH:mm:ss.SSS",
506
507             // Milliseconds are left-justified, since they format as fractions of a second
508             // Both format and parse should round HALF_UP
509             "y/M/d H:mm:ss.S", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.6", "2004 03 10 16:36:31.600",
510             "y/M/d H:mm:ss.SS", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.57", "2004 03 10 16:36:31.570",
511             "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567",
512             "y/M/d H:mm:ss.SSSS", "pf", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.568", "2004/3/10 16:36:31.5680",
513         };
514         expect(DATA, new Locale("en", "", ""));
515     }
516
517     public void TestGenericTime() {
518
519
520         // any zone pattern should parse any zone
521         Locale en = new Locale("en", "", "");
522         String ZDATA[] = {
523             "yyyy MM dd HH:mm zzz",
524             // round trip
525             "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
526             "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
527             "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
528             "y/M/d H:mm v", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
529             // non-generic timezone string influences dst offset even if wrong for date/time
530             "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PDT", "2004 01 01 01:00 PDT", "2004/1/1 0:00 PST",
531             "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PDT", "2004 01 01 01:00 PDT", "2004/1/1 0:00 Pacific Time",
532             "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PST", "2004 07 01 02:00 PDT", "2004/7/1 2:00 PDT",
533             "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PST", "2004 07 01 02:00 PDT", "2004/7/1 2:00 Pacific Time",
534             // generic timezone generates dst offset appropriate for local time
535             "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
536             "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
537             "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
538             "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 Pacific Time",
539             // daylight savings time transition edge cases.
540             // time to parse does not really exist, PT interpreted as earlier time
541             "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PT", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PDT",
542             "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PST", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PDT",
543             "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PDT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PST",
544             "y/M/d H:mm v", "pf", "2005/4/3 2:30 PT", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PT",
545             "y/M/d H:mm v", "pf", "2005/4/3 2:30 PST", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PT",
546             "y/M/d H:mm v", "pf", "2005/4/3 2:30 PDT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PT",
547             "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 03:30 PDT", "2005/4/3 3:30",
548             // time to parse is ambiguous, PT interpreted as later time
549             "y/M/d H:mm zzz", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30 PST",
550             "y/M/d H:mm v", "pf", "2005/10/30 1:30 PT", "2005 10 30  01:30 PST", "2005/10/30 1:30 PT",
551             "y/M/d H:mm", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30",
552
553             "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PT", "2004 10 31 01:30 PST", "2004/10/31 1:30 PST",
554              "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PST", "2004 10 31 01:30 PST", "2004/10/31 1:30 PST",
555              "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PDT", "2004 10 31 01:30 PDT", "2004/10/31 1:30 PDT",
556              "y/M/d H:mm v", "pf", "2004/10/31 1:30 PT", "2004 10 31 01:30 PST", "2004/10/31 1:30 PT",
557              "y/M/d H:mm v", "pf", "2004/10/31 1:30 PST", "2004 10 31 01:30 PST", "2004/10/31 1:30 PT",
558              "y/M/d H:mm v", "pf", "2004/10/31 1:30 PDT", "2004 10 31 01:30 PDT", "2004/10/31 1:30 PT",
559              "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
560             // Below is actually an invalid test case.  See the note in #5910.  Disable the case for now.
561             // TODO: Revisit after 3.8
562             //"y/M/d H:mm vvvv", "pf", "2004/10/31 1:30 Argentina Time", "2004 10 30 21:30 PDT", "2004/10/31 1:30 Argentina Time",
563         };
564         expect(ZDATA, en);
565
566         logln("cross format/parse tests");
567         final String basepat = "yy/MM/dd H:mm ";
568         final SimpleDateFormat[] formats = { 
569             new SimpleDateFormat(basepat + "v", en),
570             new SimpleDateFormat(basepat + "vvvv", en),
571             new SimpleDateFormat(basepat + "zzz", en),
572             new SimpleDateFormat(basepat + "zzzz", en)
573         };
574
575         final SimpleDateFormat univ = new SimpleDateFormat("yyyy MM dd HH:mm zzz", en);
576         final String[] times = { "2004 01 02 03:04 PST", "2004 07 08 09:10 PDT" };
577         for (int i = 0; i < times.length; ++i) {
578             try {
579                 Date d = univ.parse(times[i]);
580                 logln("time: " + d);
581                 for (int j = 0; j < formats.length; ++j) {
582                     String test = formats[j].format(d);
583                     logln("test: '" + test + "'");
584                     for (int k = 0; k < formats.length; ++k) {
585                         try {
586                             Date t = formats[k].parse(test);
587                             if (!d.equals(t)) {
588                                 errln("format " + k + 
589                                       " incorrectly parsed output of format " + j + 
590                                       " (" + test + "), returned " +
591                                       t + " instead of " + d);
592                             } else {
593                                 logln("format " + k + " parsed ok");
594                             }
595                         }
596                         catch (ParseException e) {
597                             errln("format " + k + 
598                                   " could not parse output of format " + j + 
599                                   " (" + test + ")");
600                         }
601                     }
602                 }
603             }
604             catch (ParseException e) {
605                 errln("univ could not parse: " + times[i]);
606             }
607         }
608
609     }
610
611     public void TestGenericTimeZoneOrder() {
612         // generic times should parse the same no matter what the placement of the time zone string
613         // should work for standard and daylight times
614
615         String XDATA[] = {
616             "yyyy MM dd HH:mm zzz",
617             // standard time, explicit daylight/standard
618             "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
619             "y/M/d zzz H:mm", "pf", "2004/1/1 PT 1:00", "2004 01 01 01:00 PST", "2004/1/1 PST 1:00",
620             "zzz y/M/d H:mm", "pf", "PT 2004/1/1 1:00", "2004 01 01 01:00 PST", "PST 2004/1/1 1:00",
621
622             // standard time, generic
623             "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
624             "y/M/d vvvv H:mm", "pf", "2004/1/1 PT 1:00", "2004 01 01 01:00 PST", "2004/1/1 Pacific Time 1:00",
625             "vvvv y/M/d H:mm", "pf", "PT 2004/1/1 1:00", "2004 01 01 01:00 PST", "Pacific Time 2004/1/1 1:00",
626
627             // daylight time, explicit daylight/standard
628             "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
629             "y/M/d zzz H:mm", "pf", "2004/7/1 PT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 PDT 1:00",
630             "zzz y/M/d H:mm", "pf", "PT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "PDT 2004/7/1 1:00",
631
632             // daylight time, generic
633             "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 Pacific Time",
634             "y/M/d vvvv H:mm", "pf", "2004/7/1 PT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 Pacific Time 1:00",
635             "vvvv y/M/d H:mm", "pf", "PT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "Pacific Time 2004/7/1 1:00",
636         };
637         Locale en = new Locale("en", "", "");
638         expect(XDATA, en);
639     }
640
641     public void TestTimeZoneDisplayName() {
642         Calendar cal = new GregorianCalendar();
643         SimpleDateFormat testfmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
644
645         for (int i = 0; i < fallbackTests.length; ++i) {
646             String[] info = fallbackTests[i];
647             logln(info[0] + ";" + info[1] + ";" + info[2] + ";" + info[3]);
648
649             long time = 0;
650             try {
651                 Date testd = testfmt.parse(info[2]);
652                 time = testd.getTime();
653             } catch (ParseException pe) {
654                 errln("Failed to parse test date data");
655                 continue;
656             }
657             ULocale l = new ULocale(info[0]);
658             TimeZone tz = TimeZone.getTimeZone(info[1]);
659             SimpleDateFormat fmt = new SimpleDateFormat(info[3], l);
660             cal.setTimeInMillis(time);
661             cal.setTimeZone(tz);
662             String result = fmt.format(cal);
663             if (!result.equals(info[4])) {
664                 errln(info[0] + ";" + info[1] + ";" + info[2] + ";" + info[3] + " expected: '" + 
665                       info[4] + "' but got: '" + result + "'");
666             }
667         }
668     }
669
670     private static final String GMT_BG = "\u0413\u0440\u0438\u0438\u043D\u0443\u0438\u0447";
671     private static final String GMT_ZH = "\u683C\u6797\u5C3C\u6CBB\u6807\u51C6\u65F6\u95F4";
672     //private static final String GMT_BG = "GMT";
673
674     private static final String[][] fallbackTests  = {
675         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
676         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
677         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" },
678         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "V", "PST", "America/Los_Angeles" },
679         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Pacific Standard Time", "America/Los_Angeles" },
680         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
681         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
682         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" },
683         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "V", "PDT", "America/Los_Angeles" },
684         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Pacific Daylight Time", "America/Los_Angeles" },
685         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
686         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Pacific Time", "America/Los_Angeles" },
687         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "United States (Los Angeles)", "America/Los_Angeles" },
688         { "en_GB", "America/Los_Angeles", "2004-01-15T12:00:00Z", "z", "PST", "America/Los_Angeles" },
689         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "Z", "-0700", "-7:00" },
690         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
691         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "z", "MST", "America/Phoenix" },
692         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "V", "MST", "America/Phoenix" },
693         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
694         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
695         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
696         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "z", "MST", "America/Phoenix" },
697         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "V", "MST", "America/Phoenix" },
698         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
699         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "v", "MST", "America/Phoenix" },
700         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "vvvv", "Mountain Standard Time", "America/Phoenix" },
701         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "VVVV", "United States (Phoenix)", "America/Phoenix" },
702
703         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
704         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
705         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
706         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "V", "ART", "-3:00" },
707         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Time", "-3:00" },
708         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
709         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
710         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
711         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "V", "ART", "-3:00" },
712         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Time", "-3:00" },
713         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Argentina (Buenos Aires)", "America/Buenos_Aires" },
714         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Time", "America/Buenos_Aires" },
715         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Argentina (Buenos Aires)", "America/Buenos_Aires" },
716
717         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
718         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
719         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
720         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "V", "ART", "-3:00" },
721         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Time", "-3:00" },
722         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
723         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
724         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
725         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "V", "ART", "-3:00" },
726         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Time", "-3:00" },
727         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Argentina (Buenos Aires)", "America/Buenos_Aires" },
728         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Time", "America/Buenos_Aires" },
729         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Argentina (Buenos Aires)", "America/Buenos_Aires" },
730
731         { "en", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
732         { "en", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
733         { "en", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-05:00", "-5:00" },
734         { "en", "America/Havana", "2004-01-15T00:00:00Z", "V", "CST (Cuba)", "-5:00" },
735         { "en", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Cuba Standard Time", "-5:00" },
736         { "en", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
737         { "en", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
738         { "en", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-04:00", "-4:00" },
739         { "en", "America/Havana", "2004-07-15T00:00:00Z", "V", "CDT (Cuba)", "-4:00" },
740         { "en", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Cuba Daylight Time", "-4:00" },
741         { "en", "America/Havana", "2004-07-15T00:00:00Z", "v", "Cuba Time", "America/Havana" },
742         { "en", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Cuba Time", "America/Havana" },
743         { "en", "America/Havana", "2004-07-15T00:00:00Z", "VVVV", "Cuba Time", "America/Havana" },
744
745         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
746         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
747         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
748         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "V", "AEDT", "+11:00" },
749         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
750         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
751         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
752         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
753         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "V", "AEST", "+10:00" },
754         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
755         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Australia (Sydney)", "Australia/Sydney" },
756         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
757         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "VVVV", "Australia (Sydney)", "Australia/Sydney" },
758
759         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
760         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
761         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
762         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "V", "AEDT", "+11:00" },
763         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
764         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
765         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
766         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
767         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "V", "AEST", "+10:00" },
768         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
769         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Australia (Sydney)", "Australia/Sydney" },
770         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
771         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "VVVV", "Australia (Sydney)", "Australia/Sydney" },
772
773         { "en", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
774         { "en", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+00:00", "+0:00" },
775         { "en", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
776         { "en", "Europe/London", "2004-01-15T00:00:00Z", "V", "GMT", "+0:00" },
777         { "en", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Greenwich Mean Time", "+0:00" },
778         { "en", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
779         { "en", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
780         { "en", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+01:00", "Europe/London" },
781         { "en", "Europe/London", "2004-07-15T00:00:00Z", "V", "BST", "Europe/London" },
782         { "en", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "British Summer Time", "Europe/London" },
783     // icu en.txt has exemplar city for this time zone
784         { "en", "Europe/London", "2004-07-15T00:00:00Z", "v", "United Kingdom Time", "Europe/London" },
785         { "en", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "United Kingdom Time", "Europe/London" },
786         { "en", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "United Kingdom Time", "Europe/London" },
787
788         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
789         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
790         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
791         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
792         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
793         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
794         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
795         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
796         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-03:00", "-3:00" },
797         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
798
799         // JB#5150
800         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
801         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
802         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+05:30", "+5:30" },
803         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "V", "IST", "+5:30" },
804         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
805         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
806         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
807         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+05:30", "+05:30" },
808         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "V", "IST", "+05:30" },
809         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
810         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "India Time", "Asia/Calcutta" },
811         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "India Standard Time", "Asia/Calcutta" },
812         
813         // ==========
814
815         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
816         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
817         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-08:00", "-8:00" },
818         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "GMT-08:00", "-8:00" },
819         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
820         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
821         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-07:00", "-7:00" },
822         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "GMT-07:00", "-7:00" },
823         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "Vereinigte Staaten (Los Angeles)", "America/Los_Angeles" },
824         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Vereinigte Staaten (Los Angeles)", "America/Los_Angeles" },
825
826         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
827         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
828         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
829         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
830         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
831         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
832         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
833         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
834         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Argentinien (Buenos Aires)", "America/Buenos_Aires" },
835         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinien (Buenos Aires)", "America/Buenos_Aires" },
836
837         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
838         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
839         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
840         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
841         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
842         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
843         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
844         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
845         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Argentinien (Buenos Aires)", "America/Buenos_Aires" },
846         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinien (Buenos Aires)", "America/Buenos_Aires" },
847
848         { "de", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
849         { "de", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
850         { "de", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-05:00", "-5:00" },
851         { "de", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-05:00", "-5:00" },
852         { "de", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
853         { "de", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
854         { "de", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-04:00", "-4:00" },
855         { "de", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-04:00", "-4:00" },
856         { "de", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba", "America/Havana" },
857         { "de", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kuba", "America/Havana" },
858         // added to test proper fallback of country name
859         { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba", "America/Havana" },
860         { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kuba", "America/Havana" },
861
862         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
863         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
864         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
865         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
866         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
867         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
868         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
869         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
870         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Australien (Sydney)", "Australia/Sydney" },
871         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Australien (Sydney)", "Australia/Sydney" },
872
873         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
874         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
875         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
876         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
877         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
878         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
879         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
880         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
881         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Australien (Sydney)", "Australia/Sydney" },
882         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Australien (Sydney)", "Australia/Sydney" },
883
884         { "de", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
885         { "de", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+00:00", "+0:00" },
886         { "de", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT+00:00", "+0:00" },
887         { "de", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "GMT+00:00", "+0:00" },
888         { "de", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
889         { "de", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
890         { "de", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+01:00", "+1:00" },
891         { "de", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" },
892         { "de", "Europe/London", "2004-07-15T00:00:00Z", "v", "Vereinigtes K\u00f6nigreich", "Europe/London" },
893         { "de", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "Vereinigtes K\u00f6nigreich", "Europe/London" },
894
895         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
896         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
897         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
898         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
899         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
900         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
901         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
902         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
903         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-03:00", "-3:00" },
904         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
905
906         // JB#5150
907         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
908         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
909         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+05:30", "+5:30" },
910         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
911         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
912         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
913         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+05:30", "+05:30" },
914         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
915         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "Indien", "Asia/Calcutta" },
916         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "Indien", "Asia/Calcutta" },
917
918         // ==========
919
920         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
921         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0800", "-8:00" },
922         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", GMT_ZH+"-0800", "America/Los_Angeles" },
923         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4", "America/Los_Angeles" },
924         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
925         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0700", "-7:00" },
926         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", GMT_ZH+"-0700", "America/Los_Angeles" },
927         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\u592a\u5e73\u6d0b\u590f\u4ee4\u65f6\u95f4", "America/Los_Angeles" },
928     // icu zh.txt has exemplar city for this time zone
929         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\u7f8e\u56fd (\u6d1b\u6749\u77f6)", "America/Los_Angeles" },
930         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\u7f8e\u56fd\u592a\u5e73\u6d0b\u65f6\u95f4", "America/Los_Angeles" },
931
932         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
933         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0300", "-3:00" },
934         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", GMT_ZH+"-0300", "-3:00" },
935         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\u963f\u6839\u5ef7\u6807\u51c6\u65f6\u95f4", "-3:00" },
936         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
937         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0300", "-3:00" },
938         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", GMT_ZH+"-0300", "-3:00" },
939         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\u963f\u6839\u5ef7\u6807\u51c6\u65f6\u95f4", "-3:00" },
940     // icu zh.txt does not have info for this time zone
941         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u963f\u6839\u5ef7 (\u5e03\u5b9c\u8bfa\u65af\u827e\u5229\u65af)", "America/Buenos_Aires" },
942         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u963f\u6839\u5ef7\u6807\u51c6\u65f6\u95f4", "America/Buenos_Aires" },
943
944         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
945         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0300", "-3:00" },
946         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", GMT_ZH+"-0300", "-3:00" },
947         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\u963f\u6839\u5ef7\u6807\u51c6\u65f6\u95f4", "-3:00" },
948         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
949         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0300", "-3:00" },
950         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", GMT_ZH+"-0300", "-3:00" },
951         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\u963f\u6839\u5ef7\u6807\u51c6\u65f6\u95f4", "-3:00" },
952         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u963f\u6839\u5ef7 (\u5e03\u5b9c\u8bfa\u65af\u827e\u5229\u65af)", "America/Buenos_Aires" },
953         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u963f\u6839\u5ef7\u6807\u51c6\u65f6\u95f4", "America/Buenos_Aires" },
954
955         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
956         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0500", "-5:00" },
957         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "z", GMT_ZH+"-0500", "-5:00" },
958         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\u53e4\u5df4\u6807\u51c6\u65f6\u95f4", "-5:00" },
959         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
960         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0400", "-4:00" },
961         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "z", GMT_ZH+"-0400", "-4:00" },
962         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\u53e4\u5df4\u590f\u4ee4\u65f6\u95f4", "-4:00" },
963         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "v", "\u53e4\u5df4\u65f6\u95f4", "America/Havana" },
964         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\u53e4\u5df4\u65f6\u95f4", "America/Havana" },
965
966         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
967         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"+1100", "+11:00" },
968         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "z", GMT_ZH+"+1100", "+11:00" },
969         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\u6fb3\u5927\u5229\u4e9a\u4e1c\u90e8\u590f\u4ee4\u65f6\u95f4", "+11:00" },
970         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
971         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"+1000", "+10:00" },
972         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "z", GMT_ZH+"+1000", "+10:00" },
973         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\u6fb3\u5927\u5229\u4e9a\u4e1c\u90e8\u6807\u51c6\u65f6\u95f4", "+10:00" },
974         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\u6fb3\u5927\u5229\u4e9a (\u6089\u5c3c)", "Australia/Sydney" },
975         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\u6fb3\u5927\u5229\u4e9a\u4e1c\u90e8\u65f6\u95f4", "Australia/Sydney" },
976
977         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
978         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"+1100", "+11:00" },
979         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", GMT_ZH+"+1100", "+11:00" },
980         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\u6fb3\u5927\u5229\u4e9a\u4e1c\u90e8\u590f\u4ee4\u65f6\u95f4", "+11:00" },
981         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
982         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"+1000", "+10:00" },
983         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", GMT_ZH+"+1000", "+10:00" },
984         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\u6fb3\u5927\u5229\u4e9a\u4e1c\u90e8\u6807\u51c6\u65f6\u95f4",  "+10:00" },
985         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\u6fb3\u5927\u5229\u4e9a (\u6089\u5c3c)", "Australia/Sydney" },
986         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\u6fb3\u5927\u5229\u4e9a\u4e1c\u90e8\u65f6\u95f4", "Australia/Sydney" },
987
988         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
989         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"+0000", "+0:00" },
990         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", GMT_ZH+"+0000", "+0:00" },
991         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "V", "GMT", "+0:00" },
992         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\u683C\u6797\u5C3C\u6CBB\u6807\u51C6\u65F6\u95F4", "+0:00" },
993         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
994         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"+0100", "+1:00" },
995         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "z", GMT_ZH+"+0100", "+1:00" },
996         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "V", "BST", "+1:00" },
997         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", GMT_ZH+"+0100", "+1:00" },
998         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "v", "\u82f1\u56fd\u65f6\u95f4", "Europe/London" },
999         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\u82f1\u56fd\u65f6\u95f4", "Europe/London" },
1000         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\u82f1\u56fd\u65f6\u95f4", "Europe/London" },
1001
1002         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1003         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0300", "-3:00" },
1004         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", GMT_ZH+"-0300", "-3:00" },
1005         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", GMT_ZH+"-0300", "-3:00" },
1006         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1007         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"-0300", "-3:00" },
1008         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", GMT_ZH+"-0300", "-3:00" },
1009         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", GMT_ZH+"-0300", "-3:00" },
1010         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", GMT_ZH+"-0300", "-3:00" },
1011         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", GMT_ZH+"-0300", "-3:00" },
1012
1013         // JB#5150
1014         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
1015         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", GMT_ZH+"+0530", "+5:30" },
1016         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", GMT_ZH+"+0530", "+5:30" },
1017         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\u5370\u5ea6\u6807\u51c6\u65f6\u95f4", "+5:30" },
1018         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
1019         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", GMT_ZH+"+0530", "+5:30" },
1020         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", GMT_ZH+"+0530", "+05:30" },
1021         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\u5370\u5ea6\u6807\u51c6\u65f6\u95f4", "+5:30" },
1022         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\u5370\u5ea6\u65f6\u95f4", "Asia/Calcutta" },
1023         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\u5370\u5EA6\u6807\u51c6\u65f6\u95f4", "Asia/Calcutta" },
1024
1025         // ==========
1026
1027         { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
1028         { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u096e:\u0966\u0966", "-8:00" },
1029         { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-\u0966\u096e:\u0966\u0966", "-8:00" },
1030         { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "GMT-\u0966\u096e:\u0966\u0966", "-8:00" },
1031         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
1032         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u096d:\u0966\u0966", "-7:00" },
1033         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-\u0966\u096d:\u0966\u0966", "-7:00" },
1034         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "GMT-\u0966\u096d:\u0966\u0966", "-7:00" },
1035         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\u0938\u0902\u092f\u0941\u0915\u094d\u0924 \u0930\u093e\u091c\u094d\u092f \u0905\u092e\u0947\u0930\u093f\u0915\u093e (\u0932\u094b\u0938 \u090f\u0902\u091c\u093f\u0932\u0947\u0938)", "America/Los_Angeles" },
1036         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\u0938\u0902\u092f\u0941\u0915\u094d\u0924 \u0930\u093e\u091c\u094d\u092f \u0905\u092e\u0947\u0930\u093f\u0915\u093e (\u0932\u094b\u0938 \u090f\u0902\u091c\u093f\u0932\u0947\u0938)", "America/Los_Angeles" },
1037
1038         { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1039         { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1040         { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1041         { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1042         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1043         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1044         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1045         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1046         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u0905\u0930\u094d\u091c\u0947\u0928\u094d\u091f\u0940\u0928\u093e (\u092c\u094d\u092f\u0942\u0928\u0938 \u0906\u092f\u0930\u0938)", "America/Buenos_Aires" },
1047         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u0905\u0930\u094d\u091c\u0947\u0928\u094d\u091f\u0940\u0928\u093e (\u092c\u094d\u092f\u0942\u0928\u0938 \u0906\u092f\u0930\u0938)", "America/Buenos_Aires" },
1048
1049         { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1050         { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1051         { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1052         { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1053         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1054         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1055         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1056         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1057         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u0905\u0930\u094d\u091c\u0947\u0928\u094d\u091f\u0940\u0928\u093e (\u092c\u094d\u092f\u0942\u0928\u0938 \u0906\u092f\u0930\u0938)", "America/Buenos_Aires" },
1058         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u0905\u0930\u094d\u091c\u0947\u0928\u094d\u091f\u0940\u0928\u093e (\u092c\u094d\u092f\u0942\u0928\u0938 \u0906\u092f\u0930\u0938)", "America/Buenos_Aires" },
1059
1060         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
1061         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u096b:\u0966\u0966", "-5:00" },
1062         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-\u0966\u096b:\u0966\u0966", "-5:00" },
1063         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-\u0966\u096b:\u0966\u0966", "-5:00" },
1064         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
1065         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u096a:\u0966\u0966", "-4:00" },
1066         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-\u0966\u096a:\u0966\u0966", "-4:00" },
1067         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-\u0966\u096a:\u0966\u0966", "-4:00" },
1068         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "v", "\u0915\u094d\u092f\u0942\u092c\u093e", "America/Havana" },
1069         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\u0915\u094d\u092f\u0942\u092c\u093e", "America/Havana" },
1070
1071         { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1072         { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+\u0967\u0967:\u0966\u0966", "+11:00" },
1073         { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+\u0967\u0967:\u0966\u0966", "+11:00" },
1074         { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+\u0967\u0967:\u0966\u0966", "+11:00" },
1075         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1076         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\u0967\u0966:\u0966\u0966", "+10:00" },
1077         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+\u0967\u0966:\u0966\u0966", "+10:00" },
1078         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+\u0967\u0966:\u0966\u0966", "+10:00" },
1079         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\u0911\u0938\u094d\u091f\u094d\u0930\u0947\u0932\u093f\u092f\u093e (\u0938\u093f\u0921\u0928\u0940)", "Australia/Sydney" },
1080         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\u0911\u0938\u094d\u091f\u094d\u0930\u0947\u0932\u093f\u092f\u093e (\u0938\u093f\u0921\u0928\u0940)", "Australia/Sydney" },
1081
1082         { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1083         { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+\u0967\u0967:\u0966\u0966", "+11:00" },
1084         { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+\u0967\u0967:\u0966\u0966", "+11:00" },
1085         { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+\u0967\u0967:\u0966\u0966", "+11:00" },
1086         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1087         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\u0967\u0966:\u0966\u0966", "+10:00" },
1088         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+\u0967\u0966:\u0966\u0966", "+10:00" },
1089         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+\u0967\u0966:\u0966\u0966", "+10:00" },
1090         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\u0911\u0938\u094d\u091f\u094d\u0930\u0947\u0932\u093f\u092f\u093e (\u0938\u093f\u0921\u0928\u0940)", "Australia/Sydney" },
1091         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\u0911\u0938\u094d\u091f\u094d\u0930\u0947\u0932\u093f\u092f\u093e (\u0938\u093f\u0921\u0928\u0940)", "Australia/Sydney" },
1092
1093         { "hi", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
1094         { "hi", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+\u0966\u0966:\u0966\u0966", "+0:00" },
1095         { "hi", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT+\u0966\u0966:\u0966\u0966", "+0:00" },
1096         { "hi", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "GMT+\u0966\u0966:\u0966\u0966", "+0:00" },
1097         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
1098         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\u0966\u0967:\u0966\u0966", "+1:00" },
1099         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+\u0966\u0967:\u0966\u0966", "+1:00" },
1100         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+\u0966\u0967:\u0966\u0966", "+1:00" },
1101         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "v", "\u092C\u094D\u0930\u093F\u0924\u0928", "Europe/London" },
1102         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\u092C\u094D\u0930\u093F\u0924\u0928", "Europe/London" },
1103
1104         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1105         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1106         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1107         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1108         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1109         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1110         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1111         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1112         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1113         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-\u0966\u0969:\u0966\u0966", "-3:00" },
1114
1115         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
1116         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+\u0966\u096B:\u0969\u0966", "+5:30" },
1117         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "IST", "+5:30" },
1118         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\u092D\u093E\u0930\u0924\u0940\u092F \u0938\u092E\u092F", "+5:30" },
1119         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
1120         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\u0966\u096B:\u0969\u0966", "+5:30" },
1121         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "IST", "+05:30" },
1122         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\u092D\u093E\u0930\u0924\u0940\u092F \u0938\u092E\u092F", "+5:30" },
1123         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IST", "Asia/Calcutta" },
1124         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\u092D\u093E\u0930\u0924\u0940\u092F \u0938\u092E\u092F", "Asia/Calcutta" },
1125
1126         // ==========
1127
1128         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
1129         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"-0800", "-8:00" },
1130         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", GMT_BG+"-0800", "America/Los_Angeles" },
1131         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "V", "PST", "America/Los_Angeles" },
1132         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\u0422\u0438\u0445\u043E\u043E\u043A\u0435\u0430\u043D\u0441\u043A\u0430 \u0447\u0430\u0441\u043E\u0432\u0430 \u0437\u043E\u043D\u0430", "America/Los_Angeles" },
1133         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
1134         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"-0700", "-7:00" },
1135         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", GMT_BG+"-0700", "America/Los_Angeles" },
1136         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "V", "PDT", "America/Los_Angeles" },
1137         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\u0422\u0438\u0445\u043E\u043E\u043A\u0435\u0430\u043D\u0441\u043A\u0430 \u043B\u044F\u0442\u043D\u0430 \u0447\u0430\u0441\u043E\u0432\u0430 \u0437\u043E\u043D\u0430", "America/Los_Angeles" },
1138     // icu bg.txt has exemplar city for this time zone
1139         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\u0421\u0410\u0429 (\u041b\u043e\u0441 \u0410\u043d\u0436\u0435\u043b\u0438\u0441)", "America/Los_Angeles" },
1140         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\u0421\u0410\u0429 (\u041b\u043e\u0441 \u0410\u043d\u0436\u0435\u043b\u0438\u0441)", "America/Los_Angeles" },
1141         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\u0421\u0410\u0429 (\u041b\u043e\u0441 \u0410\u043d\u0436\u0435\u043b\u0438\u0441)", "America/Los_Angeles" },
1142
1143         { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1144         { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"-0300", "-3:00" },
1145         { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", GMT_BG+"-0300", "-3:00" },
1146         { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", GMT_BG+"-0300", "-3:00" },
1147         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1148         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"-0300", "-3:00" },
1149         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", GMT_BG+"-0300", "-3:00" },
1150         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"-0300", "-3:00" },
1151         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u0410\u0440\u0436\u0435\u043d\u0442\u0438\u043d\u0430 (\u0411\u0443\u0435\u043D\u043E\u0441 \u0410\u0439\u0440\u0435\u0441)", "America/Buenos_Aires" },
1152         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u0410\u0440\u0436\u0435\u043d\u0442\u0438\u043d\u0430 (\u0411\u0443\u0435\u043D\u043E\u0441 \u0410\u0439\u0440\u0435\u0441)", "America/Buenos_Aires" },
1153
1154         { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1155         { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"-0300", "-3:00" },
1156         { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", GMT_BG+"-0300", "-3:00" },
1157         { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", GMT_BG+"-0300", "-3:00" },
1158         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1159         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"-0300", "-3:00" },
1160         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", GMT_BG+"-0300", "-3:00" },
1161         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"-0300", "-3:00" },
1162     // icu bg.txt does not have info for this time zone
1163         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u0410\u0440\u0436\u0435\u043d\u0442\u0438\u043d\u0430 (\u0411\u0443\u0435\u043D\u043E\u0441 \u0410\u0439\u0440\u0435\u0441)", "America/Buenos_Aires" },
1164         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u0410\u0440\u0436\u0435\u043d\u0442\u0438\u043d\u0430 (\u0411\u0443\u0435\u043D\u043E\u0441 \u0410\u0439\u0440\u0435\u0441)", "America/Buenos_Aires" },
1165
1166         { "bg", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
1167         { "bg", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"-0500", "-5:00" },
1168         { "bg", "America/Havana", "2004-01-15T00:00:00Z", "z", GMT_BG+"-0500", "-5:00" },
1169         { "bg", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", GMT_BG+"-0500", "-5:00" },
1170         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
1171         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"-0400", "-4:00" },
1172         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "z", GMT_BG+"-0400", "-4:00" },
1173         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"-0400", "-4:00" },
1174         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "v", "\u041a\u0443\u0431\u0430", "America/Havana" },
1175         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\u041a\u0443\u0431\u0430", "America/Havana" },
1176
1177         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1178         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"+1100", "+11:00" },
1179         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "z", GMT_BG+"+1100", "+11:00" },
1180         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", GMT_BG+"+1100", "+11:00" },
1181         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1182         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"+1000", "+10:00" },
1183         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "z", GMT_BG+"+1000", "+10:00" },
1184         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"+1000", "+10:00" },
1185         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\u0410\u0432\u0441\u0442\u0440\u0430\u043b\u0438\u044f (\u0421\u0438\u0434\u043D\u0438)", "Australia/Sydney" },
1186         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\u0410\u0432\u0441\u0442\u0440\u0430\u043b\u0438\u044f (\u0421\u0438\u0434\u043D\u0438)", "Australia/Sydney" },
1187
1188         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1189         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"+1100", "+11:00" },
1190         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", GMT_BG+"+1100", "+11:00" },
1191         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", GMT_BG+"+1100", "+11:00" },
1192         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1193         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"+1000", "+10:00" },
1194         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", GMT_BG+"+1000", "+10:00" },
1195         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"+1000", "+10:00" },
1196         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\u0410\u0432\u0441\u0442\u0440\u0430\u043b\u0438\u044f (\u0421\u0438\u0434\u043D\u0438)", "Australia/Sydney" },
1197         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\u0410\u0432\u0441\u0442\u0440\u0430\u043b\u0438\u044f (\u0421\u0438\u0434\u043D\u0438)", "Australia/Sydney" },
1198
1199         { "bg", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
1200         { "bg", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"+0000", "+0:00" },
1201         { "bg", "Europe/London", "2004-01-15T00:00:00Z", "z", GMT_BG+"+0000", "+0:00" },
1202         { "bg", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\u0427\u0430\u0441\u043E\u0432\u0430 \u0437\u043E\u043D\u0430 \u0413\u0440\u0438\u043D\u0443\u0438\u0447", "+0:00" },
1203         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
1204         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"+0100", "+1:00" },
1205         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "z", GMT_BG+"+0100", "+1:00" },
1206         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"+0100", "+1:00" },
1207         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "v", "\u041e\u0431\u0435\u0434\u0438\u043d\u0435\u043d\u043e \u043a\u0440\u0430\u043b\u0441\u0442\u0432\u043e", "Europe/London" },
1208         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\u041e\u0431\u0435\u0434\u0438\u043d\u0435\u043d\u043e \u043a\u0440\u0430\u043b\u0441\u0442\u0432\u043e", "Europe/London" },
1209
1210         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1211         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"-0300", "-3:00" },
1212         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", GMT_BG+"-0300", "-3:00" },
1213         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", GMT_BG+"-0300", "-3:00" },
1214         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1215         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"-0300", "-3:00" },
1216         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", GMT_BG+"-0300", "-3:00" },
1217         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"-0300", "-3:00" },
1218         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", GMT_BG+"-0300", "-3:00" },
1219         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", GMT_BG+"-0300", "-3:00" },
1220
1221         // JB#5150
1222         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
1223         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", GMT_BG+"+0530", "+5:30" },
1224         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", GMT_BG+"+0530", "+5:30" },
1225         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", GMT_BG+"+0530", "+5:30" },
1226         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
1227         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", GMT_BG+"+0530", "+5:30" },
1228         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", GMT_BG+"+0530", "+05:30" },
1229         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", GMT_BG+"+0530", "+5:30" },
1230         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\u0418\u043D\u0434\u0438\u044F", "Asia/Calcutta" },
1231         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\u0418\u043D\u0434\u0438\u044F", "Asia/Calcutta" },
1232
1233     // ==========
1234
1235         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
1236         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
1237         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-08:00", "America/Los_Angeles" },
1238         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "V", "PST", "America/Los_Angeles" },
1239         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u6a19\u6e96\u6642", "America/Los_Angeles" },
1240         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
1241         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
1242         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-07:00", "America/Los_Angeles" },
1243         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "V", "PDT", "America/Los_Angeles" },
1244         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593", "America/Los_Angeles" },
1245     // icu ja.txt has exemplar city for this time zone
1246         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\u30A2\u30E1\u30EA\u30AB\u5408\u8846\u56FD (\u30ed\u30b5\u30f3\u30bc\u30eb\u30b9)", "America/Los_Angeles" },
1247         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\u30A2\u30E1\u30EA\u30AB\u592A\u5E73\u6D0B\u6642\u9593", "America/Los_Angeles" },
1248         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\u30A2\u30E1\u30EA\u30AB\u5408\u8846\u56FD (\u30ed\u30b5\u30f3\u30bc\u30eb\u30b9)", "America/Los_Angeles" },
1249
1250         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1251         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1252         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1253         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1254         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1255         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1256         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1257         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1258     // icu ja.txt does not have info for this time zone
1259         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3 (\u30D6\u30A8\u30CE\u30B9\u30A2\u30A4\u30EC\u30B9)", "America/Buenos_Aires" },
1260         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3\u6642\u9593", "America/Buenos_Aires" },
1261
1262         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1263         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1264         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1265         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1266         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1267         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1268         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1269         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1270     // icu ja.txt does not have info for this time zone
1271         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3 (\u30D6\u30A8\u30CE\u30B9\u30A2\u30A4\u30EC\u30B9)", "America/Buenos_Aires" },
1272         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\u30a2\u30eb\u30bc\u30f3\u30c1\u30f3\u6642\u9593", "America/Buenos_Aires" },
1273
1274         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
1275         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
1276         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-05:00", "-5:00" },
1277         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-05:00", "-5:00" },
1278         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
1279         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
1280         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-04:00", "-4:00" },
1281         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-04:00", "-4:00" },
1282         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "v", "\u30ad\u30e5\u30fc\u30d0\u6642\u9593", "America/Havana" },
1283         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\u30ad\u30e5\u30fc\u30d0\u6642\u9593", "America/Havana" },
1284
1285         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1286         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
1287         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
1288         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
1289         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1290         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
1291         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
1292         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
1293     // icu ja.txt does not have info for this time zone
1294         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\u30aa\u30fc\u30b9\u30c8\u30e9\u30ea\u30a2 (\u30b7\u30c9\u30cb\u30fc)", "Australia/Sydney" },
1295         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\u30aa\u30fc\u30b9\u30c8\u30e9\u30ea\u30a2 (\u30b7\u30c9\u30cb\u30fc)", "Australia/Sydney" },
1296
1297         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1298         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
1299         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
1300         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
1301         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1302         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
1303         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
1304         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
1305         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\u30aa\u30fc\u30b9\u30c8\u30e9\u30ea\u30a2 (\u30b7\u30c9\u30cb\u30fc)", "Australia/Sydney" },
1306         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\u30aa\u30fc\u30b9\u30c8\u30e9\u30ea\u30a2 (\u30b7\u30c9\u30cb\u30fc)", "Australia/Sydney" },
1307
1308         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
1309         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+00:00", "+0:00" },
1310         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT+00:00", "+0:00" },
1311         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "V", "GMT", "+0:00" },
1312         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\u30B0\u30EA\u30CB\u30C3\u30B8\u6A19\u6E96\u6642", "+0:00" },
1313         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
1314         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
1315         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+01:00", "+1:00" },
1316         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "V", "GMT+01:00", "+1:00" },
1317         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" },
1318         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "v", "\u30a4\u30ae\u30ea\u30b9\u6642\u9593", "Europe/London" },
1319         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\u30a4\u30ae\u30ea\u30b9\u6642\u9593", "Europe/London" },
1320         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\u30a4\u30ae\u30ea\u30b9\u6642\u9593", "Europe/London" },
1321
1322         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1323         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1324         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1325         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1326         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1327         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1328         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1329         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1330         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-03:00", "-3:00" },
1331         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
1332
1333         // JB#5150
1334         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
1335         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
1336         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+05:30", "+5:30" },
1337         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
1338         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
1339         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
1340         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+05:30", "+05:30" },
1341         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
1342         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\u30A4\u30F3\u30C9\u6642\u9593", "Asia/Calcutta" },
1343         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\u30A4\u30F3\u30C9\u6642\u9593", "Asia/Calcutta" },
1344
1345     // ==========
1346
1347         { "si", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
1348         { "si", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
1349         { "si", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-08:00", "-8:00" },
1350         { "si", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "GMT-08:00", "-8:00" },
1351         { "si", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
1352         { "si", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
1353         { "si", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-07:00", "-7:00" },
1354         { "si", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "GMT-07:00", "-7:00" },
1355         { "si", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "US (Los Angeles)", "America/Los_Angeles" },
1356         { "si", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "US (Los Angeles)", "America/Los_Angeles" },
1357
1358         { "si", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1359         { "si", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1360         { "si", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1361         { "si", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1362         { "si", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1363         { "si", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1364         { "si", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1365         { "si", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1366         { "si", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "AR (Buenos Aires)", "America/Buenos_Aires" },
1367         { "si", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "AR (Buenos Aires)", "America/Buenos_Aires" },
1368
1369         { "si", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1370         { "si", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1371         { "si", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1372         { "si", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1373         { "si", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1374         { "si", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1375         { "si", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1376         { "si", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1377         { "si", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "AR (Buenos Aires)", "America/Buenos_Aires" },
1378         { "si", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "AR (Buenos Aires)", "America/Buenos_Aires" },
1379
1380         { "si", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
1381         { "si", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
1382         { "si", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-05:00", "-5:00" },
1383         { "si", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-05:00", "-5:00" },
1384         { "si", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
1385         { "si", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
1386         { "si", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-04:00", "-4:00" },
1387         { "si", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-04:00", "-4:00" },
1388         { "si", "America/Havana", "2004-07-15T00:00:00Z", "v", "CU", "America/Havana" },
1389         { "si", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "CU", "America/Havana" },
1390
1391         { "si", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1392         { "si", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
1393         { "si", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
1394         { "si", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
1395         { "si", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1396         { "si", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
1397         { "si", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
1398         { "si", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
1399         { "si", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "AU (Sydney)", "Australia/Sydney" },
1400         { "si", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "AU (Sydney)", "Australia/Sydney" },
1401
1402         { "si", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
1403         { "si", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
1404         { "si", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11:00", "+11:00" },
1405         { "si", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
1406         { "si", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
1407         { "si", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
1408         { "si", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10:00", "+10:00" },
1409         { "si", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
1410         { "si", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "AU (Sydney)", "Australia/Sydney" },
1411         { "si", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "AU (Sydney)", "Australia/Sydney" },
1412
1413         { "si", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
1414         { "si", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+00:00", "+0:00" },
1415         { "si", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT+00:00", "+0:00" },
1416         { "si", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "GMT+00:00", "+0:00" },
1417         { "si", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
1418         { "si", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
1419         { "si", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+01:00", "+1:00" },
1420         { "si", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" },
1421         { "si", "Europe/London", "2004-07-15T00:00:00Z", "v", "GB", "Europe/London" },
1422         { "si", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "GB", "Europe/London" },
1423
1424         { "si", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
1425         { "si", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1426         { "si", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1427         { "si", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1428         { "si", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
1429         { "si", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
1430         { "si", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-03:00", "-3:00" },
1431         { "si", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
1432         { "si", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-03:00", "-3:00" },
1433         { "si", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
1434
1435         // JB#5150
1436         { "si", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
1437         { "si", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
1438         { "si", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+05:30", "+5:30" },
1439         { "si", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
1440         { "si", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
1441         { "si", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
1442         { "si", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+05:30", "+05:30" },
1443         { "si", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
1444         { "si", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IN", "Asia/Calcutta" },
1445         { "si", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "IN", "Asia/Calcutta" },
1446         
1447     };
1448
1449     /**
1450      * Verify that strings which contain incomplete specifications are parsed
1451      * correctly.  In some instances, this means not being parsed at all, and
1452      * returning an appropriate error.
1453      */
1454     public void TestPartialParse994() {
1455     
1456         SimpleDateFormat f = new SimpleDateFormat();
1457         Calendar cal = Calendar.getInstance();
1458         cal.clear();
1459         cal.set(1997, 1 - 1, 17, 10, 11, 42);
1460         Date date = null;
1461         tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", cal.getTime());
1462         tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", date);
1463         tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", date);
1464         tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", date);
1465         tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", date);
1466     }
1467     
1468     // internal test subroutine, used by TestPartialParse994
1469     public void tryPat994(SimpleDateFormat format, String pat, String str, Date expected) {
1470         Date Null = null;
1471         logln("Pattern \"" + pat + "\"   String \"" + str + "\"");
1472         try {
1473             format.applyPattern(pat);
1474             Date date = format.parse(str);    
1475             String f = ((DateFormat) format).format(date);
1476             logln(" parse(" + str + ") -> " + date);
1477             logln(" format -> " + f);
1478             if (expected.equals(Null) || !date.equals(expected))
1479                 errln("FAIL: Expected null"); //" + expected);
1480             if (!f.equals(str))
1481                 errln("FAIL: Expected " + str);
1482         } catch (ParseException e) {
1483             logln("ParseException: " + e.getMessage());
1484             if (!(expected ==Null))
1485                 errln("FAIL: Expected " + expected);
1486         } catch (Exception e) {
1487             errln("*** Exception:");
1488             e.printStackTrace();
1489         }
1490     }
1491     
1492     /**
1493      * Verify the behavior of patterns in which digits for different fields run together
1494      * without intervening separators.
1495      */
1496     public void TestRunTogetherPattern985() {
1497         String format = "yyyyMMddHHmmssSSS";
1498         String now, then;
1499         //UBool flag;
1500         SimpleDateFormat formatter = new SimpleDateFormat(format);
1501         Date date1 = new Date();
1502         now = ((DateFormat) formatter).format(date1);
1503         logln(now);
1504         ParsePosition pos = new ParsePosition(0);
1505         Date date2 = formatter.parse(now, pos);
1506         if (date2 == null)
1507             then = "Parse stopped at " + pos.getIndex();
1508         else
1509             then = ((DateFormat) formatter).format(date2);
1510         logln(then);
1511         if (date2 == null || !date2.equals(date1))
1512             errln("FAIL");
1513     }
1514
1515     /**
1516      * Verify the behavior of patterns in which digits for different fields run together
1517      * without intervening separators.
1518      */
1519     public void TestRunTogetherPattern917() {
1520         SimpleDateFormat fmt;
1521         String myDate;
1522         fmt = new SimpleDateFormat("yyyy/MM/dd");
1523         myDate = "1997/02/03";
1524         Calendar cal = Calendar.getInstance();
1525         cal.clear();
1526         cal.set(1997, 2 - 1, 3);
1527         _testIt917(fmt, myDate, cal.getTime());
1528         fmt = new SimpleDateFormat("yyyyMMdd");
1529         myDate = "19970304";
1530         cal.clear();
1531         cal.set(1997, 3 - 1, 4);
1532         _testIt917(fmt, myDate, cal.getTime());
1533     
1534     }
1535     
1536     // internal test subroutine, used by TestRunTogetherPattern917
1537     public void _testIt917(SimpleDateFormat fmt, String str, Date expected) {
1538         logln("pattern=" + fmt.toPattern() + "   string=" + str);
1539         Date o = new Date();
1540         o = (Date) ((DateFormat) fmt).parseObject(str, new ParsePosition(0));
1541         logln("Parsed object: " + o);
1542         if (o == null || !o.equals(expected))
1543             errln("FAIL: Expected " + expected);
1544         String formatted = o==null? "null" : ((DateFormat) fmt).format(o);
1545         logln( "Formatted string: " + formatted);
1546         if (!formatted.equals(str))
1547             errln( "FAIL: Expected " + str);
1548     }
1549     
1550     /**
1551      * Verify the handling of Czech June and July, which have the unique attribute that
1552      * one is a proper prefix substring of the other.
1553      */
1554     public void TestCzechMonths459() {
1555         DateFormat fmt = DateFormat.getDateInstance(DateFormat.FULL, new Locale("cs", "", "")); 
1556         logln("Pattern " + ((SimpleDateFormat) fmt).toPattern());
1557         Calendar cal = Calendar.getInstance();
1558         cal.clear();
1559         cal.set(1997, Calendar.JUNE, 15);
1560         Date june = cal.getTime();
1561         cal.clear();
1562         cal.set(1997, Calendar.JULY, 15);
1563         Date july = cal.getTime();
1564         String juneStr = fmt.format(june);
1565         String julyStr = fmt.format(july);
1566         try {
1567             logln("format(June 15 1997) = " + juneStr);
1568             Date d = fmt.parse(juneStr);
1569             String s = fmt.format(d);
1570             int month, yr, day;
1571             cal.setTime(d);
1572             yr = cal.get(Calendar.YEAR);
1573             month = cal.get(Calendar.MONTH);
1574             day = cal.get(Calendar.DAY_OF_MONTH);
1575             logln("  . parse . " + s + " (month = " + month + ")");
1576             if (month != Calendar.JUNE)
1577                 errln("FAIL: Month should be June");
1578             if (yr != 1997)
1579                 errln("FAIL: Year should be 1997");
1580             if (day != 15)
1581                 errln("FAIL: day should be 15");
1582             logln("format(July 15 1997) = " + julyStr);
1583             d = fmt.parse(julyStr);
1584             s = fmt.format(d);
1585             cal.setTime(d);
1586             yr = cal.get(Calendar.YEAR) - 1900;
1587             month = cal.get(Calendar.MONTH);
1588             day = cal.get(Calendar.DAY_OF_WEEK);
1589             logln("  . parse . " + s + " (month = " + month + ")");
1590             if (month != Calendar.JULY)
1591                 errln("FAIL: Month should be July");
1592         } catch (ParseException e) {
1593             errln(e.getMessage());
1594         }
1595     }
1596     
1597     /**
1598      * Test the handling of 'D' in patterns.
1599      */
1600     public void TestLetterDPattern212() {
1601         String dateString = "1995-040.05:01:29";
1602         String bigD = "yyyy-DDD.hh:mm:ss";
1603         String littleD = "yyyy-ddd.hh:mm:ss";
1604         Calendar cal = Calendar.getInstance();
1605         cal.clear();
1606         cal.set(1995, 0, 1, 5, 1, 29);
1607         Date expLittleD = cal.getTime();
1608         Date expBigD = new Date((long) (expLittleD.getTime() + 39 * 24 * 3600000.0));
1609         expLittleD = expBigD; // Expect the same, with default lenient parsing
1610         logln("dateString= " + dateString);
1611         SimpleDateFormat formatter = new SimpleDateFormat(bigD);
1612         ParsePosition pos = new ParsePosition(0);
1613         Date myDate = formatter.parse(dateString, pos);
1614         logln("Using " + bigD + " . " + myDate);
1615         if (!myDate.equals(expBigD))
1616             errln("FAIL: Expected " + expBigD);
1617         formatter = new SimpleDateFormat(littleD);
1618         pos = new ParsePosition(0);
1619         myDate = formatter.parse(dateString, pos);
1620         logln("Using " + littleD + " . " + myDate);
1621         if (!myDate.equals(expLittleD))
1622             errln("FAIL: Expected " + expLittleD);
1623     }
1624     
1625     /**
1626      * Test the day of year pattern.
1627      */
1628     public void TestDayOfYearPattern195() {
1629         Calendar cal = Calendar.getInstance();
1630         Date today = cal.getTime();
1631         int year,month,day; 
1632         year = cal.get(Calendar.YEAR);
1633         month = cal.get(Calendar.MONTH);
1634         day = cal.get(Calendar.DAY_OF_MONTH);
1635         cal.clear();
1636         cal.set(year, month, day);
1637         Date expected = cal.getTime();
1638         logln("Test Date: " + today);
1639         SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance();
1640         tryPattern(sdf, today, null, expected);
1641         tryPattern(sdf, today, "G yyyy DDD", expected);
1642     }
1643     
1644     // interl test subroutine, used by TestDayOfYearPattern195
1645     public void tryPattern(SimpleDateFormat sdf, Date d, String pattern, Date expected) {
1646         if (pattern != null)
1647             sdf.applyPattern(pattern);
1648         logln("pattern: " + sdf.toPattern());
1649         String formatResult = ((DateFormat) sdf).format(d);
1650         logln(" format -> " + formatResult);
1651         try {
1652             Date d2 = sdf.parse(formatResult);
1653             logln(" parse(" + formatResult + ") -> " + d2);
1654             if (!d2.equals(expected))
1655                 errln("FAIL: Expected " + expected);
1656             String format2 = ((DateFormat) sdf).format(d2);
1657             logln(" format -> " + format2);
1658             if (!formatResult.equals(format2))
1659                 errln("FAIL: Round trip drift");
1660         } catch (Exception e) {
1661             errln(e.getMessage());
1662         }
1663     }
1664     
1665     /**
1666      * Test the handling of single quotes in patterns.
1667      */
1668     public void TestQuotePattern161() {
1669         SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy 'at' hh:mm:ss a zzz", Locale.US); 
1670         Calendar cal = Calendar.getInstance();
1671         cal.clear();
1672         cal.set(1997, Calendar.AUGUST, 13, 10, 42, 28);
1673         Date currentTime_1 = cal.getTime();
1674         String dateString = ((DateFormat) formatter).format(currentTime_1);
1675         String exp = "08/13/1997 at 10:42:28 AM ";
1676         logln("format(" + currentTime_1 + ") = " + dateString);
1677         if (!dateString.substring(0, exp.length()).equals(exp))
1678             errln("FAIL: Expected " + exp);
1679     
1680     }
1681         
1682     /**
1683      * Verify the correct behavior when handling invalid input strings.
1684      */
1685     public void TestBadInput135() {
1686         int looks[] = {DateFormat.SHORT, DateFormat.MEDIUM, DateFormat.LONG, DateFormat.FULL}; 
1687         int looks_length = looks.length;
1688         final String[] strings = {"Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"}; 
1689         int strings_length = strings.length;
1690         DateFormat full = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US); 
1691         String expected = "March 1, 2000 1:23:45 AM ";
1692         for (int i = 0; i < strings_length; ++i) {
1693             final String text = strings[i];
1694             for (int j = 0; j < looks_length; ++j) {
1695                 int dateLook = looks[j];
1696                 for (int k = 0; k < looks_length; ++k) {
1697                     int timeLook = looks[k];
1698                     DateFormat df = DateFormat.getDateTimeInstance(dateLook, timeLook, Locale.US); 
1699                     String prefix = text + ", " + dateLook + "/" + timeLook + ": "; 
1700                     try {
1701                         Date when = df.parse(text);
1702                         if (when == null) {
1703                             errln(prefix + "SHOULD NOT HAPPEN: parse returned null.");
1704                             continue;
1705                         }  
1706                         if (when != null) {
1707                             String format;
1708                             format = full.format(when);
1709                             logln(prefix + "OK: " + format);
1710                             if (!format.substring(0, expected.length()).equals(expected))
1711                                 errln("FAIL: Expected " + expected);
1712                         }
1713                     } catch(java.text.ParseException e) {
1714                         logln(e.getMessage());
1715                     }
1716                 }
1717             }
1718         }
1719     }
1720     
1721     /**
1722      * Verify the correct behavior when parsing an array of inputs against an
1723      * array of patterns, with known results.  The results are encoded after
1724      * the input strings in each row.
1725      */
1726     public void TestBadInput135a() {
1727     
1728         SimpleDateFormat dateParse = new SimpleDateFormat("", Locale.US);
1729         final String ss;
1730         Date date;
1731         String[] parseFormats ={"MMMM d, yyyy", "MMMM d yyyy", "M/d/yy",
1732                                 "d MMMM, yyyy", "d MMMM yyyy",  "d MMMM",
1733                                 "MMMM d", "yyyy", "h:mm a MMMM d, yyyy" };
1734         String[] inputStrings = {
1735             "bogus string", null, null, null, null, null, null, null, null, null,
1736                 "April 1, 1997", "April 1, 1997", null, null, null, null, null, "April 1", null, null,
1737                 "Jan 1, 1970", "January 1, 1970", null, null, null, null, null, "January 1", null, null,
1738                 "Jan 1 2037", null, "January 1 2037", null, null, null, null, "January 1", null, null,
1739                 "1/1/70", null, null, "1/1/70", null, null, null, null, "0001", null,
1740                 "5 May 1997", null, null, null, null, "5 May 1997", "5 May", null, "0005", null,
1741                 "16 May", null, null, null, null, null, "16 May", null, "0016", null,
1742                 "April 30", null, null, null, null, null, null, "April 30", null, null,
1743                 "1998", null, null, null, null, null, null, null, "1998", null,
1744                 "1", null, null, null, null, null, null, null, "0001", null,
1745                 "3:00 pm Jan 1, 1997", null, null, null, null, null, null, null, "0003", "3:00 PM January 1, 1997",
1746                 };
1747         final int PF_LENGTH = parseFormats.length;
1748         final int INPUT_LENGTH = inputStrings.length;
1749     
1750         dateParse.applyPattern("d MMMM, yyyy");
1751         dateParse.setTimeZone(TimeZone.getDefault());
1752         ss = "not parseable";
1753         //    String thePat;
1754         logln("Trying to parse \"" + ss + "\" with " + dateParse.toPattern());
1755         try {
1756             date = dateParse.parse(ss);
1757         } catch (Exception ex) {
1758             logln("FAIL:" + ex);
1759         }
1760         for (int i = 0; i < INPUT_LENGTH; i += (PF_LENGTH + 1)) {
1761             ParsePosition parsePosition = new ParsePosition(0);
1762             String s = inputStrings[i];
1763             for (int index = 0; index < PF_LENGTH; ++index) {
1764                 final String expected = inputStrings[i + 1 + index];
1765                 dateParse.applyPattern(parseFormats[index]);
1766                 dateParse.setTimeZone(TimeZone.getDefault());
1767                 try {
1768                     parsePosition.setIndex(0);
1769                     date = dateParse.parse(s, parsePosition);
1770                     if (parsePosition.getIndex() != 0) {
1771                         String s1, s2;
1772                         s1 = s.substring(0, parsePosition.getIndex());
1773                         s2 = s.substring(parsePosition.getIndex(), s.length());
1774                         if (date == null) {
1775                             errln("ERROR: null result fmt=\"" + parseFormats[index]
1776                                     + "\" pos=" + parsePosition.getIndex()
1777                                     + " " + s1 + "|" + s2);
1778                         } else {
1779                             String result = ((DateFormat) dateParse).format(date);
1780                             logln("Parsed \"" + s + "\" using \"" + dateParse.toPattern() + "\" to: " + result);
1781                             if (expected == null)
1782                                 errln("FAIL: Expected parse failure");
1783                             else
1784                                 if (!result.equals(expected))
1785                                     errln("FAIL: Expected " + expected);
1786                         }
1787                     } else
1788                         if (expected != null) {
1789                             errln("FAIL: Expected " + expected + " from \"" + s
1790                                     + "\" with \"" + dateParse.toPattern()+ "\"");
1791                         }
1792                 } catch (Exception ex) {
1793                     logln("FAIL:" + ex);
1794                 }
1795             }
1796         }
1797     
1798     }
1799     
1800     /**
1801      * Test the parsing of two-digit years.
1802      */
1803     public void TestTwoDigitYear() {
1804         DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
1805         Calendar cal = Calendar.getInstance();
1806         cal.clear();
1807         cal.set(117 + 1900, Calendar.JUNE, 5);
1808         parse2DigitYear(fmt, "6/5/17", cal.getTime());
1809         cal.clear();
1810         cal.set(34 + 1900, Calendar.JUNE, 4);
1811         parse2DigitYear(fmt, "6/4/34", cal.getTime());
1812     }
1813     
1814     // internal test subroutine, used by TestTwoDigitYear
1815     public void parse2DigitYear(DateFormat fmt, String str, Date expected) {
1816         try {
1817             Date d = fmt.parse(str);
1818             logln("Parsing \""+ str+ "\" with "+ ((SimpleDateFormat) fmt).toPattern()
1819                     + "  => "+ d); 
1820             if (!d.equals(expected))
1821                 errln( "FAIL: Expected " + expected);
1822         } catch (ParseException e) {
1823             errln(e.getMessage());
1824         }
1825     }
1826     
1827     /**
1828      * Test the formatting of time zones.
1829      */
1830     public void TestDateFormatZone061() {
1831         Date date;
1832         DateFormat formatter;
1833         date = new Date(859248000000l);
1834         logln("Date 1997/3/25 00:00 GMT: " + date);
1835         formatter = new SimpleDateFormat("dd-MMM-yyyyy HH:mm", Locale.UK);
1836         formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
1837         String temp = formatter.format(date);
1838         logln("Formatted in GMT to: " + temp);
1839         try {
1840             Date tempDate = formatter.parse(temp);
1841             logln("Parsed to: " + tempDate);
1842             if (!tempDate.equals(date))
1843                 errln("FAIL: Expected " + date + " Got: " + tempDate);
1844         } catch (Throwable t) {
1845             System.out.println(t);
1846         }
1847     
1848     }
1849     
1850     /**
1851      * Test the formatting of time zones.
1852      */
1853     public void TestDateFormatZone146() {
1854         TimeZone saveDefault = TimeZone.getDefault();
1855     
1856         //try {
1857         TimeZone thedefault = TimeZone.getTimeZone("GMT");
1858         TimeZone.setDefault(thedefault);
1859         // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
1860     
1861         // check to be sure... its GMT all right
1862         TimeZone testdefault = TimeZone.getDefault();
1863         String testtimezone = testdefault.getID();
1864         if (testtimezone.equals("GMT"))
1865             logln("Test timezone = " + testtimezone);
1866         else
1867             errln("Test timezone should be GMT, not " + testtimezone);
1868     
1869         // now try to use the default GMT time zone
1870         GregorianCalendar greenwichcalendar = new GregorianCalendar(1997, 3, 4, 23, 0);
1871         //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
1872         //greenwichcalendar.set(1997, 3, 4, 23, 0);
1873         // try anything to set hour to 23:00 !!!
1874         greenwichcalendar.set(Calendar.HOUR_OF_DAY, 23);
1875         // get time
1876         Date greenwichdate = greenwichcalendar.getTime();
1877         // format every way
1878         String DATA[] = {
1879                 "simple format:  ", "04/04/97 23:00 GMT+00:00", 
1880                 "MM/dd/yy HH:mm zzz", "full format:    ", 
1881                 "Friday, April 4, 1997 11:00:00 o'clock PM GMT+00:00", 
1882                 "EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a zzz", 
1883                 "long format:    ", "April 4, 1997 11:00:00 PM GMT+00:00", 
1884                 "MMMM d, yyyy h:mm:ss a z", "default format: ", 
1885                 "04-Apr-97 11:00:00 PM", "dd-MMM-yy h:mm:ss a", 
1886                 "short format:   ", "4/4/97 11:00 PM", 
1887                 "M/d/yy h:mm a"}; 
1888         int DATA_length = DATA.length;
1889     
1890         for (int i = 0; i < DATA_length; i += 3) {
1891             DateFormat fmt = new SimpleDateFormat(DATA[i + 2], Locale.ENGLISH);
1892             fmt.setCalendar(greenwichcalendar);
1893             String result = fmt.format(greenwichdate);
1894             logln(DATA[i] + result);
1895             if (!result.equals(DATA[i + 1]))
1896                 errln("FAIL: Expected " + DATA[i + 1] + ", got " + result);
1897         }
1898         //}
1899         //finally {
1900         TimeZone.setDefault(saveDefault);
1901         //}
1902     
1903     }
1904     
1905     /**
1906      * Test the formatting of dates in different locales.
1907      */
1908     public void TestLocaleDateFormat() {
1909     
1910         Date testDate = new Date(874306800000l); //Mon Sep 15 00:00:00 PDT 1997
1911         DateFormat dfFrench = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.FRENCH);
1912         DateFormat dfUS = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.US);
1913         //Set TimeZone = PDT
1914         TimeZone tz = TimeZone.getTimeZone("PST");
1915         dfFrench.setTimeZone(tz);
1916         dfUS.setTimeZone(tz);
1917         String expectedFRENCH_JDK12 = "lundi 15 septembre 1997 00:00:00 heure avanc\u00E9e du Pacifique";
1918         //String expectedFRENCH = "lundi 15 septembre 1997 00 h 00 PDT";
1919         String expectedUS = "Monday, September 15, 1997 12:00:00 AM Pacific Daylight Time";
1920         logln("Date set to : " + testDate);
1921         String out = dfFrench.format(testDate);
1922         logln("Date Formated with French Locale " + out);
1923         //fix the jdk resources differences between jdk 1.2 and jdk 1.3
1924         /* our own data only has GMT-xxxx information here
1925         String javaVersion = System.getProperty("java.version");
1926         if (javaVersion.startsWith("1.2")) {
1927             if (!out.equals(expectedFRENCH_JDK12))
1928                 errln("FAIL: Expected " + expectedFRENCH_JDK12+" Got "+out);
1929         } else {
1930             if (!out.equals(expectedFRENCH))
1931                 errln("FAIL: Expected " + expectedFRENCH);
1932         }
1933         */
1934         if (!out.equals(expectedFRENCH_JDK12))
1935             errln("FAIL: Expected " + expectedFRENCH_JDK12+" Got "+out);
1936         out = dfUS.format(testDate);
1937         logln("Date Formated with US Locale " + out);
1938         if (!out.equals(expectedUS))
1939             errln("FAIL: Expected " + expectedUS+" Got "+out);
1940     }
1941
1942     /**
1943      * Test the formatting of dates with the 'NONE' keyword.
1944      */
1945     public void TestDateFormatNone() {
1946     
1947         Date testDate = new Date(874306800000l); //Mon Sep 15 00:00:00 PDT 1997
1948         DateFormat dfFrench = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.NONE, Locale.FRENCH);
1949         //Set TimeZone = PDT
1950         TimeZone tz = TimeZone.getTimeZone("PST");
1951         dfFrench.setTimeZone(tz);
1952         String expectedFRENCH_JDK12 = "lundi 15 septembre 1997";
1953         //String expectedFRENCH = "lundi 15 septembre 1997 00 h 00 PDT";
1954         logln("Date set to : " + testDate);
1955         String out = dfFrench.format(testDate);
1956         logln("Date Formated with French Locale " + out);
1957         if (!out.equals(expectedFRENCH_JDK12))
1958             errln("FAIL: Expected " + expectedFRENCH_JDK12+" Got "+out);
1959     }
1960
1961
1962     /**
1963      * Test DateFormat(Calendar) API
1964      */
1965     public void TestDateFormatCalendar() {
1966         DateFormat date=null, time=null, full=null;
1967         Calendar cal=null;
1968         ParsePosition pos = new ParsePosition(0);
1969         String str;
1970         Date when;
1971
1972         /* Create a formatter for date fields. */
1973         date = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
1974         if (date == null) {
1975             errln("FAIL: getDateInstance failed");
1976             return;
1977         }
1978
1979         /* Create a formatter for time fields. */
1980         time = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US);
1981         if (time == null) {
1982             errln("FAIL: getTimeInstance failed");
1983             return;
1984         }
1985
1986         /* Create a full format for output */
1987         full = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL,
1988                                               Locale.US);
1989         if (full == null) {
1990             errln("FAIL: getInstance failed");
1991             return;
1992         }
1993
1994         /* Create a calendar */
1995         cal = Calendar.getInstance(Locale.US);
1996         if (cal == null) {
1997             errln("FAIL: Calendar.getInstance failed");
1998             return;
1999         }
2000
2001         /* Parse the date */
2002         cal.clear();
2003         str = "4/5/2001";
2004         pos.setIndex(0);
2005         date.parse(str, cal, pos);
2006         if (pos.getIndex() != str.length()) {
2007             errln("FAIL: DateFormat.parse(4/5/2001) failed at " +
2008                   pos.getIndex());
2009             return;
2010         }
2011
2012         /* Parse the time */
2013         str = "5:45 PM";
2014         pos.setIndex(0);
2015         time.parse(str, cal, pos);
2016         if (pos.getIndex() != str.length()) {
2017             errln("FAIL: DateFormat.parse(17:45) failed at " +
2018                   pos.getIndex());
2019             return;
2020         }
2021     
2022         /* Check result */
2023         when = cal.getTime();
2024         str = full.format(when);
2025         // Thursday, April 5, 2001 5:45:00 PM PDT 986517900000
2026         if (when.getTime() == 986517900000.0) {
2027             logln("Ok: Parsed result: " + str);
2028         } else {
2029             errln("FAIL: Parsed result: " + str + ", exp 4/5/2001 5:45 PM");
2030         }
2031     }
2032
2033     /**
2034      * Test DateFormat's parsing of space characters.  See jitterbug 1916.
2035      */
2036     public void TestSpaceParsing() {
2037
2038         String DATA[] = {
2039             "yyyy MM dd",
2040
2041             // pattern, input, expected output (in quotes)
2042             "MMMM d yy", " 04 05 06",  null, // MMMM wants Apr/April
2043             null,        "04 05 06",   null,
2044             "MM d yy",   " 04 05 06",  "2006 04 05",
2045             null,        "04 05 06",   "2006 04 05",
2046             "MMMM d yy", " Apr 05 06", "2006 04 05",
2047             null,        "Apr 05 06",  "2006 04 05",
2048         };
2049
2050         expectParse(DATA, new Locale("en", "", ""));
2051     }
2052
2053     /**
2054      * Test handling of "HHmmss" pattern.
2055      */
2056     public void TestExactCountFormat() {
2057         String DATA[] = {
2058             "yyyy MM dd HH:mm:ss",
2059
2060             // pattern, input, expected parse or null if expect parse failure
2061             "HHmmss", "123456", "1970 01 01 12:34:56",
2062             null,     "12345",  "1970 01 01 01:23:45",
2063             null,     "1234",   null,
2064             null,     "00-05",  null,
2065             null,     "12-34",  null,
2066             null,     "00+05",  null,
2067             "ahhmm",  "PM730",  "1970 01 01 19:30:00",
2068         };
2069
2070         expectParse(DATA, new Locale("en", "", ""));
2071     }
2072
2073     /**
2074      * Test handling of white space.
2075      */
2076     public void TestWhiteSpaceParsing() {
2077         String DATA[] = {
2078             "yyyy MM dd",
2079
2080             // pattern, input, expected parse or null if expect parse failure
2081
2082             // Pattern space run should parse input text space run
2083             "MM   d yy",   " 04 01 03",    "2003 04 01",
2084             null,          " 04  01   03 ", "2003 04 01",
2085         };
2086
2087         expectParse(DATA, new Locale("en", "", ""));
2088     }
2089
2090     public void TestInvalidPattern() {
2091         Exception e = null;
2092         SimpleDateFormat f = null;
2093         String out = null;
2094         try {
2095             f = new SimpleDateFormat("Yesterday");
2096             out = f.format(new Date(0));
2097         } catch (IllegalArgumentException e1) {
2098             e = e1;
2099         }
2100         if (e != null) {
2101             logln("Ok: Received " + e.getMessage());
2102         } else {
2103             errln("FAIL: Expected exception, got " + f.toPattern() +
2104                   "; " + out);
2105         }
2106     }
2107
2108     public void TestGreekMay() {
2109         Date date = new Date(-9896080848000L);
2110         SimpleDateFormat fmt = new SimpleDateFormat("EEEE, dd MMMM yyyy h:mm:ss a",
2111                              new Locale("el", "", ""));
2112         String str = fmt.format(date);
2113         ParsePosition pos = new ParsePosition(0);
2114         Date d2 = fmt.parse(str, pos);
2115         if (!date.equals(d2)) {
2116             errln("FAIL: unable to parse strings where case-folding changes length");
2117         }
2118     }
2119
2120     public void testErrorChecking() {
2121         try {
2122             DateFormat.getDateTimeInstance(-1, -1, Locale.US);
2123             errln("Expected exception for getDateTimeInstance(-1, -1, Locale)");
2124         }
2125         catch(IllegalArgumentException e) {
2126             logln("one ok");
2127         }
2128         catch(Exception e) {
2129             warnln("Expected IllegalArgumentException, got: " + e);
2130         }
2131         
2132         try {
2133             DateFormat df = new SimpleDateFormat("aabbccc");
2134             df.format(new Date());
2135             errln("Expected exception for format with bad pattern");
2136         }
2137         catch(IllegalArgumentException ex) {
2138             logln("two ok");
2139         }
2140         catch(Exception e) {
2141             warnln("Expected IllegalArgumentException, got: " + e);
2142         }
2143         
2144         {
2145             SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yy"); // opposite of text
2146             fmt.set2DigitYearStart(getDate(2003, Calendar.DECEMBER, 25));
2147             String text = "12/25/03";
2148             Calendar xcal = new GregorianCalendar();
2149             xcal.setLenient(false);
2150             ParsePosition pp = new ParsePosition(0);
2151             fmt.parse(text, xcal, pp); // should get parse error on second field, not lenient
2152             if (pp.getErrorIndex() == -1) {
2153                 errln("Expected parse error");
2154             } else {
2155                 logln("three ok");
2156             }
2157         }
2158     }
2159
2160     public void TestChineseDateFormatLocalizedPatternChars() {
2161         // jb 4904
2162         // make sure we can display localized versions of the chars used in the default
2163         // chinese date format patterns
2164         Calendar chineseCalendar = new ChineseCalendar();
2165         chineseCalendar.setTimeInMillis((new Date()).getTime());
2166         SimpleDateFormat longChineseDateFormat = 
2167             (SimpleDateFormat)chineseCalendar.getDateTimeFormat(DateFormat.LONG, DateFormat.LONG, Locale.CHINA );
2168         DateFormatSymbols dfs = new ChineseDateFormatSymbols( chineseCalendar, Locale.CHINA );
2169         longChineseDateFormat.setDateFormatSymbols( dfs );
2170         // This next line throws the exception
2171         try {
2172             longChineseDateFormat.toLocalizedPattern();
2173         }
2174         catch (Exception e) {
2175             errln("could not localized pattern: " + e.getMessage());
2176         }
2177     }
2178
2179     public void TestCoverage() {
2180         Date now = new Date();
2181         Calendar cal = new GregorianCalendar();
2182         DateFormat f = DateFormat.getTimeInstance();
2183         logln("time: " + f.format(now));
2184
2185         int hash = f.hashCode(); // sigh, everyone overrides this
2186         
2187         f = DateFormat.getInstance(cal);
2188         if(hash == f.hashCode()){
2189             errln("FAIL: hashCode equal for inequal objects");
2190         }
2191         logln("time again: " + f.format(now));
2192
2193         f = DateFormat.getTimeInstance(cal, DateFormat.FULL);
2194         logln("time yet again: " + f.format(now));
2195
2196         f = DateFormat.getDateInstance();
2197         logln("time yet again: " + f.format(now));
2198
2199         ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,"de_DE");
2200         DateFormatSymbols sym = new DateFormatSymbols(rb, Locale.GERMANY);
2201         DateFormatSymbols sym2 = (DateFormatSymbols)sym.clone();
2202         if (sym.hashCode() != sym2.hashCode()) {
2203             errln("fail, date format symbols hashcode not equal");
2204         }
2205         if (!sym.equals(sym2)) {
2206             errln("fail, date format symbols not equal");
2207         }
2208         
2209         Locale foo = new Locale("fu", "FU", "BAR");
2210         rb = null;
2211         sym = new DateFormatSymbols(GregorianCalendar.class, foo);
2212         sym.equals(null);
2213         
2214         sym = new ChineseDateFormatSymbols();
2215         sym = new ChineseDateFormatSymbols(new ChineseCalendar(), foo);
2216         // cover new ChineseDateFormatSymbols(Calendar, ULocale)
2217         ChineseCalendar ccal = new ChineseCalendar();
2218         sym = new ChineseDateFormatSymbols(ccal, ULocale.CHINA); //gclsh1 add
2219         
2220         StringBuffer buf = new StringBuffer();
2221         FieldPosition pos = new FieldPosition(0);
2222         
2223         f.format((Object)cal, buf, pos);
2224         f.format((Object)now, buf, pos);
2225         f.format((Object)new Long(now.getTime()), buf, pos);
2226         try {
2227             f.format((Object)"Howdy", buf, pos);
2228         }
2229         catch (Exception e) {
2230         }
2231
2232         NumberFormat nf = f.getNumberFormat();
2233         f.setNumberFormat(nf);
2234         
2235         boolean lenient = f.isLenient();
2236         f.setLenient(lenient);
2237         
2238         ULocale uloc = f.getLocale(ULocale.ACTUAL_LOCALE);
2239         
2240         DateFormat sdfmt = new SimpleDateFormat();
2241         
2242         if (f.hashCode() != f.hashCode()) {
2243             errln("hashCode is not stable");
2244         }
2245         if (!f.equals(f)) {
2246             errln("f != f");
2247         }
2248         if (f.equals(null)) {
2249             errln("f should not equal null");
2250         }
2251         if (f.equals(sdfmt)) {
2252             errln("A time instance shouldn't equal a default date format");
2253         }
2254         
2255         Date d;
2256         {
2257             ChineseDateFormat fmt = new ChineseDateFormat("yymm", Locale.US);
2258             try {
2259                 fmt.parse("2"); // fewer symbols than required 2
2260                 errln("whoops");
2261             }
2262             catch (ParseException e) {
2263                 logln("ok");
2264             }
2265
2266             try {
2267                 fmt.parse("2255"); // should succeed with obeycount
2268                 logln("ok");
2269             }
2270             catch (ParseException e) {
2271                 errln("whoops");
2272             }
2273
2274             try {
2275                 fmt.parse("ni hao"); // not a number, should fail
2276                 errln("whoops ni hao");
2277             }
2278             catch (ParseException e) {
2279                 logln("ok ni hao");
2280             }
2281         }
2282         {
2283             Calendar xcal = new GregorianCalendar();
2284             xcal.set(Calendar.HOUR_OF_DAY, 0);
2285             DateFormat fmt = new SimpleDateFormat("k");
2286             StringBuffer xbuf = new StringBuffer();
2287             FieldPosition fpos = new FieldPosition(Calendar.HOUR_OF_DAY);
2288             fmt.format(xcal, xbuf, fpos);
2289             try {
2290                 fmt.parse(xbuf.toString());
2291                 logln("ok");
2292                 
2293                 xbuf.setLength(0);
2294                 xcal.set(Calendar.HOUR_OF_DAY, 25);
2295                 fmt.format(xcal, xbuf, fpos);
2296                 Date d2 = fmt.parse(xbuf.toString());
2297                 logln("ok again - d2=" + d2);
2298             }
2299             catch (ParseException e) {
2300                 errln("whoops");
2301             }
2302         }
2303         
2304         {
2305             // cover gmt+hh:mm
2306             DateFormat fmt = new SimpleDateFormat("MM/dd/yy z");
2307             try {
2308                 d = fmt.parse("07/10/53 GMT+10:00");
2309                 logln("ok : d = " + d);
2310             }
2311             catch (ParseException e) {
2312                 errln("Parse of 07/10/53 GMT+10:00 for pattern MM/dd/yy z");
2313             }
2314             
2315             // cover invalid separator after GMT
2316             {
2317                 ParsePosition pp = new ParsePosition(0);
2318                 String text = "07/10/53 GMT=10:00";
2319                 d = fmt.parse(text, pp);
2320                 if(pp.getIndex()!=12){
2321                     errln("Parse of 07/10/53 GMT=10:00 for pattern MM/dd/yy z");
2322                 }
2323                 logln("Parsing of the text stopped at pos: " + pp.getIndex() + " as expected and length is "+text.length());
2324             }
2325             
2326             // cover bad text after GMT+.
2327             try {
2328                 fmt.parse("07/10/53 GMT+blecch");
2329                 logln("ok GMT+blecch");
2330             }
2331             catch (ParseException e) {
2332                 errln("whoops GMT+blecch");
2333             }
2334             
2335             // cover bad text after GMT+hh:.
2336             try {
2337                 fmt.parse("07/10/53 GMT+07:blecch");
2338                 logln("ok GMT+xx:blecch");
2339             }
2340             catch (ParseException e) {
2341                 errln("whoops GMT+xx:blecch");
2342             }
2343             
2344             // cover no ':' GMT+#, # < 24 (hh)
2345             try {
2346                 d = fmt.parse("07/10/53 GMT+07");
2347                 logln("ok GMT+07");
2348             }
2349             catch (ParseException e) {
2350                 errln("Parse of 07/10/53 GMT+07 for pattern MM/dd/yy z");
2351             }
2352             
2353             // cover no ':' GMT+#, # > 24 (hhmm)
2354             try {
2355                 d = fmt.parse("07/10/53 GMT+0730");
2356                 logln("ok");
2357             }
2358             catch (ParseException e) {
2359                 errln("Parse of 07/10/53 GMT+0730 for pattern MM/dd/yy z");
2360             }
2361             
2362             // cover GMT+#, # with second field
2363             try {
2364                 d = fmt.parse("07/10/53 GMT+07:30:15");
2365                 logln("ok GMT+07:30:15");
2366             }
2367             catch (ParseException e) {
2368                 errln("Parse of 07/10/53 GMT+07:30:15 for pattern MM/dd/yy z");
2369             }
2370
2371             // cover no ':' GMT+#, # with second field, no leading zero
2372             try {
2373                 d = fmt.parse("07/10/53 GMT+73015");
2374                 logln("ok GMT+73015");
2375             }
2376             catch (ParseException e) {
2377                 errln("Parse of 07/10/53 GMT+73015 for pattern MM/dd/yy z");
2378             }
2379
2380             // cover no ':' GMT+#, # with 1 digit second field
2381             try {
2382                 d = fmt.parse("07/10/53 GMT+07300");
2383                 logln("ok GMT+07300");
2384             }
2385             catch (ParseException e) {
2386                 errln("Parse of 07/10/53 GMT+07300 for pattern MM/dd/yy z");
2387             }
2388             
2389             // cover raw digits with no leading sign (bad RFC822) 
2390             try {
2391                 d = fmt.parse("07/10/53 07");
2392                 errln("Parse of 07/10/53 07 for pattern MM/dd/yy z passed!");
2393             }
2394             catch (ParseException e) {
2395                 logln("ok");
2396             }
2397             
2398             // cover raw digits (RFC822) 
2399             try {
2400                 d = fmt.parse("07/10/53 +07");
2401                 logln("ok");
2402             }
2403             catch (ParseException e) {
2404                 errln("Parse of 07/10/53 +07 for pattern MM/dd/yy z failed");
2405             }
2406             
2407             // cover raw digits (RFC822) 
2408             try {
2409                 d = fmt.parse("07/10/53 -0730");
2410                 logln("ok");
2411             }
2412             catch (ParseException e) {
2413                 errln("Parse of 07/10/53 -00730 for pattern MM/dd/yy z failed");
2414             }
2415             
2416             // cover raw digits (RFC822) in DST
2417             try {
2418                 fmt.setTimeZone(TimeZone.getTimeZone("PDT"));
2419                 d = fmt.parse("07/10/53 -0730");
2420                 logln("ok");
2421             }
2422             catch (ParseException e) {
2423                 errln("Parse of 07/10/53 -0730 for pattern MM/dd/yy z failed");
2424             }
2425         }
2426         
2427         // TODO: revisit toLocalizedPattern
2428         if (false) {
2429             SimpleDateFormat fmt = new SimpleDateFormat("aabbcc");
2430             try {
2431                 String pat = fmt.toLocalizedPattern();
2432                 errln("whoops, shouldn't have been able to localize aabbcc");
2433             }
2434             catch (IllegalArgumentException e) {
2435                 logln("aabbcc localize ok");
2436             }
2437         }
2438
2439         {
2440             SimpleDateFormat fmt = new SimpleDateFormat("'aabbcc");
2441             try {
2442                 fmt.toLocalizedPattern();
2443                 errln("whoops, localize unclosed quote");
2444             }
2445             catch (IllegalArgumentException e) {
2446                 logln("localize unclosed quote ok");
2447             }
2448         }
2449         {
2450             SimpleDateFormat fmt = new SimpleDateFormat("MM/dd/yy z");
2451             String text = "08/15/58 DBDY"; // bogus time zone
2452             try {
2453                 fmt.parse(text);
2454                 errln("recognized bogus time zone DBDY");
2455             }
2456             catch (ParseException e) {
2457                 logln("time zone ex ok");
2458             }
2459         }
2460         
2461         {
2462             // force fallback to default timezone when fmt timezone 
2463             // is not named
2464             SimpleDateFormat fmt = new SimpleDateFormat("MM/dd/yy z");
2465             // force fallback to default time zone, still fails
2466             fmt.setTimeZone(TimeZone.getTimeZone("GMT+0147")); // not in equivalency group
2467             String text = "08/15/58 DBDY";
2468             try {
2469                 fmt.parse(text);
2470                 errln("Parse of 07/10/53 DBDY for pattern MM/dd/yy z passed");
2471             }
2472             catch (ParseException e) {
2473                 logln("time zone ex2 ok");
2474             }
2475             
2476             // force success on fallback
2477             text = "08/15/58 " + TimeZone.getDefault().getID();
2478             try {
2479                 fmt.parse(text);
2480                 logln("found default tz");
2481             }
2482             catch (ParseException e) {
2483                 errln("whoops, got parse exception");
2484             }
2485         }
2486         
2487         {
2488             // force fallback to symbols list of timezones when neither 
2489             // fmt and default timezone is named
2490             SimpleDateFormat fmt = new SimpleDateFormat("MM/dd/yy z");
2491             TimeZone oldtz = TimeZone.getDefault();
2492             TimeZone newtz = TimeZone.getTimeZone("GMT+0137"); // nonstandard tz
2493             fmt.setTimeZone(newtz);
2494             TimeZone.setDefault(newtz); // todo: fix security issue
2495
2496             // fallback to symbol list, but fail
2497             String text = "08/15/58 DBDY"; // try to parse the bogus time zone
2498             try {
2499                 fmt.parse(text);
2500                 errln("Parse of 07/10/53 DBDY for pattern MM/dd/yy z passed");
2501             }
2502             catch (ParseException e) {
2503                 logln("time zone ex3 ok");
2504             }
2505             catch (Exception e) {
2506                 // hmmm... this shouldn't happen.  don't want to exit this
2507                 // fn with timezone improperly set, so just in case
2508                 TimeZone.setDefault(oldtz);
2509                 throw new IllegalStateException(e.getMessage());
2510             }
2511
2512             // create DFS that recognizes our bogus time zone, sortof
2513             DateFormatSymbols xsym = new DateFormatSymbols();
2514             String[][] tzids = xsym.getZoneStrings();
2515             if (tzids.length > 0) { // let's hope!
2516                 tzids[0][1] = "DBDY"; // change a local name
2517                 logln("replaced '" + tzids[0][0] + "' with DBDY");
2518
2519                 xsym.setZoneStrings(tzids);
2520                 fmt.setDateFormatSymbols(xsym);
2521
2522                 try {
2523                     fmt.parse(text);
2524                     logln("we parsed DBDY (as GMT, but still...)");
2525                 }
2526                 catch (ParseException e) {
2527                     errln("hey, still didn't recognize DBDY");
2528                 }
2529                 finally {
2530                     TimeZone.setDefault(oldtz);
2531                 }
2532             }
2533         }
2534
2535         {
2536             //cover getAvailableULocales
2537             final ULocale[] locales = DateFormat.getAvailableULocales();
2538             long count = locales.length;
2539             if (count==0) {
2540                 errln(" got a empty list for getAvailableULocales");
2541             }else{
2542                 logln("" + count + " available ulocales");            
2543             }
2544         }
2545         
2546         {
2547             //cover DateFormatSymbols.getDateFormatBundle
2548             cal = new GregorianCalendar();
2549             Locale loc = Locale.getDefault();
2550             DateFormatSymbols mysym = new DateFormatSymbols(cal, loc);
2551             if (mysym == null) 
2552                 errln("FAIL: constructs DateFormatSymbols with calendar and locale failed");
2553             
2554             uloc = ULocale.getDefault();
2555             // These APIs are obsolete and return null
2556             ResourceBundle resb = DateFormatSymbols.getDateFormatBundle(cal, loc);
2557             ResourceBundle resb2 = DateFormatSymbols.getDateFormatBundle(cal, uloc);
2558             ResourceBundle resb3 = DateFormatSymbols.getDateFormatBundle(cal.getClass(), loc);
2559             ResourceBundle resb4 = DateFormatSymbols.getDateFormatBundle(cal.getClass(), uloc);
2560
2561             if (resb != null) {
2562                 logln("resb is not null");
2563             }
2564             if (resb2 != null) {
2565                 logln("resb2 is not null");
2566             }
2567             if (resb3 != null) {
2568                 logln("resb3 is not null");
2569             }
2570             if (resb4 != null) {
2571                 logln("resb4 is not null");
2572             }
2573         }
2574
2575         {
2576             //cover DateFormatSymbols.getInstance
2577             DateFormatSymbols datsym1 = DateFormatSymbols.getInstance();
2578             DateFormatSymbols datsym2 = new DateFormatSymbols();
2579             if (!datsym1.equals(datsym2)) {
2580                 errln("FAIL: DateFormatSymbols returned by getInstance()" +
2581                         "does not match new DateFormatSymbols().");
2582             }
2583             datsym1 = DateFormatSymbols.getInstance(Locale.JAPAN);
2584             datsym2 = DateFormatSymbols.getInstance(ULocale.JAPAN);
2585             if (!datsym1.equals(datsym2)) {
2586                 errln("FAIL: DateFormatSymbols returned by getInstance(Locale.JAPAN)" +
2587                         "does not match the one returned by getInstance(ULocale.JAPAN).");
2588             }
2589         }
2590         {
2591             //cover DateFormatSymbols.getAvailableLocales/getAvailableULocales
2592             Locale[] allLocales = DateFormatSymbols.getAvailableLocales();
2593             if (allLocales.length == 0) {
2594                 errln("FAIL: Got a empty list for DateFormatSymbols.getAvailableLocales");
2595             } else {
2596                 logln("PASS: " + allLocales.length +
2597                         " available locales returned by DateFormatSymbols.getAvailableLocales");            
2598             }
2599
2600             ULocale[] allULocales = DateFormatSymbols.getAvailableULocales();
2601             if (allULocales.length == 0) {
2602                 errln("FAIL: Got a empty list for DateFormatSymbols.getAvailableLocales");
2603             } else {
2604                 logln("PASS: " + allULocales.length +
2605                         " available locales returned by DateFormatSymbols.getAvailableULocales");            
2606             }
2607         }
2608     }
2609
2610     public void TestStandAloneMonths()
2611     {
2612         String EN_DATA[] = {
2613             "yyyy MM dd HH:mm:ss",
2614
2615             "yyyy LLLL dd H:mm:ss", "fp", "2004 03 10 16:36:31", "2004 March 10 16:36:31", "2004 03 10 16:36:31",
2616             "yyyy LLL dd H:mm:ss",  "fp", "2004 03 10 16:36:31", "2004 Mar 10 16:36:31",   "2004 03 10 16:36:31",
2617             "yyyy LLLL dd H:mm:ss", "F",  "2004 03 10 16:36:31", "2004 March 10 16:36:31",
2618             "yyyy LLL dd H:mm:ss",  "pf", "2004 Mar 10 16:36:31", "2004 03 10 16:36:31", "2004 Mar 10 16:36:31",
2619             
2620             "LLLL", "fp", "1970 01 01 0:00:00", "January",   "1970 01 01 0:00:00",
2621             "LLLL", "fp", "1970 02 01 0:00:00", "February",  "1970 02 01 0:00:00",
2622             "LLLL", "fp", "1970 03 01 0:00:00", "March",     "1970 03 01 0:00:00",
2623             "LLLL", "fp", "1970 04 01 0:00:00", "April",     "1970 04 01 0:00:00",
2624             "LLLL", "fp", "1970 05 01 0:00:00", "May",       "1970 05 01 0:00:00",
2625             "LLLL", "fp", "1970 06 01 0:00:00", "June",      "1970 06 01 0:00:00",
2626             "LLLL", "fp", "1970 07 01 0:00:00", "July",      "1970 07 01 0:00:00",
2627             "LLLL", "fp", "1970 08 01 0:00:00", "August",    "1970 08 01 0:00:00",
2628             "LLLL", "fp", "1970 09 01 0:00:00", "September", "1970 09 01 0:00:00",
2629             "LLLL", "fp", "1970 10 01 0:00:00", "October",   "1970 10 01 0:00:00",
2630             "LLLL", "fp", "1970 11 01 0:00:00", "November",  "1970 11 01 0:00:00",
2631             "LLLL", "fp", "1970 12 01 0:00:00", "December",  "1970 12 01 0:00:00",
2632             
2633             "LLL", "fp", "1970 01 01 0:00:00", "Jan", "1970 01 01 0:00:00",
2634             "LLL", "fp", "1970 02 01 0:00:00", "Feb", "1970 02 01 0:00:00",
2635             "LLL", "fp", "1970 03 01 0:00:00", "Mar", "1970 03 01 0:00:00",
2636             "LLL", "fp", "1970 04 01 0:00:00", "Apr", "1970 04 01 0:00:00",
2637             "LLL", "fp", "1970 05 01 0:00:00", "May", "1970 05 01 0:00:00",
2638             "LLL", "fp", "1970 06 01 0:00:00", "Jun", "1970 06 01 0:00:00",
2639             "LLL", "fp", "1970 07 01 0:00:00", "Jul", "1970 07 01 0:00:00",
2640             "LLL", "fp", "1970 08 01 0:00:00", "Aug", "1970 08 01 0:00:00",
2641             "LLL", "fp", "1970 09 01 0:00:00", "Sep", "1970 09 01 0:00:00",
2642             "LLL", "fp", "1970 10 01 0:00:00", "Oct", "1970 10 01 0:00:00",
2643             "LLL", "fp", "1970 11 01 0:00:00", "Nov", "1970 11 01 0:00:00",
2644             "LLL", "fp", "1970 12 01 0:00:00", "Dec", "1970 12 01 0:00:00",
2645         };
2646         
2647         String CS_DATA[] = {
2648             "yyyy MM dd HH:mm:ss",
2649
2650             "yyyy LLLL dd H:mm:ss", "fp", "2004 04 10 16:36:31", "2004 duben 10 16:36:31", "2004 04 10 16:36:31",
2651             "yyyy MMMM dd H:mm:ss", "fp", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31", "2004 04 10 16:36:31",
2652             "yyyy LLL dd H:mm:ss",  "fp", "2004 04 10 16:36:31", "2004 4. 10 16:36:31",   "2004 04 10 16:36:31",
2653             "yyyy LLLL dd H:mm:ss", "F",  "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
2654             "yyyy MMMM dd H:mm:ss", "F",  "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
2655             "yyyy LLLL dd H:mm:ss", "pf", "2004 duben 10 16:36:31", "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
2656             "yyyy MMMM dd H:mm:ss", "pf", "2004 dubna 10 16:36:31", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
2657             
2658             "LLLL", "fp", "1970 01 01 0:00:00", "leden",               "1970 01 01 0:00:00",
2659             "LLLL", "fp", "1970 02 01 0:00:00", "\u00FAnor",           "1970 02 01 0:00:00",
2660             "LLLL", "fp", "1970 03 01 0:00:00", "b\u0159ezen",         "1970 03 01 0:00:00",
2661             "LLLL", "fp", "1970 04 01 0:00:00", "duben",               "1970 04 01 0:00:00",
2662             "LLLL", "fp", "1970 05 01 0:00:00", "kv\u011Bten",         "1970 05 01 0:00:00",
2663             "LLLL", "fp", "1970 06 01 0:00:00", "\u010Derven",         "1970 06 01 0:00:00",
2664             "LLLL", "fp", "1970 07 01 0:00:00", "\u010Dervenec",       "1970 07 01 0:00:00",
2665             "LLLL", "fp", "1970 08 01 0:00:00", "srpen",               "1970 08 01 0:00:00",
2666             "LLLL", "fp", "1970 09 01 0:00:00", "z\u00E1\u0159\u00ED", "1970 09 01 0:00:00",
2667             "LLLL", "fp", "1970 10 01 0:00:00", "\u0159\u00EDjen",     "1970 10 01 0:00:00",
2668             "LLLL", "fp", "1970 11 01 0:00:00", "listopad",            "1970 11 01 0:00:00",
2669             "LLLL", "fp", "1970 12 01 0:00:00", "prosinec",            "1970 12 01 0:00:00",
2670
2671             "LLL", "fp", "1970 01 01 0:00:00", "1.",  "1970 01 01 0:00:00",
2672             "LLL", "fp", "1970 02 01 0:00:00", "2.",  "1970 02 01 0:00:00",
2673             "LLL", "fp", "1970 03 01 0:00:00", "3.",  "1970 03 01 0:00:00",
2674             "LLL", "fp", "1970 04 01 0:00:00", "4.",  "1970 04 01 0:00:00",
2675             "LLL", "fp", "1970 05 01 0:00:00", "5.",  "1970 05 01 0:00:00",
2676             "LLL", "fp", "1970 06 01 0:00:00", "6.",  "1970 06 01 0:00:00",
2677             "LLL", "fp", "1970 07 01 0:00:00", "7.",  "1970 07 01 0:00:00",
2678             "LLL", "fp", "1970 08 01 0:00:00", "8.",  "1970 08 01 0:00:00",
2679             "LLL", "fp", "1970 09 01 0:00:00", "9.",  "1970 09 01 0:00:00",
2680             "LLL", "fp", "1970 10 01 0:00:00", "10.", "1970 10 01 0:00:00",
2681             "LLL", "fp", "1970 11 01 0:00:00", "11.", "1970 11 01 0:00:00",
2682             "LLL", "fp", "1970 12 01 0:00:00", "12.", "1970 12 01 0:00:00",
2683         };
2684         
2685         expect(EN_DATA, new Locale("en", "", ""));
2686         expect(CS_DATA, new Locale("cs", "", ""));
2687     }
2688     
2689     public void TestStandAloneDays()
2690     {
2691         String EN_DATA[] = {
2692             "yyyy MM dd HH:mm:ss",
2693
2694             "cccc", "fp", "1970 01 04 0:00:00", "Sunday",    "1970 01 04 0:00:00",
2695             "cccc", "fp", "1970 01 05 0:00:00", "Monday",    "1970 01 05 0:00:00",
2696             "cccc", "fp", "1970 01 06 0:00:00", "Tuesday",   "1970 01 06 0:00:00",
2697             "cccc", "fp", "1970 01 07 0:00:00", "Wednesday", "1970 01 07 0:00:00",
2698             "cccc", "fp", "1970 01 01 0:00:00", "Thursday",  "1970 01 01 0:00:00",
2699             "cccc", "fp", "1970 01 02 0:00:00", "Friday",    "1970 01 02 0:00:00",
2700             "cccc", "fp", "1970 01 03 0:00:00", "Saturday",  "1970 01 03 0:00:00",
2701             
2702             "ccc", "fp", "1970 01 04 0:00:00", "Sun", "1970 01 04 0:00:00",
2703             "ccc", "fp", "1970 01 05 0:00:00", "Mon", "1970 01 05 0:00:00",
2704             "ccc", "fp", "1970 01 06 0:00:00", "Tue", "1970 01 06 0:00:00",
2705             "ccc", "fp", "1970 01 07 0:00:00", "Wed", "1970 01 07 0:00:00",
2706             "ccc", "fp", "1970 01 01 0:00:00", "Thu", "1970 01 01 0:00:00",
2707             "ccc", "fp", "1970 01 02 0:00:00", "Fri", "1970 01 02 0:00:00",
2708             "ccc", "fp", "1970 01 03 0:00:00", "Sat", "1970 01 03 0:00:00",
2709         };
2710             
2711         String CS_DATA[] = {
2712             "yyyy MM dd HH:mm:ss",
2713
2714             "cccc", "fp", "1970 01 04 0:00:00", "ned\u011Ble",       "1970 01 04 0:00:00",
2715             "cccc", "fp", "1970 01 05 0:00:00", "pond\u011Bl\u00ED", "1970 01 05 0:00:00",
2716             "cccc", "fp", "1970 01 06 0:00:00", "\u00FAter\u00FD",   "1970 01 06 0:00:00",
2717             "cccc", "fp", "1970 01 07 0:00:00", "st\u0159eda",       "1970 01 07 0:00:00",
2718             "cccc", "fp", "1970 01 01 0:00:00", "\u010Dtvrtek",      "1970 01 01 0:00:00",
2719             "cccc", "fp", "1970 01 02 0:00:00", "p\u00E1tek",        "1970 01 02 0:00:00",
2720             "cccc", "fp", "1970 01 03 0:00:00", "sobota",            "1970 01 03 0:00:00",
2721             
2722             "ccc", "fp", "1970 01 04 0:00:00", "ne",      "1970 01 04 0:00:00",
2723             "ccc", "fp", "1970 01 05 0:00:00", "po",      "1970 01 05 0:00:00",
2724             "ccc", "fp", "1970 01 06 0:00:00", "\u00FAt", "1970 01 06 0:00:00",
2725             "ccc", "fp", "1970 01 07 0:00:00", "st",      "1970 01 07 0:00:00",
2726             "ccc", "fp", "1970 01 01 0:00:00", "\u010Dt", "1970 01 01 0:00:00",
2727             "ccc", "fp", "1970 01 02 0:00:00", "p\u00E1", "1970 01 02 0:00:00",
2728             "ccc", "fp", "1970 01 03 0:00:00", "so",      "1970 01 03 0:00:00",
2729         };
2730         
2731         expect(EN_DATA, new Locale("en", "", ""));
2732         expect(CS_DATA, new Locale("cs", "", ""));
2733     }
2734     
2735     public void TestNarrowNames()
2736     {
2737         String EN_DATA[] = {
2738                 "yyyy MM dd HH:mm:ss",
2739
2740                 "yyyy MMMMM dd H:mm:ss", "2004 03 10 16:36:31", "2004 M 10 16:36:31",
2741                 "yyyy LLLLL dd H:mm:ss",  "2004 03 10 16:36:31", "2004 M 10 16:36:31",
2742                 
2743                 "MMMMM", "1970 01 01 0:00:00", "J",
2744                 "MMMMM", "1970 02 01 0:00:00", "F",
2745                 "MMMMM", "1970 03 01 0:00:00", "M",
2746                 "MMMMM", "1970 04 01 0:00:00", "A",
2747                 "MMMMM", "1970 05 01 0:00:00", "M",
2748                 "MMMMM", "1970 06 01 0:00:00", "J",
2749                 "MMMMM", "1970 07 01 0:00:00", "J",
2750                 "MMMMM", "1970 08 01 0:00:00", "A",
2751                 "MMMMM", "1970 09 01 0:00:00", "S",
2752                 "MMMMM", "1970 10 01 0:00:00", "O",
2753                 "MMMMM", "1970 11 01 0:00:00", "N",
2754                 "MMMMM", "1970 12 01 0:00:00", "D",
2755                 
2756                 "LLLLL", "1970 01 01 0:00:00", "J",
2757                 "LLLLL", "1970 02 01 0:00:00", "F",
2758                 "LLLLL", "1970 03 01 0:00:00", "M",
2759                 "LLLLL", "1970 04 01 0:00:00", "A",
2760                 "LLLLL", "1970 05 01 0:00:00", "M",
2761                 "LLLLL", "1970 06 01 0:00:00", "J",
2762                 "LLLLL", "1970 07 01 0:00:00", "J",
2763                 "LLLLL", "1970 08 01 0:00:00", "A",
2764                 "LLLLL", "1970 09 01 0:00:00", "S",
2765                 "LLLLL", "1970 10 01 0:00:00", "O",
2766                 "LLLLL", "1970 11 01 0:00:00", "N",
2767                 "LLLLL", "1970 12 01 0:00:00", "D",
2768
2769                 "EEEEE", "1970 01 04 0:00:00", "S",
2770                 "EEEEE", "1970 01 05 0:00:00", "M",
2771                 "EEEEE", "1970 01 06 0:00:00", "T",
2772                 "EEEEE", "1970 01 07 0:00:00", "W",
2773                 "EEEEE", "1970 01 01 0:00:00", "T",
2774                 "EEEEE", "1970 01 02 0:00:00", "F",
2775                 "EEEEE", "1970 01 03 0:00:00", "S",
2776                 
2777                 "ccccc", "1970 01 04 0:00:00", "S",
2778                 "ccccc", "1970 01 05 0:00:00", "M",
2779                 "ccccc", "1970 01 06 0:00:00", "T",
2780                 "ccccc", "1970 01 07 0:00:00", "W",
2781                 "ccccc", "1970 01 01 0:00:00", "T",
2782                 "ccccc", "1970 01 02 0:00:00", "F",
2783                 "ccccc", "1970 01 03 0:00:00", "S",
2784             };
2785             
2786             String CS_DATA[] = {
2787                 "yyyy MM dd HH:mm:ss",
2788
2789                 "yyyy LLLLL dd H:mm:ss", "2004 04 10 16:36:31", "2004 d 10 16:36:31",
2790                 "yyyy MMMMM dd H:mm:ss", "2004 04 10 16:36:31", "2004 d 10 16:36:31",
2791                 
2792                 "MMMMM", "1970 01 01 0:00:00", "l",
2793                 "MMMMM", "1970 02 01 0:00:00", "\u00FA",
2794                 "MMMMM", "1970 03 01 0:00:00", "b",
2795                 "MMMMM", "1970 04 01 0:00:00", "d",
2796                 "MMMMM", "1970 05 01 0:00:00", "k",
2797                 "MMMMM", "1970 06 01 0:00:00", "\u010D",
2798                 "MMMMM", "1970 07 01 0:00:00", "\u010D",
2799                 "MMMMM", "1970 08 01 0:00:00", "s",
2800                 "MMMMM", "1970 09 01 0:00:00", "z",
2801                 "MMMMM", "1970 10 01 0:00:00", "\u0159",
2802                 "MMMMM", "1970 11 01 0:00:00", "l",
2803                 "MMMMM", "1970 12 01 0:00:00", "p",
2804                 
2805                 "LLLLL", "1970 01 01 0:00:00", "l",
2806                 "LLLLL", "1970 02 01 0:00:00", "\u00FA",
2807                 "LLLLL", "1970 03 01 0:00:00", "b",
2808                 "LLLLL", "1970 04 01 0:00:00", "d",
2809                 "LLLLL", "1970 05 01 0:00:00", "k",
2810                 "LLLLL", "1970 06 01 0:00:00", "\u010D",
2811                 "LLLLL", "1970 07 01 0:00:00", "\u010D",
2812                 "LLLLL", "1970 08 01 0:00:00", "s",
2813                 "LLLLL", "1970 09 01 0:00:00", "z",
2814                 "LLLLL", "1970 10 01 0:00:00", "\u0159",
2815                 "LLLLL", "1970 11 01 0:00:00", "l",
2816                 "LLLLL", "1970 12 01 0:00:00", "p",
2817
2818                 "EEEEE", "1970 01 04 0:00:00", "N",
2819                 "EEEEE", "1970 01 05 0:00:00", "P",
2820                 "EEEEE", "1970 01 06 0:00:00", "\u00DA",
2821                 "EEEEE", "1970 01 07 0:00:00", "S",
2822                 "EEEEE", "1970 01 01 0:00:00", "\u010C",
2823                 "EEEEE", "1970 01 02 0:00:00", "P",
2824                 "EEEEE", "1970 01 03 0:00:00", "S",
2825
2826                 "ccccc", "1970 01 04 0:00:00", "N",
2827                 "ccccc", "1970 01 05 0:00:00", "P",
2828                 "ccccc", "1970 01 06 0:00:00", "\u00DA",
2829                 "ccccc", "1970 01 07 0:00:00", "S",
2830                 "ccccc", "1970 01 01 0:00:00", "\u010C",
2831                 "ccccc", "1970 01 02 0:00:00", "P",
2832                 "ccccc", "1970 01 03 0:00:00", "S",
2833             };
2834             
2835             expectFormat(EN_DATA, new Locale("en", "", ""));
2836             expectFormat(CS_DATA, new Locale("cs", "", ""));
2837     }
2838     
2839     public void TestEras()
2840     {
2841         String EN_DATA[] = {
2842             "yyyy MM dd",
2843
2844             "MMMM dd yyyy G",    "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
2845             "MMMM dd yyyy GG",   "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
2846             "MMMM dd yyyy GGG",  "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
2847             "MMMM dd yyyy GGGG", "fp", "1951 07 17", "July 17 1951 Anno Domini", "1951 07 17",
2848
2849             "MMMM dd yyyy G",    "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
2850             "MMMM dd yyyy GG",   "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
2851             "MMMM dd yyyy GGG",  "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
2852             "MMMM dd yyyy GGGG", "fp", "-438 07 17", "July 17 0439 Before Christ", "-438 07 17",
2853        };
2854         
2855         expect(EN_DATA, new Locale("en", "", ""));
2856     }
2857 /*    
2858     public void TestQuarters()
2859     {
2860         String EN_DATA[] = {
2861             "yyyy MM dd",
2862
2863             "Q",    "fp", "1970 01 01", "1",           "1970 01 01",
2864             "QQ",   "fp", "1970 04 01", "02",          "1970 04 01",
2865             "QQQ",  "fp", "1970 07 01", "Q3",          "1970 07 01",
2866             "QQQQ", "fp", "1970 10 01", "4th quarter", "1970 10 01",
2867
2868             "q",    "fp", "1970 01 01", "1",           "1970 01 01",
2869             "qq",   "fp", "1970 04 01", "02",          "1970 04 01",
2870             "qqq",  "fp", "1970 07 01", "Q3",          "1970 07 01",
2871             "qqqq", "fp", "1970 10 01", "4th quarter", "1970 10 01",
2872        };
2873         
2874         expect(EN_DATA, new Locale("en", "", ""));
2875     }
2876 */
2877
2878     /**
2879      * Test DateFormat's parsing of default GMT variants.  See ticket#6135
2880      */
2881     public void TestGMTParsing() {
2882         String DATA[] = {
2883             "HH:mm:ss Z",
2884
2885             // pattern, input, expected output (in quotes)
2886             "HH:mm:ss Z",       "10:20:30 GMT+03:00",   "10:20:30 +0300",
2887             "HH:mm:ss Z",       "10:20:30 UT-02:00",    "10:20:30 -0200",
2888             "HH:mm:ss Z",       "10:20:30 GMT",         "10:20:30 +0000",
2889             "HH:mm:ss vvvv",    "10:20:30 UT+10:00",    "10:20:30 +1000",
2890             "HH:mm:ss zzzz",    "10:20:30 UTC",         "10:20:30 +0000",   // standalone "UTC"
2891             "ZZZZ HH:mm:ss",    "UT 10:20:30",          "10:20:30 +0000",
2892             "V HH:mm:ss",       "UT+0130 10:20:30",     "10:20:30 +0130",
2893             "V HH:mm:ss",       "UTC+0130 10:20:30",    null,               // UTC+0130 is not a supported pattern
2894             "HH mm Z ss",       "10 20 GMT-1100 30",    "10:20:30 -1100",
2895         };
2896         expectParse(DATA, new Locale("en", "", ""));
2897     }
2898
2899     /**
2900      * Test parsing.  Input is an array that starts with the following
2901      * header:
2902      *
2903      * [0]   = pattern string to parse [i+2] with
2904      *
2905      * followed by test cases, each of which is 3 array elements:
2906      *
2907      * [i]   = pattern, or null to reuse prior pattern
2908      * [i+1] = input string
2909      * [i+2] = expected parse result (parsed with pattern [0])
2910      *
2911      * If expect parse failure, then [i+2] should be null.
2912      */
2913     void expectParse(String[] data, Locale loc) {
2914         Date FAIL = null;
2915         String FAIL_STR = "parse failure";
2916         int i = 0;
2917
2918         SimpleDateFormat fmt = new SimpleDateFormat("", loc);
2919         SimpleDateFormat ref = new SimpleDateFormat(data[i++], loc);
2920         SimpleDateFormat gotfmt = new SimpleDateFormat("G yyyy MM dd HH:mm:ss z", loc);
2921
2922         String currentPat = null;
2923         while (i<data.length) {
2924             String pattern  = data[i++];
2925             String input    = data[i++];
2926             String expected = data[i++];
2927
2928             if (pattern != null) {
2929                 fmt.applyPattern(pattern);
2930                 currentPat = pattern;
2931             }
2932             String gotstr = FAIL_STR;
2933             Date got;
2934             try {
2935                 got = fmt.parse(input);
2936                 gotstr = gotfmt.format(got);
2937             } catch (ParseException e1) {
2938                 got = FAIL;
2939             }
2940
2941             Date exp = FAIL;
2942             String expstr = FAIL_STR;
2943             if (expected != null) {
2944                 expstr = expected;
2945                 try {
2946                     exp = ref.parse(expstr);
2947                 } catch (ParseException e2) {
2948                     errln("FAIL: Internal test error");
2949                 }
2950             }
2951
2952             if (got == exp || (got != null && got.equals(exp))) {
2953                 logln("Ok: " + input + " x " +
2954                       currentPat + " => " + gotstr);                
2955             } else {
2956                 errln("FAIL: " + input + " x " +
2957                       currentPat + " => " + gotstr + ", expected " +
2958                       expstr);
2959             }
2960         }    
2961     }
2962     
2963     /**
2964      * Test formatting.  Input is an array of String that starts
2965      * with a single 'header' element
2966      *
2967      * [0]   = reference dateformat pattern string (ref)
2968      *
2969      * followed by test cases, each of which is 4 or 5 elements:
2970      *
2971      * [i]   = test dateformat pattern string (test), or null to reuse prior test pattern
2972      * [i+1] = data string A
2973      * [i+2] = data string B
2974      *
2975      * Formats a date, checks the result.
2976      *
2977      * Examples:
2978      * "y/M/d H:mm:ss.SSS", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567"
2979      * -- ref.parse A, get t0
2980      * -- test.format t0, get r0
2981      * -- compare r0 to B, fail if not equal
2982      */
2983     void expectFormat(String[] data, Locale loc)
2984     {
2985         int i = 1;
2986         String currentPat = null;
2987         SimpleDateFormat ref = new SimpleDateFormat(data[0], loc);
2988
2989         while (i<data.length) {
2990             SimpleDateFormat fmt = new SimpleDateFormat("", loc);
2991             String pattern  = data[i++];
2992             if (pattern != null) {
2993                 fmt.applyPattern(pattern);
2994                 currentPat = pattern;
2995             }
2996
2997             String datestr = data[i++];
2998             String string = data[i++];
2999             Date date = null;
3000             
3001             try {
3002                 date = ref.parse(datestr);
3003             } catch (ParseException e) {
3004                 errln("FAIL: Internal test error; can't parse " + datestr);
3005                 continue;
3006             }
3007             
3008             assertEquals("\"" + currentPat + "\".format(" + datestr + ")",
3009                          string,
3010                          fmt.format(date));
3011         }
3012     }
3013
3014     /**
3015      * Test formatting and parsing.  Input is an array of String that starts
3016      * with a single 'header' element
3017      *
3018      * [0]   = reference dateformat pattern string (ref)
3019      *
3020      * followed by test cases, each of which is 4 or 5 elements:
3021      *
3022      * [i]   = test dateformat pattern string (test), or null to reuse prior test pattern
3023      * [i+1] = control string, either "fp", "pf", or "F".
3024      * [i+2] = data string A
3025      * [i+3] = data string B
3026      * [i+4] = data string C (not present for 'F' control string)
3027      *
3028      * Note: the number of data strings depends on the control string.
3029      *
3030      * fp formats a date, checks the result, then parses the result and checks against a (possibly different) date
3031      * pf parses a string, checks the result, then formats the result and checks against a (possibly different) string
3032      * F is a shorthand for fp when the second date is the same as the first
3033      * P is a shorthand for pf when the second string is the same as the first
3034      *
3035      * Examples:
3036      * (fp) "y/M/d H:mm:ss.SS", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.56", "2004 03 10 16:36:31.560",
3037      * -- ref.parse A, get t0
3038      * -- test.format t0, get r0
3039      * -- compare r0 to B, fail if not equal
3040      * -- test.parse B, get t1
3041      * -- ref.parse C, get t2
3042      * -- compare t1 and t2, fail if not equal
3043      *
3044      * (F) "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567"
3045      * -- ref.parse A, get t0
3046      * -- test.format t0, get r0
3047      * -- compare r0 to B, fail if not equal
3048      * -- test.parse B, get t1
3049      * -- compare t1 and t0, fail if not equal
3050      *
3051      * (pf) "y/M/d H:mm:ss.SSSS", "pf", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.5670",
3052      * -- test.parse A, get t0
3053      * -- ref.parse B, get t1
3054      * -- compare t0 to t1, fail if not equal
3055      * -- test.format t1, get r0
3056      * -- compare r0 and C, fail if not equal
3057      *
3058      * (P) "y/M/d H:mm:ss.SSSS", "P", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567"",
3059      * -- test.parse A, get t0
3060      * -- ref.parse B, get t1
3061      * -- compare t0 to t1, fail if not equal
3062      * -- test.format t1, get r0
3063      * -- compare r0 and A, fail if not equal
3064      */
3065     void expect(String[] data, Locale loc) {
3066         int i = 1;
3067         SimpleDateFormat univ = new SimpleDateFormat("EE G yyyy MM dd HH:mm:ss.SSS zzz", loc);
3068         String currentPat = null;
3069         SimpleDateFormat ref = new SimpleDateFormat(data[0], loc);
3070
3071         while (i<data.length) {
3072             SimpleDateFormat fmt = new SimpleDateFormat("", loc);
3073             String pattern  = data[i++];
3074             if (pattern != null) {
3075                 fmt.applyPattern(pattern);
3076                 currentPat = pattern;
3077             }
3078
3079             String control = data[i++];
3080
3081             if (control.equals("fp") || control.equals("F")) {
3082                 // 'f'
3083                 String datestr = data[i++];
3084                 String string = data[i++];
3085                 String datestr2 = datestr;
3086                 if (control.length() == 2) {
3087                     datestr2 = data[i++];
3088                 }
3089                 Date date = null;
3090                 try {
3091                     date = ref.parse(datestr);
3092                 } catch (ParseException e) {
3093                     errln("FAIL: Internal test error; can't parse " + datestr);
3094                     continue;
3095                 }
3096                 assertEquals("\"" + currentPat + "\".format(" + datestr + ")",
3097                              string,
3098                              fmt.format(date));
3099                 // 'p'
3100                 if (!datestr2.equals(datestr)) {
3101                     try {
3102                         date = ref.parse(datestr2);
3103                     } catch (ParseException e2) {
3104                         errln("FAIL: Internal test error; can't parse " + datestr2);
3105                         continue;
3106                     }
3107                 }
3108                 try {
3109                     Date parsedate = fmt.parse(string);
3110                     assertEquals("\"" + currentPat + "\".parse(" + string + ")",
3111                                  univ.format(date),
3112                                  univ.format(parsedate));
3113                 } catch (ParseException e3) {
3114                     errln("FAIL: \"" + currentPat + "\".parse(" + string + ") => " +
3115                           e3);
3116                     continue;
3117                 }
3118             }
3119             else if (control.equals("pf") || control.equals("P")) {
3120                 // 'p'
3121                 String string = data[i++];
3122                 String datestr = data[i++];
3123                 String string2 = string;
3124                 if (control.length() == 2) {
3125                     string2 = data[i++];
3126                 }
3127
3128                 Date date = null;
3129                 try {
3130                     date = ref.parse(datestr);
3131                 } catch (ParseException e) {
3132                     errln("FAIL: Internal test error; can't parse " + datestr);
3133                     continue;
3134                 }
3135                 try {
3136                     Date parsedate = fmt.parse(string);
3137                     assertEquals("\"" + currentPat + "\".parse(" + string + ")",
3138                                  univ.format(date),
3139                                  univ.format(parsedate));
3140                 } catch (ParseException e2) {
3141                     errln("FAIL: \"" + currentPat + "\".parse(" + string + ") => " +
3142                           e2);
3143                     continue;
3144                 }
3145                 // 'f'
3146                 assertEquals("\"" + currentPat + "\".format(" + datestr + ")",
3147                              string2,
3148                              fmt.format(date));
3149             }
3150             else {
3151                 errln("FAIL: Invalid control string " + control);
3152                 return;
3153             }
3154         }
3155     }
3156     /*
3157     public void TestJB4757(){
3158         DateFormat dfmt = DateFormat.getDateInstance(DateFormat.FULL, ULocale.ROOT);
3159     }
3160     */
3161
3162 //#if defined(FOUNDATION10) || defined(J2SE13)
3163 //#else
3164     /*
3165      * Test case for formatToCharacterIterator
3166      */
3167     public void TestFormatToCharacterIterator() {
3168         // Generate pattern string including all pattern letters with various length
3169         AttributedCharacterIterator acit;
3170         final char SEPCHAR = '~';
3171         String[] patterns = new String[5];
3172         StringBuffer sb = new StringBuffer();
3173         for (int i = 0; i < patterns.length; i++) {
3174             sb.setLength(0);
3175             for (int j = 0; j < PATTERN_CHARS.length(); j++) {
3176                 if (j != 0) {
3177                     for (int k = 0; k <= i; k++) {
3178                         sb.append(SEPCHAR);
3179                     }
3180                 }
3181                 char letter = PATTERN_CHARS.charAt(j);
3182                 for (int k = 0; k <= i; k++) {
3183                     sb.append(letter);
3184                 }
3185             }
3186             patterns[i] = sb.toString();
3187         }
3188         if (isVerbose()) {
3189             for (int i = 0; i < patterns.length; i++) {
3190                 logln("patterns[" + i + "] = " + patterns[i]);
3191             }
3192         }
3193
3194         Calendar cal = Calendar.getInstance();
3195         cal.set(2007, Calendar.JULY, 16, 8, 20, 25);
3196         cal.set(Calendar.MILLISECOND, 567);
3197         final Date d = cal.getTime();
3198
3199         // Test AttributedCharacterIterator returned by SimpleDateFormat
3200         for (int i = 0; i < patterns.length; i++) {
3201             SimpleDateFormat sdf = new SimpleDateFormat(patterns[i]);
3202             acit = sdf.formatToCharacterIterator(d);
3203             int patidx = 0;
3204
3205             while (true) {
3206                 Map map = acit.getAttributes();
3207                 int limit = acit.getRunLimit();
3208                 if (map.isEmpty()) {
3209                     // Must be pattern literal - '~'
3210                     while (acit.getIndex() < limit) {
3211                         if (acit.current() != SEPCHAR) {
3212                             errln("FAIL: Invalid pattern literal at " + acit.current() + " in patterns[" + i + "]");
3213                         }
3214                         acit.next();
3215                     }
3216                 } else {
3217                     Set keySet = map.keySet();
3218                     if (keySet.size() == 1) {
3219                         // Check the attribute
3220                         Iterator keyIterator = keySet.iterator();
3221                         DateFormat.Field attr = (DateFormat.Field)keyIterator.next();
3222                         if (!DATEFORMAT_FIELDS[patidx].equals(attr)) {
3223                             errln("FAIL: The attribute at " + acit.getIndex() + " in patterns[" + i + "" +
3224                                     "] is " + attr + " - Expected: " + DATEFORMAT_FIELDS[patidx]);
3225                         }
3226                     } else {
3227                         // SimpleDateFormat#formatToCharacterIterator never set multiple
3228                         // attributes to a single text run.
3229                         errln("FAIL: Multiple attributes were set");
3230                     }
3231                     patidx++;
3232                     // Move to the run limit
3233                     acit.setIndex(limit);
3234                 }
3235                 if (acit.current() == CharacterIterator.DONE) {
3236                     break;
3237                 }
3238             }
3239         }
3240
3241         // ChineseDateFormat has pattern letter 'l' for leap month marker in addition to regular DateFormat
3242         cal.clear();
3243         cal.set(2009, Calendar.JUNE, 22); // 26x78-5-30
3244         Date nonLeapMonthDate = cal.getTime(); // non-leap month
3245         cal.set(2009, Calendar.JUNE, 23); // 26x78-5*-1
3246         Date leapMonthDate = cal.getTime(); // leap month
3247
3248         ChineseDateFormat cdf = new ChineseDateFormat("y'x'G-Ml-d", ULocale.US);
3249         acit = cdf.formatToCharacterIterator(nonLeapMonthDate);
3250         Set keys = acit.getAllAttributeKeys();
3251         if (keys.contains(ChineseDateFormat.Field.IS_LEAP_MONTH)) {
3252             errln("FAIL: IS_LEAP_MONTH attribute must not present for Chinese calendar date "
3253                     + cdf.format(nonLeapMonthDate));
3254         }
3255         acit = cdf.formatToCharacterIterator(leapMonthDate);
3256         keys = acit.getAllAttributeKeys();
3257         if (!keys.contains(ChineseDateFormat.Field.IS_LEAP_MONTH)) {
3258             errln("FAIL: IS_LEAP_MONTH attribute must present for Chinese calendar date "
3259                     + cdf.format(leapMonthDate));
3260         }
3261     }
3262
3263     /*
3264      * API coverage test case for formatToCharacterIterator
3265      */
3266     public void TestFormatToCharacterIteratorCoverage() {
3267         // Calling formatToCharacterIterator, using various argument types
3268         DateFormat df = DateFormat.getDateTimeInstance();
3269         AttributedCharacterIterator acit = null;
3270
3271         Calendar cal = Calendar.getInstance();
3272         try {
3273             acit = df.formatToCharacterIterator(cal);
3274             if (acit == null) {
3275                 errln("FAIL: null AttributedCharacterIterator returned by formatToCharacterIterator(Calendar)");
3276             }
3277         } catch (IllegalArgumentException iae) {
3278             errln("FAIL: Calendar must be accepted by formatToCharacterIterator");
3279         }
3280
3281         Date d = cal.getTime();
3282         try {
3283             acit = df.formatToCharacterIterator(d);
3284             if (acit == null) {
3285                 errln("FAIL: null AttributedCharacterIterator returned by formatToCharacterIterator(Date)");
3286             }
3287         } catch (IllegalArgumentException iae) {
3288             errln("FAIL: Date must be accepted by formatToCharacterIterator");
3289         }
3290
3291         Number num = new Long(d.getTime());
3292         try {
3293             acit = df.formatToCharacterIterator(num);
3294             if (acit == null) {
3295                 errln("FAIL: null AttributedCharacterIterator returned by formatToCharacterIterator(Number)");
3296             }
3297         } catch (IllegalArgumentException iae) {
3298             errln("FAIL: Number must be accepted by formatToCharacterIterator");
3299         }
3300
3301         boolean isException = false;
3302         String str = df.format(d);
3303         try {
3304             acit = df.formatToCharacterIterator(str);
3305             if (acit == null) {
3306                 errln("FAIL: null AttributedCharacterIterator returned by formatToCharacterIterator(String)");
3307             }
3308         } catch (IllegalArgumentException iae) {
3309             logln("IllegalArgumentException is thrown by formatToCharacterIterator");
3310             isException = true;
3311         }
3312         if (!isException) {
3313             errln("FAIL: String must not be accepted by formatToCharacterIterator");
3314         }
3315
3316         // DateFormat.Field#ofCalendarField and getCalendarField
3317         for (int i = 0; i < DATEFORMAT_FIELDS.length; i++) {
3318             int calField = DATEFORMAT_FIELDS[i].getCalendarField();
3319             if (calField != -1) {
3320                 DateFormat.Field field = DateFormat.Field.ofCalendarField(calField);
3321                 if (field != DATEFORMAT_FIELDS[i]) {
3322                     errln("FAIL: " + field + " is returned for a Calendar field " + calField
3323                             + " - Expected: " + DATEFORMAT_FIELDS[i]);
3324                 }
3325             }
3326         }
3327
3328         // IllegalArgument for ofCalendarField
3329         isException = false;
3330         try {
3331             DateFormat.Field.ofCalendarField(-1);
3332         } catch (IllegalArgumentException iae) {
3333             logln("IllegalArgumentException is thrown by ofCalendarField");
3334             isException = true;
3335         }
3336         if (!isException) {
3337             errln("FAIL: IllegalArgumentException must be thrown by ofCalendarField for calendar field value -1");
3338         }
3339
3340         // ChineseDateFormat.Field#ofCalendarField and getCalendarField
3341         int ccalField = ChineseDateFormat.Field.IS_LEAP_MONTH.getCalendarField();
3342         if (ccalField != ChineseCalendar.IS_LEAP_MONTH) {
3343             errln("FAIL: ChineseCalendar field " + ccalField + " is returned for ChineseDateFormat.Field.IS_LEAP_MONTH.getCalendarField()");
3344         } else {
3345             DateFormat.Field cfield = ChineseDateFormat.Field.ofCalendarField(ccalField);
3346             if (cfield != ChineseDateFormat.Field.IS_LEAP_MONTH) {
3347                 errln("FAIL: " + cfield + " is returned for a ChineseCalendar field " + ccalField
3348                         + " - Expected: " + ChineseDateFormat.Field.IS_LEAP_MONTH);
3349             }
3350         }
3351     }
3352 //#endif
3353
3354     /*
3355      * Test for checking SimpleDateFormat/DateFormatSymbols creation
3356      * honor the calendar keyword in the given locale.  See ticket#6100
3357      */
3358     public void TestCalendarType() {
3359         final String testPattern = "GGGG y MMMM d EEEE";
3360
3361         final ULocale[] testLocales = {
3362                 new ULocale("de"),
3363                 new ULocale("fr_FR@calendar=gregorian"),
3364                 new ULocale("en@calendar=islamic"),
3365                 new ULocale("ja_JP@calendar=japanese"),
3366                 new ULocale("zh_Hans_CN@calendar=bogus"),
3367         };
3368
3369         SimpleDateFormat[] formatters = new SimpleDateFormat[5];
3370         for (int i = 0; i < testLocales.length; i++) {
3371             // Create a locale with no keywords
3372             StringBuffer locStrBuf = new StringBuffer();
3373             if (testLocales[i].getLanguage().length() > 0) {
3374                 locStrBuf.append(testLocales[i].getLanguage());
3375             }
3376             if (testLocales[i].getScript().length() > 0) {
3377                 locStrBuf.append('_');
3378                 locStrBuf.append(testLocales[i].getScript());
3379             }
3380             if (testLocales[i].getCountry().length() > 0) {
3381                 locStrBuf.append('_');
3382                 locStrBuf.append(testLocales[i].getCountry());
3383             }
3384             ULocale locNoKeywords = new ULocale(locStrBuf.toString());
3385
3386             Calendar cal = Calendar.getInstance(testLocales[i]);
3387
3388             // Calendar getDateFormat method
3389             DateFormat df = cal.getDateTimeFormat(DateFormat.MEDIUM, DateFormat.MEDIUM, locNoKeywords);
3390             if (df instanceof SimpleDateFormat) {
3391                 formatters[0] = (SimpleDateFormat)df;
3392                 formatters[0].applyPattern(testPattern);
3393             } else {
3394                 formatters[0] = null;
3395             }
3396
3397             // DateFormat constructor with locale
3398             df = DateFormat.getDateInstance(DateFormat.MEDIUM, testLocales[i]);
3399             if (df instanceof SimpleDateFormat) {
3400                 formatters[1] = (SimpleDateFormat)df;
3401                 formatters[1].applyPattern(testPattern);
3402             } else {
3403                 formatters[1] = null;
3404             }
3405
3406             // DateFormat constructor with Calendar
3407             df = DateFormat.getDateInstance(cal, DateFormat.MEDIUM, locNoKeywords);
3408             if (df instanceof SimpleDateFormat) {
3409                 formatters[2] = (SimpleDateFormat)df;
3410                 formatters[2].applyPattern(testPattern);
3411             } else {
3412                 formatters[2] = null;
3413             }
3414
3415             // SimpleDateFormat constructor
3416             formatters[3] = new SimpleDateFormat(testPattern, testLocales[i]);
3417  
3418             // SimpleDateFormat with DateFormatSymbols
3419             DateFormatSymbols dfs = new DateFormatSymbols(testLocales[i]);
3420             formatters[4] = new SimpleDateFormat(testPattern, dfs, testLocales[i]);
3421
3422             // All SimpleDateFormat instances should produce the exact
3423             // same result.
3424             String expected = null;
3425             Date d = new Date();
3426             for (int j = 0; j < formatters.length; j++) {
3427                 if (formatters[j] != null) {
3428                     String tmp = formatters[j].format(d);
3429                     if (expected == null) {
3430                         expected = tmp;
3431                     } else if (!expected.equals(tmp)) {
3432                         errln("FAIL: formatter[" + j + "] returned \"" + tmp + "\" in locale " +
3433                                 testLocales[i] + " - expected: " + expected);
3434                     }
3435                 }
3436             }
3437         }
3438     }
3439
3440     /*
3441      * Test for format/parse method with calendar which is different
3442      * from what DateFormat instance internally use.  See ticket#6420.
3443      */
3444     public void TestRoundtripWithCalendar() {
3445         TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
3446         TimeZone gmt = TimeZone.getTimeZone("Etc/GMT");
3447
3448         final Calendar[] calendars = {
3449             new GregorianCalendar(tz),
3450             new BuddhistCalendar(tz),
3451             new HebrewCalendar(tz),
3452             new IslamicCalendar(tz),
3453             new JapaneseCalendar(tz),
3454         };
3455
3456         final String pattern = "GyMMMMdEEEEHHmmssVVVV";
3457
3458         //FIXME The formatters commented out below are currently failing because of
3459         // the calendar calculation problem reported by #6691
3460
3461         // The order of test formatters mus match the order of calendars above.
3462         final DateFormat[] formatters = {
3463             DateFormat.getPatternInstance(pattern, new ULocale("en_US")), //calendar=gregorian
3464             DateFormat.getPatternInstance(pattern, new ULocale("th_TH")), //calendar=buddhist
3465             DateFormat.getPatternInstance(pattern, new ULocale("he_IL@calendar=hebrew")),
3466 //            DateFormat.getPatternInstance(pattern, new ULocale("ar_EG@calendar=islamic")),
3467 //            DateFormat.getPatternInstance(pattern, new ULocale("ja_JP@calendar=japanese")),
3468         };
3469
3470         Date d = new Date();
3471         StringBuffer buf = new StringBuffer();
3472         FieldPosition fpos = new FieldPosition(0);
3473         ParsePosition ppos = new ParsePosition(0);
3474
3475         for (int i = 0; i < formatters.length; i++) {
3476             buf.setLength(0);
3477             fpos.setBeginIndex(0);
3478             fpos.setEndIndex(0);
3479             calendars[i].setTime(d);
3480
3481             // Normal case output - the given calendar matches the calendar
3482             // used by the formatter
3483             formatters[i].format(calendars[i], buf, fpos);
3484             String refStr = buf.toString();
3485
3486             for (int j = 0; j < calendars.length; j++) {
3487                 if (j == i) {
3488                     continue;
3489                 }
3490                 buf.setLength(0);
3491                 fpos.setBeginIndex(0);
3492                 fpos.setEndIndex(0);
3493                 calendars[j].setTime(d);
3494
3495                 // Even the different calendar type is specified,
3496                 // we should get the same result.
3497                 formatters[i].format(calendars[j], buf, fpos);
3498                 if (!refStr.equals(buf.toString())) {
3499                     errln("FAIL: Different format result with a different calendar for the same time -"
3500                             + "\n Reference calendar type=" + calendars[i].getType()
3501                             + "\n Another calendar type=" + calendars[j].getType()
3502                             + "\n Expected result=" + refStr
3503                             + "\n Actual result=" + buf.toString());
3504                 }
3505             }
3506
3507             calendars[i].setTimeZone(gmt);
3508             calendars[i].clear();
3509             ppos.setErrorIndex(-1);
3510             ppos.setIndex(0);
3511
3512             // Normal case parse result - the given calendar matches the calendar
3513             // used by the formatter
3514             formatters[i].parse(refStr, calendars[i], ppos);
3515
3516             for (int j = 0; j < calendars.length; j++) {
3517                 if (j == i) {
3518                     continue;
3519                 }
3520                 calendars[j].setTimeZone(gmt);
3521                 calendars[j].clear();
3522                 ppos.setErrorIndex(-1);
3523                 ppos.setIndex(0);
3524
3525                 // Even the different calendar type is specified,
3526                 // we should get the same time and time zone.
3527                 formatters[i].parse(refStr, calendars[j], ppos);
3528                 if (calendars[i].getTimeInMillis() != calendars[j].getTimeInMillis()
3529                         || !calendars[i].getTimeZone().equals(calendars[j].getTimeZone())) {
3530                     errln("FAIL: Different parse result with a different calendar for the same string -"
3531                             + "\n Reference calendar type=" + calendars[i].getType()
3532                             + "\n Another calendar type=" + calendars[j].getType()
3533                             + "\n Date string=" + refStr
3534                             + "\n Expected time=" + calendars[i].getTimeInMillis()
3535                             + "\n Expected time zone=" + calendars[i].getTimeZone().getID()
3536                             + "\n Actual time=" + calendars[j].getTimeInMillis()
3537                             + "\n Actual time zone=" + calendars[j].getTimeZone().getID());
3538                 }
3539             }
3540         }
3541     }
3542
3543     // based on TestRelativeDateFormat() in icu/trunk/source/test/cintltst/cdattst.c
3544     public void TestRelativeDateFormat() {
3545         ULocale loc = ULocale.US;
3546         TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
3547         Calendar cal = new GregorianCalendar(tz, loc);
3548         Date now = new Date();
3549         cal.setTime(now);
3550         cal.set(Calendar.HOUR_OF_DAY, 18);
3551         cal.set(Calendar.MINUTE, 49);
3552         cal.set(Calendar.SECOND, 0);
3553         Date today = cal.getTime();
3554         String minutesStr = "49"; // minutes string to search for in formatted result
3555         int[] dateStylesList = { DateFormat.RELATIVE_FULL, DateFormat.RELATIVE_LONG, DateFormat.RELATIVE_MEDIUM, DateFormat.RELATIVE_SHORT };
3556
3557         for (int i = 0; i < dateStylesList.length; i++) {
3558             int dateStyle = dateStylesList[i];
3559             DateFormat fmtRelDateTime = DateFormat.getDateTimeInstance(dateStyle, DateFormat.SHORT, loc);
3560             DateFormat fmtRelDate = DateFormat.getDateInstance(dateStyle, loc);
3561             DateFormat fmtTime = DateFormat.getTimeInstance(DateFormat.SHORT, loc);
3562
3563             for (int dayOffset = -2; dayOffset <= 2; dayOffset++ ) {
3564                 StringBuffer dateTimeStr = new StringBuffer(64);
3565                 StringBuffer dateStr = new StringBuffer(64);
3566                 StringBuffer timeStr = new StringBuffer(64);
3567                 FieldPosition fp = new FieldPosition(DateFormat.MINUTE_FIELD);
3568                 cal.setTime(today);
3569                 cal.add(Calendar.DATE, dayOffset);
3570
3571                 fmtRelDateTime.format(cal, dateTimeStr, fp);
3572                 fmtRelDate.format(cal, dateStr, new FieldPosition(0) );
3573                 fmtTime.format(cal, timeStr, new FieldPosition(0) );
3574
3575                 // check that dateStr is in dateTimeStr
3576                 if ( dateTimeStr.toString().indexOf( dateStr.toString() ) < 0 ) {
3577                     errln("relative date string not found in datetime format with timeStyle SHORT, dateStyle " +
3578                             dateStyle + " for dayOffset " + dayOffset );
3579                     errln("datetime format is " + dateTimeStr.toString() + ", date string is " + dateStr.toString() );
3580                 }
3581                 // check that timeStr is in dateTimeStr
3582                 if ( dateTimeStr.toString().indexOf( timeStr.toString() ) < 0 ) {
3583                     errln("short time string not found in datetime format with timeStyle SHORT, dateStyle " +
3584                             dateStyle + " for dayOffset " + dayOffset );
3585                     errln("datetime format is " + dateTimeStr.toString() + ", time string is " + timeStr.toString() );
3586                 }
3587                 // check index of minutesStr
3588                 int minutesStrIndex = dateTimeStr.toString().indexOf( minutesStr );
3589                 if ( fp.getBeginIndex() != minutesStrIndex ) {
3590                     errln("FieldPosition beginIndex " + fp.getBeginIndex() + " instead of " + minutesStrIndex + " for datetime format with timeStyle SHORT, dateStyle " +
3591                             dateStyle + " for dayOffset " + dayOffset );
3592                     errln("datetime format is " + dateTimeStr.toString() );
3593                 }
3594             }
3595         }
3596     }
3597
3598     public void Test6880() {
3599         Date d1, d2, dp1, dp2, dexp1, dexp2;
3600         String s1, s2;
3601
3602         TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
3603         GregorianCalendar gcal = new GregorianCalendar(tz);
3604
3605         gcal.clear();
3606         gcal.set(1910, Calendar.JANUARY, 1, 12, 00);    // offset 8:05:52
3607         d1 = gcal.getTime();
3608
3609         gcal.clear();
3610         gcal.set(1950, Calendar.JANUARY, 1, 12, 00);    // offset 8:00
3611         d2 = gcal.getTime();
3612
3613         gcal.clear();
3614         gcal.set(1970, Calendar.JANUARY, 1, 12, 00);
3615         dexp2 = gcal.getTime();
3616         dexp1 = new Date(dexp2.getTime() - (5*60 + 52)*1000);   // subtract 5m52s
3617
3618         DateFormat fmt = DateFormat.getTimeInstance(DateFormat.FULL, new ULocale("zh"));
3619         fmt.setTimeZone(tz);
3620
3621         s1 = fmt.format(d1);
3622         s2 = fmt.format(d2);
3623
3624         try {
3625             dp1 = fmt.parse(s1);
3626             dp2 = fmt.parse(s2);
3627
3628             if (!dp1.equals(dexp1)) {
3629                 errln("FAIL: Failed to parse " + s1 + " parsed: " + dp1 + " expected: " + dexp1);
3630             }
3631             if (!dp2.equals(dexp2)) {
3632                 errln("FAIL: Failed to parse " + s2 + " parsed: " + dp2 + " expected: " + dexp2);
3633             }
3634         } catch (ParseException pe) {
3635             errln("FAIL: Parse failure");
3636         }
3637     }
3638 }