]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / tests / core / src / com / ibm / icu / dev / test / format / DateTimeGeneratorTest.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2006-2010, Google, International Business Machines Corporation *\r
4  * and others. All Rights Reserved.                                            *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 package com.ibm.icu.dev.test.format;\r
9 \r
10 import java.text.ParsePosition;\r
11 import java.util.Collection;\r
12 import java.util.Date;\r
13 import java.util.HashSet;\r
14 import java.util.Iterator;\r
15 import java.util.LinkedHashMap;\r
16 import java.util.LinkedHashSet;\r
17 import java.util.List;\r
18 import java.util.Map;\r
19 import java.util.Random;\r
20 import java.util.Set;\r
21 \r
22 import com.ibm.icu.dev.test.TestFmwk;\r
23 import com.ibm.icu.impl.PatternTokenizer;\r
24 import com.ibm.icu.impl.Utility;\r
25 import com.ibm.icu.text.DateFormat;\r
26 import com.ibm.icu.text.DateTimePatternGenerator;\r
27 import com.ibm.icu.text.SimpleDateFormat;\r
28 import com.ibm.icu.text.UTF16;\r
29 import com.ibm.icu.text.UnicodeSet;\r
30 import com.ibm.icu.text.DateTimePatternGenerator.FormatParser;\r
31 import com.ibm.icu.text.DateTimePatternGenerator.VariableField;\r
32 import com.ibm.icu.util.Calendar;\r
33 import com.ibm.icu.util.GregorianCalendar;\r
34 import com.ibm.icu.util.SimpleTimeZone;\r
35 import com.ibm.icu.util.TimeZone;\r
36 import com.ibm.icu.util.ULocale;\r
37 \r
38 public class DateTimeGeneratorTest extends TestFmwk {\r
39     public static boolean GENERATE_TEST_DATA;\r
40     static {\r
41         try {\r
42             GENERATE_TEST_DATA = System.getProperty("GENERATE_TEST_DATA") != null;\r
43         } catch (SecurityException e) {\r
44             GENERATE_TEST_DATA = false;\r
45         }\r
46     };\r
47     public static int RANDOM_COUNT = 1000;\r
48     public static boolean DEBUG = false;\r
49     \r
50     public static void main(String[] args) throws Exception {\r
51         new DateTimeGeneratorTest().run(args);\r
52     }\r
53     \r
54     public void TestSimple() {\r
55         // some simple use cases\r
56         ULocale locale = ULocale.GERMANY;\r
57         TimeZone zone = TimeZone.getTimeZone("Europe/Paris");\r
58         \r
59         // make from locale\r
60         DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(locale);\r
61         SimpleDateFormat format = new SimpleDateFormat(gen.getBestPattern("MMMddHmm"), locale);\r
62         format.setTimeZone(zone);\r
63         assertEquals("simple format: MMMddHmm", "14. Okt 08:58", format.format(sampleDate)); // (fixed expected result per ticket 6872<-7180)\r
64         // (a generator can be built from scratch, but that is not a typical use case)\r
65 \r
66         // modify the generator by adding patterns\r
67         DateTimePatternGenerator.PatternInfo returnInfo = new DateTimePatternGenerator.PatternInfo();\r
68         gen.addPattern("d'. von' MMMM", true, returnInfo); \r
69         // the returnInfo is mostly useful for debugging problem cases\r
70         format.applyPattern(gen.getBestPattern("MMMMdHmm"));\r
71         assertEquals("modified format: MMMdHmm", "14. von Oktober 08:58", format.format(sampleDate)); // (fixed expected result per ticket 6872<-7180)\r
72 \r
73         // get a pattern and modify it\r
74         format = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);\r
75         format.setTimeZone(zone);\r
76         String pattern = format.toPattern();\r
77         assertEquals("full-date", "Donnerstag, 14. Oktober 1999 08:58:59 Mitteleurop\u00E4ische Sommerzeit", format.format(sampleDate));\r
78 \r
79         // modify it to change the zone.\r
80         String newPattern = gen.replaceFieldTypes(pattern, "vvvv");\r
81         format.applyPattern(newPattern);\r
82         assertEquals("full-date: modified zone", "Donnerstag, 14. Oktober 1999 08:58:59 (Frankreich)", format.format(sampleDate));\r
83         \r
84         // add test of basic cases\r
85 \r
86         //lang  YYYYMMM MMMd    MMMdhmm hmm hhmm    Full Date-Time\r
87         // en  Mar 2007    Mar 4   6:05 PM Mar 4   6:05 PM 06:05 PM    Sunday, March 4, 2007 6:05:05 PM PT\r
88         DateTimePatternGenerator enGen = DateTimePatternGenerator.getInstance(ULocale.ENGLISH);\r
89         TimeZone enZone = TimeZone.getTimeZone("Etc/GMT");\r
90         SimpleDateFormat enFormat = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, ULocale.ENGLISH);\r
91         enFormat.setTimeZone(enZone);\r
92         String[][] tests = {\r
93               {"yyyyMMMdd", "Oct 14, 1999"},\r
94               {"yyyyqqqq", "4th quarter 1999"},\r
95               {"yMMMdd", "Oct 14, 1999"},\r
96               {"EyyyyMMMdd", "Thu, Oct 14, 1999"},\r
97               {"yyyyMMdd", "10/14/1999"},\r
98               {"yyyyMMM", "Oct 1999"},\r
99               {"yyyyMM", "10/1999"},\r
100               {"yyMM", "10/99"},\r
101               {"yMMMMMd", "O 14, 1999"},  // narrow format\r
102               {"EEEEEMMMMMd", "T, O 14"},  // narrow format\r
103               {"MMMd", "Oct 14"},\r
104               {"MMMdhmm", "Oct 14 6:58 AM"},\r
105               {"EMMMdhmms", "Thu, Oct 14 6:58:59 AM"},\r
106               {"MMdhmm", "10/14 6:58 AM"},\r
107               {"EEEEMMMdhmms", "Thursday, Oct 14 6:58:59 AM"},\r
108               {"yyyyMMMddhhmmss", "Oct 14, 1999 6:58:59 AM"}, // (fixed expected result per ticket 6872<-7180)\r
109               {"EyyyyMMMddhhmmss", "Thu, Oct 14, 1999 6:58:59 AM"}, // (fixed expected result per ticket 6872<-7180)\r
110               {"hmm", "6:58 AM"},\r
111               {"hhmm", "6:58 AM"}, // (fixed expected result per ticket 6872<-7180)\r
112               {"hhmmVVVV", "6:58 AM GMT+00:00"}, // (fixed expected result per ticket 6872<-7180)\r
113         };\r
114         for (int i = 0; i < tests.length; ++i) {\r
115             final String testSkeleton = tests[i][0];\r
116             String pat = enGen.getBestPattern(testSkeleton);\r
117             enFormat.applyPattern(pat);\r
118             String formattedDate = enFormat.format(sampleDate);\r
119             assertEquals("Testing skeleton '" + testSkeleton + "' with  " + sampleDate, tests[i][1], formattedDate);\r
120         }\r
121     }\r
122 \r
123     public void TestRoot() {\r
124         DateTimePatternGenerator rootGen = DateTimePatternGenerator.getInstance(ULocale.ROOT);\r
125         SimpleDateFormat rootFormat = new SimpleDateFormat(rootGen.getBestPattern("yMdHms"), ULocale.ROOT);\r
126         rootFormat.setTimeZone(gmt);\r
127         // *** expected result should be "1999-10-14 6:58:59" with current data, changed test temporarily to match current result, needs investigation\r
128         assertEquals("root format: yMdHms", "1999-10-14 06:58:59", rootFormat.format(sampleDate)); \r
129     }\r
130     \r
131     public void TestEmpty() {\r
132         // now nothing\r
133         DateTimePatternGenerator nullGen = DateTimePatternGenerator.getEmptyInstance();\r
134         SimpleDateFormat format = new SimpleDateFormat(nullGen.getBestPattern("yMdHms"), ULocale.ROOT);\r
135         TimeZone rootZone = TimeZone.getTimeZone("Etc/GMT");\r
136         format.setTimeZone(rootZone);\r
137     }\r
138 \r
139     public void TestPatternParser() {\r
140         StringBuffer buffer = new StringBuffer();\r
141         PatternTokenizer pp = new PatternTokenizer()\r
142         .setIgnorableCharacters(new UnicodeSet("[-]"))\r
143         .setSyntaxCharacters(new UnicodeSet("[a-zA-Z]"))\r
144         .setEscapeCharacters(new UnicodeSet("[b#]"))\r
145         .setUsingQuote(true);\r
146         logln("Using Quote");\r
147         for (int i = 0; i < patternTestData.length; ++i) {\r
148             String patternTest = (String) patternTestData[i];\r
149             CheckPattern(buffer, pp, patternTest);\r
150         }\r
151         String[] randomSet = {"abcdef", "$12!@#-", "'\\"};\r
152         for (int i = 0; i < RANDOM_COUNT; ++i) {\r
153             String patternTest = getRandomString(randomSet, 0, 10);\r
154             CheckPattern(buffer, pp, patternTest);\r
155         }\r
156         logln("Using Backslash");\r
157         pp.setUsingQuote(false).setUsingSlash(true);\r
158         for (int i = 0; i < patternTestData.length; ++i) {\r
159             String patternTest = (String) patternTestData[i];\r
160             CheckPattern(buffer, pp, patternTest);\r
161         }\r
162         for (int i = 0; i < RANDOM_COUNT; ++i) {\r
163             String patternTest = getRandomString(randomSet, 0, 10);\r
164             CheckPattern(buffer, pp, patternTest);\r
165         }\r
166     }\r
167     \r
168     Random random = new java.util.Random(-1);\r
169     \r
170     private String getRandomString(String[] randomList, int minLen, int maxLen) {\r
171         StringBuffer result = new StringBuffer();\r
172         int len = random.nextInt(maxLen + 1 - minLen) + minLen;\r
173         for (int i = minLen; i < len; ++ i) {\r
174             String source = randomList[random.nextInt(randomList.length)]; // don't bother with surrogates\r
175             char ch = source.charAt(random.nextInt(source.length()));\r
176             UTF16.append(result, ch);\r
177         }\r
178         return result.toString();\r
179     }\r
180     \r
181     private void CheckPattern(StringBuffer buffer, PatternTokenizer pp, String patternTest) {\r
182         pp.setPattern(patternTest);\r
183         if (DEBUG && isVerbose()) {\r
184             showItems(buffer, pp, patternTest);\r
185         }\r
186         String normalized = pp.setStart(0).normalize();\r
187         logln("input:\t<" + patternTest + ">" + "\tnormalized:\t<" + normalized + ">");\r
188         String doubleNormalized = pp.setPattern(normalized).normalize();\r
189         if (!normalized.equals(doubleNormalized)) {\r
190             errln("Normalization not idempotent:\t" + patternTest + "\tnormalized: " + normalized +  "\tnormalized2: " + doubleNormalized);\r
191             // allow for debugging at the point of failure\r
192             if (DEBUG) {\r
193                 pp.setPattern(patternTest);\r
194                 normalized = pp.setStart(0).normalize();\r
195                 pp.setPattern(normalized);\r
196                 showItems(buffer, pp, normalized);\r
197                 doubleNormalized = pp.normalize();\r
198             }\r
199         }\r
200     }\r
201 \r
202     private void showItems(StringBuffer buffer, PatternTokenizer pp, String patternTest) {\r
203         logln("input:\t<" + patternTest + ">");\r
204         while (true) {\r
205             buffer.setLength(0);\r
206             int status = pp.next(buffer);\r
207             if (status == PatternTokenizer.DONE) break;\r
208             String lit = "";\r
209             if (status != PatternTokenizer.SYNTAX ) {\r
210                 lit = "\t<" + pp.quoteLiteral(buffer) + ">";\r
211             }\r
212             logln("\t" + statusName[status] + "\t<" + buffer + ">" + lit);\r
213         }\r
214     }\r
215     \r
216     static final String[] statusName = {"DONE", "SYNTAX", "LITERAL", "BROKEN_QUOTE", "BROKEN_ESCAPE", "UNKNOWN"};\r
217     \r
218     public void TestBasic() {\r
219         ULocale uLocale = null;\r
220         DateTimePatternGenerator dtfg = null;\r
221         Date date = null;\r
222         for (int i = 0; i < dateTestData.length; ++i) {\r
223             if (dateTestData[i] instanceof ULocale) {\r
224                 uLocale = (ULocale) dateTestData[i];\r
225                 dtfg = DateTimePatternGenerator.getInstance(uLocale);\r
226                 if (GENERATE_TEST_DATA) logln("new ULocale(\"" + uLocale.toString() + "\"),");\r
227             } else if (dateTestData[i] instanceof Date) {\r
228                 date = (Date) dateTestData[i];\r
229                 if (GENERATE_TEST_DATA) logln("new Date(" + date.getTime()+ "L),");\r
230             } else if (dateTestData[i] instanceof String) {\r
231                 String testSkeleton = (String) dateTestData[i];\r
232                 String pattern = dtfg.getBestPattern(testSkeleton);\r
233                 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale);\r
234                 String formatted = sdf.format(date);\r
235                 if (GENERATE_TEST_DATA) logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},");\r
236                 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date));\r
237             } else {\r
238                 String[] testPair = (String[]) dateTestData[i];\r
239                 String testSkeleton = testPair[0];\r
240                 String testFormatted = testPair[1];\r
241                 String pattern = dtfg.getBestPattern(testSkeleton);\r
242                 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale);\r
243                 String formatted = sdf.format(date);\r
244                 if (GENERATE_TEST_DATA) {\r
245                     logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},");\r
246                 } else if (!formatted.equals(testFormatted)) {\r
247                     errln(uLocale + "\tformatted string doesn't match test case: " + testSkeleton + "\t generated: " +  pattern + "\t expected: " + testFormatted + "\t got: " + formatted);\r
248                     if (true) { // debug\r
249                         pattern = dtfg.getBestPattern(testSkeleton);\r
250                         sdf = new SimpleDateFormat(pattern, uLocale);\r
251                         formatted = sdf.format(date);\r
252                     }\r
253                 }\r
254                 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date));\r
255             }\r
256         }\r
257     }\r
258     \r
259     static final Object[] patternTestData = {\r
260         "'$f''#c",\r
261         "'' 'a",\r
262         "'.''.'",\r
263         "\\u0061\\\\",\r
264         "mm.dd 'dd ' x",\r
265         "'' ''",\r
266     };\r
267     \r
268     // can be generated by using GENERATE_TEST_DATA. Must be reviewed before adding\r
269     static final Object[] dateTestData = {\r
270         new Date(916300739000L), // 1999-01-13T23:58:59,0-0800\r
271         new ULocale("en_US"),\r
272         new String[] {"yM", "1/1999"},\r
273         new String[] {"yMMM", "Jan 1999"},\r
274         new String[] {"yMd", "1/13/1999"},\r
275         new String[] {"yMMMd", "Jan 13, 1999"},\r
276         new String[] {"Md", "1/13"},\r
277         new String[] {"MMMd", "Jan 13"},\r
278         new String[] {"yQQQ", "Q1 1999"},\r
279         new String[] {"hhmm", "11:58 PM"},\r
280         new String[] {"HHmm", "23:58"},\r
281         new String[] {"jjmm", "11:58 PM"},\r
282         new String[] {"mmss", "58:59"},\r
283         new String[] {"yyyyMMMM", "January 1999"}, // (new item for testing 6872<-5702)\r
284         new ULocale("en_US@calendar=japanese"), // (new locale for testing ticket 6872<-5702)\r
285         new String[] {"yM", "H 11-01"},\r
286         new String[] {"yMMM", "H 11 Jan"},\r
287         new String[] {"yMd", "H 11-01-13"},\r
288         new String[] {"yMMMd", "H 11 Jan 13"},\r
289         new String[] {"Md", "1-13"},\r
290         new String[] {"MMMd", "Jan 13"},\r
291         new String[] {"yQQQ", "H 11 Q1"},\r
292         new String[] {"hhmm", "11:58 PM"},\r
293         new String[] {"HHmm", "23:58"},\r
294         new String[] {"jjmm", "23:58"},\r
295         new String[] {"mmss", "58:59"},\r
296         new String[] {"yyyyMMMM", "H 11 January"},\r
297         new ULocale("zh_Hans_CN"),\r
298         new String[] {"yM", "1999-1"},\r
299         new String[] {"yMMM", "1999\u5E741\u6708"}, // (fixed expected result per ticket 6872<-6626)\r
300         new String[] {"yMd", "1999\u5E741\u670813\u65E5"},\r
301         new String[] {"yMMMd", "1999\u5E741\u670813\u65E5"}, // (fixed expected result per ticket 6872<-6626)\r
302         new String[] {"Md", "1-13"},\r
303         new String[] {"MMMd", "1\u670813\u65E5"}, // (fixed expected result per ticket 6872<-6626)\r
304         new String[] {"yQQQ", "1999\u5E741\u5B63"},\r
305         new String[] {"hhmm", "\u4E0B\u534811:58"},\r
306         new String[] {"HHmm", "23:58"},\r
307         new String[] {"jjmm", "\u4E0B\u534811:58"},\r
308         new String[] {"mmss", "58:59"},\r
309         new String[] {"yyyyMMMM", "1999\u5E741\u6708"}, // (new item for testing 6872<-5702)\r
310         new ULocale("de_DE"),\r
311         new String[] {"yM", "1.1999"},\r
312         new String[] {"yMMM", "Jan 1999"},\r
313         new String[] {"yMd", "13.1.1999"},\r
314         new String[] {"yMMMd", "13. Jan 1999"},\r
315         new String[] {"Md", "13.1."},   // 13.1\r
316         new String[] {"MMMd", "13. Jan"},\r
317         new String[] {"yQQQ", "Q1 1999"},\r
318         new String[] {"hhmm", "11:58 nachm."},\r
319         new String[] {"HHmm", "23:58"},\r
320         new String[] {"jjmm", "23:58"},\r
321         new String[] {"mmss", "58:59"},\r
322         new String[] {"yyyyMMMM", "Januar 1999"}, // (new item for testing 6872<-5702)\r
323         new ULocale("fi"),\r
324         new String[] {"yM", "1.1999"}, // (fixed expected result per ticket 6872<-6626)\r
325         new String[] {"yMMM", "tammi 1999"}, // (fixed expected result per ticket 6872<-7007)\r
326         new String[] {"yMd", "13.1.1999"},\r
327         new String[] {"yMMMd", "13. tammikuuta 1999"},\r
328         new String[] {"Md", "13.1."},\r
329         new String[] {"MMMd", "13. tammikuuta"},\r
330         new String[] {"yQQQ", "1. nelj./1999"}, // 1. nelj. 1999 // *** get "expected result" but it seems incorrect, needs investigation\r
331         new String[] {"hhmm", "11.58 ip."},\r
332         new String[] {"HHmm", "23.58"},\r
333         new String[] {"jjmm", "23.58"},\r
334         new String[] {"mmss", "58.59"},\r
335         new String[] {"yyyyMMMM", "tammikuu 1999"}, // (new item for testing 6872<-5702,7007)\r
336         new ULocale("ja"), // (new locale for testing ticket 6872<-6626)\r
337         new String[] {"yM", "1999/1"},\r
338         new String[] {"yMMM", "1999\u5E741\u6708"},\r
339         new String[] {"yMd", "1999\u5E741\u670813\u65E5"}, // *** expected result should be "1999/1/13" with current data, changed test temporarily to match current result, needs investigation\r
340         new String[] {"yMMMd", "1999\u5E741\u670813\u65E5"},\r
341         new String[] {"Md", "1/13"},\r
342         new String[] {"MMMd", "1\u670813\u65E5"},\r
343         new String[] {"yQQQ", "1999/Q1"}, // *** expected result should be "1999Q1" with current data, changed test temporarily to match current result, needs investigation\r
344         new String[] {"hhmm", "\u5348\u5F8C11:58"},\r
345         new String[] {"HHmm", "23:58"},\r
346         new String[] {"jjmm", "23:58"},\r
347         new String[] {"mmss", "58:59"},\r
348         new String[] {"yyyyMMMM", "1999\u5E741\u6708"}, // (new item for testing 6872<-5702)\r
349         new ULocale("ja@calendar=japanese"), // (new locale for testing ticket 6872<-5702)\r
350         new String[] {"yM", "\u5E73\u621011/1"},\r
351         new String[] {"yMMM", "\u5E73\u621011\u5E741\u6708"},\r
352         new String[] {"yMd", "\u5E73\u621011/1/13"},\r
353         new String[] {"yMMMd", "\u5E73\u621011\u5E741\u670813\u65E5"},\r
354         new String[] {"Md", "1/13"},\r
355         new String[] {"MMMd", "1\u670813\u65E5"},\r
356         new String[] {"yQQQ", "\u5E73\u621011/Q1"},\r
357         new String[] {"hhmm", "\u5348\u5F8C11:58"},\r
358         new String[] {"HHmm", "23:58"},\r
359         new String[] {"jjmm", "23:58"},\r
360         new String[] {"mmss", "58:59"},\r
361         new String[] {"yyyyMMMM", "\u5E73\u621011\u5E741\u6708"},\r
362         new ULocale("zh_TW@calendar=roc"), // (new locale for testing ticket 6872<-5702)\r
363         new String[] {"yM", "\u6C11\u570B88/1"},\r
364         new String[] {"yMMM", "\u6C11\u570B88\u5E741\u6708"},\r
365         new String[] {"yMd", "\u6C11\u570B88/1/13"},\r
366         new String[] {"yMMMd", "\u6C11\u570B88\u5E741\u670813\u65E5"},\r
367         new String[] {"Md", "1/13"},\r
368         new String[] {"MMMd", "1\u670813\u65E5"},\r
369         new String[] {"yQQQ", "\u6C11\u570B88 1\u5B63"},\r
370         new String[] {"hhmm", "\u4E0B\u534811:58"},\r
371         new String[] {"HHmm", "23:58"},\r
372         new String[] {"jjmm", "\u4E0B\u534811:58"},\r
373         new String[] {"mmss", "58:59"},\r
374         new String[] {"yyyyMMMM", "\u6C11\u570B88\u5E741\u6708"},\r
375     };\r
376     \r
377     public void DayMonthTest() {\r
378         final ULocale locale = ULocale.FRANCE;\r
379         \r
380         // set up the generator\r
381         DateTimePatternGenerator dtpgen\r
382           = DateTimePatternGenerator.getInstance(locale);\r
383         \r
384         // get a pattern for an abbreviated month and day\r
385         final String pattern = dtpgen.getBestPattern("MMMd");\r
386         SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale);\r
387         \r
388         // use it to format (or parse)\r
389         String formatted = formatter.format(new Date());\r
390         logln("formatted=" + formatted);\r
391         // for French, the result is "13 sept."\r
392     }\r
393     \r
394     public void TestOrdering() {\r
395         ULocale[] locales = ULocale.getAvailableLocales();\r
396         for (int i = 0; i < locales.length; ++i) {\r
397             for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) {\r
398                 for (int style2 = DateFormat.FULL; style2 < style1; ++style2) {\r
399                     checkCompatible(style1, style2, locales[i]);                    \r
400                 }\r
401             }\r
402         }\r
403     }\r
404     \r
405     public void TestReplacingZoneString() {\r
406         Date testDate = new Date();\r
407         TimeZone testTimeZone = TimeZone.getTimeZone("America/New_York");\r
408         TimeZone bogusTimeZone = new SimpleTimeZone(1234, "Etc/Unknown");\r
409         Calendar calendar = Calendar.getInstance();\r
410         ParsePosition parsePosition = new ParsePosition(0);\r
411 \r
412         ULocale[] locales = ULocale.getAvailableLocales();\r
413         int count = 0;\r
414         for (int i = 0; i < locales.length; ++i) {\r
415             // skip the country locales unless we are doing exhaustive tests\r
416             if (getInclusion() < 6) {\r
417                 if (locales[i].getCountry().length() > 0) {\r
418                     continue;\r
419                 }\r
420             }\r
421             count++;\r
422             // Skipping some test case in the non-exhaustive mode to reduce the test time\r
423             //ticket#6503\r
424             if(params.inclusion<=5 && count%3!=0){\r
425                 continue;\r
426             }\r
427             logln(locales[i].toString());\r
428             DateTimePatternGenerator dtpgen\r
429             = DateTimePatternGenerator.getInstance(locales[i]);\r
430             \r
431             for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) {\r
432                 final SimpleDateFormat oldFormat = (SimpleDateFormat) DateFormat.getTimeInstance(style1, locales[i]);\r
433                 String pattern = oldFormat.toPattern();\r
434                 String newPattern = dtpgen.replaceFieldTypes(pattern, "VVVV"); // replaceZoneString(pattern, "VVVV");\r
435                 if (newPattern.equals(pattern)) {\r
436                     continue;\r
437                 }\r
438                 // verify that it roundtrips parsing\r
439                 SimpleDateFormat newFormat = new SimpleDateFormat(newPattern, locales[i]);\r
440                 newFormat.setTimeZone(testTimeZone);\r
441                 String formatted = newFormat.format(testDate);\r
442                 calendar.setTimeZone(bogusTimeZone);\r
443                 parsePosition.setIndex(0);\r
444                 newFormat.parse(formatted, calendar, parsePosition);\r
445                 if (parsePosition.getErrorIndex() >= 0) {\r
446                     errln("Failed parse with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted.substring(0,parsePosition.getErrorIndex()) + "{}" + formatted.substring(parsePosition.getErrorIndex()) + "\"");\r
447                 } else if (!calendar.getTimeZone().getID().equals(testTimeZone.getID())) {\r
448                     errln("Failed timezone roundtrip with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted + "\",\t" + calendar.getTimeZone().getID() + " != " + testTimeZone.getID());\r
449                 } else {\r
450                     logln(locales[i] + ":\t\"" + pattern + "\" => \t\"" + newPattern + "\"\t" + formatted);\r
451                 }\r
452             }\r
453         }\r
454     }\r
455     \r
456     public void TestVariableCharacters() {\r
457         UnicodeSet valid = new UnicodeSet("[G   y   Y   u   Q   q   M   L   w   W   d   D   F   g   E   e   c   a   h   H   K   k   m   s   S   A   z   Z   v   V]");\r
458         for (char c = 0; c < 0xFF; ++c) {\r
459             boolean works = false;\r
460             try {\r
461                 VariableField vf = new VariableField(String.valueOf(c), true);\r
462                 logln("VariableField " + vf.toString());\r
463                 works = true;\r
464             } catch (Exception e) {}\r
465             if (works != valid.contains(c)) {\r
466                 if (works) {\r
467                     errln("VariableField can be created with illegal character: " + c);\r
468                 } else {\r
469                     errln("VariableField can't be created with legal character: " + c);\r
470                 }\r
471             }\r
472         }\r
473     }\r
474     \r
475     static String[] DATE_STYLE_NAMES = {\r
476         "FULL", "LONG", "MEDIUM", "SHORT"\r
477     };\r
478     \r
479     /**\r
480      * @param fullOrder\r
481      * @param longOrder\r
482      */\r
483     private void checkCompatible(int style1, int style2, ULocale uLocale) {\r
484         DateOrder order1 = getOrdering(style1, uLocale);\r
485         DateOrder order2 = getOrdering(style2, uLocale);\r
486         if (!order1.hasSameOrderAs(order2)) {\r
487             if (order1.monthLength == order2.monthLength) { // error if have same month length, different ordering\r
488                 if (skipIfBeforeICU(4,5,1)) { // ticket#6806\r
489                     logln(showOrderComparison(uLocale, style1, style2, order1, order2));\r
490                 } else {\r
491                     errln(showOrderComparison(uLocale, style1, style2, order1, order2));\r
492                 }\r
493             } else if (isVerbose() && order1.monthLength > 2 && order2.monthLength > 2) { // warn if both are not numeric\r
494                 logln(showOrderComparison(uLocale, style1, style2, order1, order2));\r
495             }\r
496         }\r
497     }\r
498 \r
499     private String showOrderComparison(ULocale uLocale, int style1, int style2, DateOrder order1, DateOrder order2) {\r
500         String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(style1, uLocale)).toPattern();\r
501         String pattern2 = ((SimpleDateFormat) DateFormat.getDateInstance(style2, uLocale)).toPattern();\r
502         return "Mismatch in in ordering for " + uLocale + ": " + DATE_STYLE_NAMES[style1] + ": " + order1 + ", <" + pattern1 \r
503                 + ">; " \r
504                 + DATE_STYLE_NAMES[style2] + ": " + order2 + ", <" + pattern2 + ">; " ;\r
505     }\r
506 \r
507     /**\r
508      * Main date fields -- Poor-man's enum -- change to real enum when we get JDK 1.5\r
509      */\r
510     public static class DateFieldType {\r
511         private String name;\r
512         private DateFieldType(String string) {\r
513             name = string;\r
514         }\r
515         \r
516         public static DateFieldType \r
517         YEAR = new DateFieldType("YEAR"), \r
518         MONTH = new DateFieldType("MONTH"), \r
519         DAY = new DateFieldType("DAY");\r
520         \r
521         public String toString() {\r
522             return name;\r
523         }\r
524     }\r
525     \r
526     /**\r
527      * Simple struct for output from getOrdering\r
528      */\r
529     static class DateOrder {\r
530         int monthLength;\r
531         DateFieldType[] fields = new DateFieldType[3];\r
532         \r
533         public boolean isCompatible(DateOrder other) {\r
534             return monthLength == other.monthLength;\r
535         }\r
536         /**\r
537          * @param order2\r
538          * @return\r
539          */\r
540         public boolean hasSameOrderAs(DateOrder other) {\r
541             // TODO Auto-generated method stub\r
542             return fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2];\r
543         }\r
544         public String toString() {\r
545             return "{" + monthLength + ", " + fields[0]  + ", " + fields[1]  + ", " + fields[2] + "}";\r
546         }\r
547         public boolean equals(Object that) {\r
548             DateOrder other = (DateOrder) that;\r
549             return monthLength == other.monthLength && fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2];            \r
550         }\r
551     }\r
552     \r
553     DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser ();\r
554     DateTimePatternGenerator generator = DateTimePatternGenerator.getEmptyInstance();\r
555     \r
556     private Calendar sampleCalendar;\r
557     {\r
558         sampleCalendar = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles"));\r
559         sampleCalendar.set(1999, Calendar.OCTOBER, 13, 23, 58, 59);\r
560     }\r
561 \r
562     private Date sampleDate = sampleCalendar.getTime();\r
563     private TimeZone gmt = TimeZone.getTimeZone("Etc/GMT");\r
564     \r
565     /**\r
566      * Replace the zone string with a different type, eg v's for z's, etc. <p>Called with a pattern, such as one gotten from \r
567      * <pre>\r
568      * String pattern = ((SimpleDateFormat) DateFormat.getTimeInstance(style, locale)).toPattern();\r
569      * </pre>\r
570      * @param pattern original pattern to change, such as "HH:mm zzzz"\r
571      * @param newZone Must be: z, zzzz, Z, ZZZZ, v, vvvv, V, or VVVV\r
572      * @return\r
573      */\r
574     public String replaceZoneString(String pattern, String newZone) {\r
575         final List itemList = formatParser.set(pattern).getItems();\r
576         boolean changed = false;\r
577         for (int i = 0; i < itemList.size(); ++i) {\r
578             Object item = itemList.get(i);\r
579             if (item instanceof VariableField) {\r
580                 VariableField variableField = (VariableField) item;\r
581                 if (variableField.getType() == DateTimePatternGenerator.ZONE) {\r
582                     if (!variableField.toString().equals(newZone)) {\r
583                         changed = true;\r
584                         itemList.set(i, new VariableField(newZone, true));\r
585                     }\r
586                 }\r
587             }\r
588         }\r
589         return changed ? formatParser.toString() : pattern;\r
590     }\r
591     \r
592     public boolean containsZone(String pattern) {\r
593         for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) {\r
594             Object item = it.next();\r
595             if (item instanceof VariableField) {\r
596                 VariableField variableField = (VariableField) item;\r
597                 if (variableField.getType() == DateTimePatternGenerator.ZONE) {\r
598                     return true;\r
599                 }\r
600             }\r
601         }\r
602         return false;\r
603     }\r
604 \r
605     /**\r
606      * Get the ordering from a particular date format. Best is to use\r
607      * DateFormat.FULL to get the format with String form month (like "January")\r
608      * and DateFormat.SHORT for the numeric format order. They may be different.\r
609      * (Theoretically all 4 formats could be different but that never happens in\r
610      * practice.)\r
611      *\r
612      * @param style\r
613      *          DateFormat.FULL..DateFormat.SHORT\r
614      * @param locale\r
615      *          desired locale.\r
616      * @return\r
617      * @return list of ordered items DateFieldType (I\r
618      *         didn't know what form you really wanted so this is just a\r
619      *         stand-in.)\r
620      */\r
621   private DateOrder getOrdering(int style, ULocale locale) {\r
622       // and the date pattern\r
623       String pattern = ((SimpleDateFormat) DateFormat.getDateInstance(style, locale)).toPattern();\r
624       int count = 0;\r
625       DateOrder result = new DateOrder();\r
626      \r
627       for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) {\r
628           Object item = it.next();\r
629         if (!(item instanceof String)) {\r
630           // the first character of the variable field determines the type,\r
631           // according to CLDR.\r
632           String variableField = item.toString();\r
633           switch (variableField.charAt(0)) {\r
634             case 'y': case 'Y': case 'u':\r
635               result.fields[count++] = DateFieldType.YEAR;\r
636               break;\r
637             case 'M': case 'L':\r
638                 result.monthLength = variableField.length();\r
639                 if (result.monthLength < 2) {\r
640                     result.monthLength = 2;\r
641                 }\r
642                 result.fields[count++] = DateFieldType.MONTH;\r
643               break;\r
644             case 'd': case 'D': case 'F': case 'g':\r
645                 result.fields[count++] = DateFieldType.DAY;\r
646               break;\r
647           }\r
648         }\r
649       }\r
650       return result;\r
651     }\r
652       /* Tests the method\r
653        *        public static DateTimePatternGenerator getInstance()\r
654        */\r
655       public void TestGetInstance(){\r
656           try{\r
657               DateTimePatternGenerator.getInstance();\r
658           } catch(Exception e){\r
659               errln("DateTimePatternGenerator.getInstance() was not suppose to " +\r
660                       "return an exception.");\r
661           }\r
662       }\r
663       \r
664       /* Tests the method\r
665        *        public String getSkeleton(String pattern)\r
666        */\r
667       public void TestGetSkeleton(){\r
668           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
669           String[] cases = {"MMDD","MMMDD","MMM-DD","DD/MMM","ddM"};\r
670           String[] results = {"MMDD","MMMDD","MMMDD","MMMDD","Mdd"};\r
671           for(int i=0; i<cases.length; i++){\r
672               if(!dtpg.getSkeleton(cases[i]).equals(results[i])){\r
673                   errln("DateTimePatternGenerator.getSkeleton(String) did " +\r
674                           "return the expected result when passing " + cases[i] +\r
675                           " and expected " + results[i] + " but got " +\r
676                           dtpg.getSkeleton(cases[i]));\r
677               }\r
678           }\r
679       }\r
680       \r
681       /* Tests the method\r
682        *        public String getBaseSkeleton(String pattern)\r
683        */\r
684       public void TestGetBaseSkeleton(){\r
685           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
686           String[] cases = {"MMDD","MMMDD","MMM-DD","DD/MMM","ddM"};\r
687           String[] results = {"MD","MMMD","MMMD","MMMD","Md"};\r
688           for(int i=0; i<cases.length; i++){\r
689               if(!dtpg.getBaseSkeleton(cases[i]).equals(results[i])){\r
690                   errln("DateTimePatternGenerator.getSkeleton(String) did " +\r
691                           "return the expected result when passing " + cases[i] +\r
692                           " and expected " + results[i] + " but got " +\r
693                           dtpg.getBaseSkeleton(cases[i]));\r
694               }\r
695           }\r
696       }\r
697       \r
698       /* Tests the method\r
699        *        public Map<String, String> getSkeletons(Map<String, String> result)\r
700        */\r
701       public void TestGetSkeletons(){\r
702           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
703           // Tests when "if (result == null)" is true\r
704           try{\r
705               dtpg.getSkeletons(null);\r
706           } catch(Exception e){\r
707               errln("DateTimePatternGenerator.getSkeletons(Map) was suppose to " +\r
708                       "return a new LinkedHashMap for a null parameter.");\r
709           }\r
710           \r
711           // Tests when "if (result == null)" is false\r
712           Map<String,String> mm = new LinkedHashMap<String, String>();\r
713           try{\r
714               dtpg.getSkeletons(mm);\r
715           } catch(Exception e){\r
716               errln("DateTimePatternGenerator.getSkeletons(Map) was suppose to " +\r
717                       "return a new LinkedHashMap for a LinkedHashMap parameter.");\r
718           }\r
719       }\r
720       \r
721       /* Tests the method\r
722        *        public Set<String> getBaseSkeletons(Set<String> result)\r
723        */\r
724       public void TestGetBaseSkeletons(){\r
725           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
726           // Tests when "if (result == null)" is true\r
727           try{\r
728               dtpg.getBaseSkeletons(null);\r
729           } catch(Exception e){\r
730               errln("DateTimePatternGenerator.getBaseSkeletons(Map) was suppose to " +\r
731                       "return a new LinkedHashMap for a null parameter.");\r
732           }\r
733           \r
734           // Tests when "if (result == null)" is false\r
735           Set<String> mm = new HashSet<String>();\r
736           try{\r
737               dtpg.getBaseSkeletons(mm);\r
738           } catch(Exception e){\r
739               errln("DateTimePatternGenerator.getBaseSkeletons(Map) was suppose to " +\r
740                       "return a new LinkedHashMap for a HashSet parameter.");\r
741           }\r
742       }\r
743       \r
744       /* Tests the method\r
745        *        public String getDecimal()\r
746        */\r
747       public void TestGetDecimal(){\r
748           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
749           if(!dtpg.getDecimal().equals(".")){\r
750               errln("DateTimePatternGenerator.getDecimal() was to return '.' " +\r
751                       "when the object gets a new instance.");\r
752           }\r
753           \r
754           String[] cases = {",","-","","*","&","a","0"};\r
755           for(int i=0; i<cases.length; i++){\r
756               dtpg.setDecimal(cases[i]);\r
757               if(!dtpg.getDecimal().equals(cases[i])){\r
758                   errln("DateTimePatternGenerator.getDecimal() was to return " + cases[i] +\r
759                           "when setting decimal with " + cases[i]);\r
760               }\r
761           }\r
762       }\r
763       \r
764       /* Tests the method\r
765        *        public Collection<String> getRedundants(Collection<String> output)\r
766        */\r
767       public void TestGetRedundants(){\r
768           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
769           \r
770           // Tests when "if (output == null)" is true\r
771           try{\r
772               dtpg.getRedundants(null);\r
773           } catch(Exception e){\r
774               errln("DateTimeGenerator.getRedundants was not suppose to return " +\r
775                       "an exception when passing a null parameter.");\r
776           }\r
777           \r
778           // Tests when "if (output == null)" is false\r
779           try{\r
780               Collection<String> out = new LinkedHashSet<String>();\r
781               dtpg.getRedundants(out);\r
782           } catch(Exception e){\r
783               errln("DateTimeGenerator.getRedundants was not suppose to return " +\r
784                   "an exception when passing a new LinkedHashSet<String>() parameter.");\r
785           }\r
786           \r
787       }\r
788       \r
789       /* Tests the method\r
790        *        public String getAppendItemFormat(int field)\r
791        */\r
792       public void TestGetAppendItemFormat(){\r
793           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
794           String[] cases = {"d","u","m","m","y"};\r
795           for(int i=0; i<cases.length; i++){\r
796               dtpg.setAppendItemFormat(i, cases[i]);\r
797               if(!dtpg.getAppendItemFormat(i).equals(cases[i])){\r
798                   errln("DateTimePatternGeneratorgetAppendItemFormat(int field) " +\r
799                           "did not return as expected. Value set at " + i + " was " +\r
800                           cases[i] + " but got back " + dtpg.getAppendItemFormat(i));\r
801               }\r
802           }\r
803       }\r
804       \r
805       /* Tests the method\r
806        *    public String getAppendItemName(int field)\r
807        */\r
808       public void TestGetAppendItemName(){\r
809           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
810           String[] cases = {"d","u","m","m","y"};\r
811           for(int i=0; i<cases.length; i++){\r
812               dtpg.setAppendItemName(i, cases[i]);\r
813               if(!dtpg.getAppendItemName(i).equals(cases[i])){\r
814                   errln("DateTimePatternGenerator.getAppendItemFormat(int field) " +\r
815                           "did not return as expected. Value set at " + i + " was " +\r
816                           cases[i] + " but got back " + dtpg.getAppendItemName(i));\r
817               }\r
818           }\r
819       }\r
820       \r
821       /* Tests the method\r
822        *    public static boolean isSingleField(String skeleton)\r
823        */\r
824       @SuppressWarnings("static-access")\r
825     public void TestIsSingleField(){\r
826           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
827           String[] cases = {" ", "m","mm","md","mmd","mmdd"};\r
828           boolean[] results = {true,true,true,false,false,false};\r
829           for(int i=0; i<cases.length; i++){\r
830               if(dtpg.isSingleField(cases[i]) != results[i]){\r
831                   errln("DateTimePatternGenerator.isSingleField(String skeleton) " +\r
832                           "did not return as expected. Value passed was " + cases[i] +\r
833                           " but got back " + dtpg.isSingleField(cases[i]));\r
834               }\r
835           }\r
836       }\r
837       \r
838       /* Tests the method\r
839        *    public Object freeze()\r
840        *    public Object cloneAsThawed()\r
841        */\r
842       public void TestFreezeAndCloneAsThawed(){\r
843           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
844           \r
845           if(dtpg.isFrozen() != false){\r
846               errln("DateTimePatternGenerator.isFrozen() is suppose to return false " +\r
847                       "for a DateTimePatternGenerator object that was just " +\r
848                       "created.");\r
849           }\r
850           \r
851           dtpg.freeze();\r
852           if(dtpg.isFrozen() != true){\r
853               errln("DateTimePatternGenerator.isFrozen() is suppose to return true " +\r
854                       "for a DateTimePatternGenerator object that was just " +\r
855                       "created and freeze.");\r
856           }\r
857           \r
858           DateTimePatternGenerator dtpg2 = (DateTimePatternGenerator) dtpg.cloneAsThawed();\r
859           if(dtpg.isFrozen() != false){\r
860               errln("DateTimePatternGenerator.isFrozen() is suppose to return false " +\r
861                       "for a DateTimePatternGenerator object that was just " +\r
862                       "clone as thawed.");\r
863           }\r
864           if(dtpg2.isFrozen() != false){\r
865               errln("DateTimePatternGenerator.isFrozen() is suppose to return false " +\r
866                       "for a second DateTimePatternGenerator object that was just " +\r
867                       "clone as thawed.");\r
868           }\r
869       }\r
870       \r
871       /* Tests the method\r
872        *    public Object clone()\r
873        */\r
874       public void TestClone(){\r
875           DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();\r
876           DateTimePatternGenerator dtpg2 = (DateTimePatternGenerator) dtpg.clone();\r
877           dtpg = (DateTimePatternGenerator) dtpg2.clone();\r
878       }\r
879       \r
880       /* Tests the constructor\r
881        *    public VariableField(String string)\r
882        */\r
883       @SuppressWarnings("unused")\r
884       public void TestVariableField_String(){\r
885           String[] cases = {"d","mm","aa"};\r
886           String[] invalid = {null,"","dummy"};\r
887           for(int i=0; i<cases.length; i++){\r
888               try{\r
889                   VariableField vf = new VariableField(cases[i]);\r
890               } catch(Exception e){\r
891                   errln("VariableField constructor was not suppose to return " +\r
892                   "an exception when created when passing " + cases[i]);\r
893               }\r
894           }\r
895           for(int i=0; i<invalid.length; i++){\r
896               try{\r
897                 VariableField vf = new VariableField(invalid[i]);\r
898                   errln("VariableField constructor was suppose to return " +\r
899                           "an exception when created when passing " + invalid[i]);\r
900               } catch(Exception e){}\r
901           }\r
902       }\r
903       \r
904       /* Tests the method\r
905        *    public FormatParser set(String string, boolean strict)\r
906        */\r
907       public void TestSet(){\r
908           FormatParser fp = new FormatParser();\r
909           //Tests when "if (string.length() == 0)" is true\r
910           try{\r
911               fp.set("",true);\r
912           }catch(Exception e){\r
913               errln("FormatParser.set(String,boolean) was not suppose to " +\r
914                       "return an exception.");\r
915           }\r
916       }\r
917       \r
918       /* Tests the method\r
919        *    public String toString()\r
920        */\r
921       public void TestToString(){\r
922           FormatParser fp = new FormatParser();\r
923           if(!fp.toString().equals("")){\r
924               errln("FormatParser.toString() was suppose to return an " +\r
925                       "empty string for a new FormatParser object.");\r
926           }\r
927           \r
928           String[] cases = {"m","d","y","mm","mmm","mm dd","mm':'dd","mm-dd-yyyy"};\r
929           String[] results = {"m","d","y","mm","mmm","mm dd","mm:dd","mm-dd-yyyy"};\r
930           for(int i=0; i<cases.length; i++){\r
931               fp.set(cases[i]);\r
932               if(!fp.toString().equals(results[i])){\r
933                   errln("FormatParser.toString() was suppose to return " + results[i] + \r
934                   " after setting the object. Got: " + fp.toString());\r
935               }\r
936           }\r
937       }\r
938       \r
939       /* Tests the method\r
940        *    public boolean hasDateAndTimeFields()\r
941        */\r
942       public void TestHasDateAndTimeFields(){\r
943           FormatParser fp = new FormatParser();\r
944           if(fp.hasDateAndTimeFields() != false){\r
945               errln("FormatParser.hasDateAndTimeFields() was suppose to return " +\r
946                       "false when a new object is created.");\r
947           }\r
948           \r
949           String[] cases = {"MMDDYY", "HHMMSS", "", "MM/DD/YYYY HH:MM:SS",\r
950                   "MMDDYY HHMMSS", "HHMMSS MMDDYYYY", "HMS MDY"};\r
951           boolean[] results = {false,true,false,true,true,true,true};\r
952           for(int i=0; i<cases.length; i++){\r
953               fp.set(cases[i]);\r
954               if(fp.hasDateAndTimeFields() != results[i]){\r
955                   errln("FormatParser.hasDateAndTimeFields() was suppose to " +\r
956                           "return " + results[i] + " but returned " +\r
957                           fp.hasDateAndTimeFields() + " for parameter " + \r
958                           cases[i] + " that is set to FormatParser.");\r
959               }\r
960           }\r
961       }\r
962       \r
963       /* Tests the method\r
964        *    private void checkFrozen()\r
965        * from public void setDateTimeFormat(String dateTimeFormat)\r
966        */\r
967       public void TestCheckFrozen(){\r
968           // Tests when "if (isFrozen())" is true\r
969           DateTimePatternGenerator dt = DateTimePatternGenerator.getInstance();\r
970           try{\r
971               dt.freeze();\r
972               dt.setDateTimeFormat("MMDDYYYY");\r
973               errln("DateTimePatternGenerator.checkFrozen() was suppose to " +\r
974                       "return an exception when trying to setDateTimeFormat " +\r
975                       "for a frozen object.");\r
976           } catch(Exception e){}\r
977           dt = (DateTimePatternGenerator) dt.cloneAsThawed();\r
978       }\r
979       \r
980       /* Tests the method\r
981        *    public String getFields(String pattern)\r
982        */\r
983       public void TestGetFields(){\r
984           DateTimePatternGenerator dt = DateTimePatternGenerator.getInstance();\r
985           String[] cases = {"MMDDYY", "HHMMSS", "", "MM/DD/YYYY HH:MM:SS",\r
986                   "MMDDYY HHMMSS", "HHMMSS MMDDYYYY", "HMS MDY"};\r
987           String[] results = {"{Month:N}{Day_Of_Year:N}{Year:N}",\r
988                   "{Hour:N}{Month:N}{Fractional_Second:N}","",\r
989                   "{Month:N}/{Day_Of_Year:N}/{Year:N} {Hour:N}:{Month:N}:{Fractional_Second:N}",\r
990                   "{Month:N}{Day_Of_Year:N}{Year:N} {Hour:N}{Month:N}{Fractional_Second:N}",\r
991                   "{Hour:N}{Month:N}{Fractional_Second:N} {Month:N}{Day_Of_Year:N}{Year:N}",\r
992                   "{Hour:N}{Month:N}{Fractional_Second:N} {Month:N}{Day_Of_Year:N}{Year:N}"};\r
993           for(int i=0; i<cases.length; i++){\r
994               try{\r
995                   if(!dt.getFields(cases[i]).equals(results[i]));\r
996               } catch(Exception e){\r
997                   errln("DateTimePatternGenerator.getFields(String) did not " +\r
998                           "not return an expected result when passing " + cases[i] +\r
999                           ". Got " + dt.getFields(cases[i]) + " but expected " +\r
1000                           results[i]);\r
1001               }\r
1002           }\r
1003       }\r
1004 \r
1005       /*\r
1006        * Test case for DateFormatPatternGenerator threading problem #7169\r
1007        */\r
1008       public void TestT7169() {\r
1009           Thread[] workers = new Thread[10];\r
1010           for (int i = 0 ; i < workers.length; i++) {\r
1011               workers[i] = new Thread(new Runnable() {\r
1012                   public void run() {\r
1013                       try {\r
1014                           for (int i = 0; i < 50; i++) {\r
1015                               DateTimePatternGenerator patternGenerator =\r
1016                                   DateTimePatternGenerator.getFrozenInstance(ULocale.US);\r
1017                               patternGenerator.getBestPattern("MMMMd");\r
1018                           }\r
1019                       } catch (Exception e) {\r
1020                           errln("FAIL: Caught an exception (frozen)" + e);\r
1021                       }\r
1022                       try {\r
1023                           for (int i = 0; i < 50; i++) {\r
1024                               DateTimePatternGenerator patternGenerator =\r
1025                                   DateTimePatternGenerator.getInstance(ULocale.US);\r
1026                               patternGenerator.getBestPattern("MMMMd");\r
1027                           }\r
1028                       } catch (Exception e) {\r
1029                           errln("FAIL: Caught an exception " + e);\r
1030                       }\r
1031                   }\r
1032               });\r
1033           }\r
1034           for (Thread wk : workers) {\r
1035               wk.start();\r
1036           }\r
1037           for (Thread wk : workers) {\r
1038               try {\r
1039                   wk.join();\r
1040               } catch (InterruptedException ie) {\r
1041                   \r
1042               }\r
1043           }\r
1044       }\r
1045 \r
1046       /**\r
1047        * Test handling of options\r
1048        *\r
1049        * For reference, as of ICU 4.3.3,\r
1050        *  root/gregorian has\r
1051        *      Hm{"H:mm"}\r
1052        *      Hms{"H:mm:ss"}\r
1053        *      hm{"h:mm a"}\r
1054        *      hms{"h:mm:ss a"}\r
1055        *  en/gregorian has\r
1056        *      Hm{"H:mm"}\r
1057        *      Hms{"H:mm:ss"}\r
1058        *      hm{"h:mm a"}\r
1059        *  be/gregorian has\r
1060        *      HHmmss{"HH.mm.ss"}\r
1061        *      Hm{"HH.mm"}\r
1062        *      hm{"h.mm a"}\r
1063        *      hms{"h.mm.ss a"}\r
1064        */\r
1065       private final class TestOptionsItem {\r
1066           public String locale;\r
1067           public String skeleton;\r
1068           public String expectedPattern;\r
1069           public int options;\r
1070           // Simple constructor\r
1071           public TestOptionsItem(String loc, String skel, String expectedPat, int opts) {\r
1072               locale = loc;\r
1073               skeleton = skel;\r
1074               expectedPattern = expectedPat;\r
1075               options = opts;\r
1076           }\r
1077       }\r
1078       public void TestOptions() {\r
1079           final TestOptionsItem[] testOptionsData = {\r
1080               new TestOptionsItem( "en", "Hmm",  "HH:mm",   DateTimePatternGenerator.MATCH_NO_OPTIONS        ),\r
1081               new TestOptionsItem( "en", "HHmm", "HH:mm",   DateTimePatternGenerator.MATCH_NO_OPTIONS        ),\r
1082               new TestOptionsItem( "en", "hhmm", "h:mm a",  DateTimePatternGenerator.MATCH_NO_OPTIONS        ),\r
1083               new TestOptionsItem( "en", "Hmm",  "HH:mm",   DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ),\r
1084               new TestOptionsItem( "en", "HHmm", "HH:mm",   DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ),\r
1085               new TestOptionsItem( "en", "hhmm", "hh:mm a", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ),\r
1086               new TestOptionsItem( "be", "Hmm",  "HH.mm",   DateTimePatternGenerator.MATCH_NO_OPTIONS        ),\r
1087               new TestOptionsItem( "be", "HHmm", "HH.mm",   DateTimePatternGenerator.MATCH_NO_OPTIONS        ),\r
1088               new TestOptionsItem( "be", "hhmm", "h.mm a",  DateTimePatternGenerator.MATCH_NO_OPTIONS        ),\r
1089               new TestOptionsItem( "be", "Hmm",  "H.mm",    DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ),\r
1090               new TestOptionsItem( "be", "HHmm", "HH.mm",   DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ),\r
1091               new TestOptionsItem( "be", "hhmm", "hh.mm a", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ),\r
1092           };\r
1093 \r
1094           for (int i = 0; i < testOptionsData.length; ++i) {\r
1095               ULocale uloc = new ULocale(testOptionsData[i].locale);\r
1096               DateTimePatternGenerator dtpgen = DateTimePatternGenerator.getInstance(uloc);\r
1097               String pattern = dtpgen.getBestPattern(testOptionsData[i].skeleton, testOptionsData[i].options);\r
1098               if (pattern.compareTo(testOptionsData[i].expectedPattern) != 0) {\r
1099                   errln("Locale " + testOptionsData[i].locale + ", skeleton " + testOptionsData[i].skeleton +\r
1100                       ", options " + ((testOptionsData[i].options != 0)? "!=0": "==0") +\r
1101                       ", expected pattern " + testOptionsData[i].expectedPattern + ", got " + pattern);\r
1102               }\r
1103           }\r
1104       }\r
1105 }\r