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