]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / format / DateTimeGeneratorTest.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2006-2009, 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.Date;\r
12 import java.util.Iterator;\r
13 import java.util.List;\r
14 import java.util.Random;\r
15 \r
16 import com.ibm.icu.dev.test.TestFmwk;\r
17 import com.ibm.icu.impl.PatternTokenizer;\r
18 import com.ibm.icu.impl.Utility;\r
19 import com.ibm.icu.text.DateFormat;\r
20 import com.ibm.icu.text.DateTimePatternGenerator;\r
21 import com.ibm.icu.text.SimpleDateFormat;\r
22 import com.ibm.icu.text.UTF16;\r
23 import com.ibm.icu.text.UnicodeSet;\r
24 import com.ibm.icu.text.DateTimePatternGenerator.VariableField;\r
25 import com.ibm.icu.util.Calendar;\r
26 import com.ibm.icu.util.GregorianCalendar;\r
27 import com.ibm.icu.util.SimpleTimeZone;\r
28 import com.ibm.icu.util.TimeZone;\r
29 import com.ibm.icu.util.ULocale;\r
30 \r
31 public class DateTimeGeneratorTest extends TestFmwk {\r
32     public static boolean GENERATE_TEST_DATA = System.getProperty("GENERATE_TEST_DATA") != null;\r
33     public static int RANDOM_COUNT = 1000;\r
34     public static boolean DEBUG = false;\r
35     \r
36     public static void main(String[] args) throws Exception {\r
37         new DateTimeGeneratorTest().run(args);\r
38     }\r
39     \r
40     public void TestSimple() {\r
41         // some simple use cases\r
42         ULocale locale = ULocale.GERMANY;\r
43         TimeZone zone = TimeZone.getTimeZone("Europe/Paris");\r
44         \r
45         // make from locale\r
46         DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(locale);\r
47         SimpleDateFormat format = new SimpleDateFormat(gen.getBestPattern("MMMddHmm"), locale);\r
48         format.setTimeZone(zone);\r
49         assertEquals("simple format: MMMddHmm", "14. Okt 8:58", format.format(sampleDate));\r
50         // (a generator can be built from scratch, but that is not a typical use case)\r
51 \r
52         // modify the generator by adding patterns\r
53         DateTimePatternGenerator.PatternInfo returnInfo = new DateTimePatternGenerator.PatternInfo();\r
54         gen.addPattern("d'. von' MMMM", true, returnInfo); \r
55         // the returnInfo is mostly useful for debugging problem cases\r
56         format.applyPattern(gen.getBestPattern("MMMMddHmm"));\r
57         assertEquals("modified format: MMMddHmm", "14. von Oktober 8:58", format.format(sampleDate));\r
58 \r
59         // get a pattern and modify it\r
60         format = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);\r
61         format.setTimeZone(zone);\r
62         String pattern = format.toPattern();\r
63         assertEquals("full-date", "Donnerstag, 14. Oktober 1999 08:58:59 Mitteleurop\u00E4ische Sommerzeit", format.format(sampleDate));\r
64 \r
65         // modify it to change the zone.\r
66         String newPattern = gen.replaceFieldTypes(pattern, "vvvv");\r
67         format.applyPattern(newPattern);\r
68         assertEquals("full-date: modified zone", "Donnerstag, 14. Oktober 1999 08:58:59 Frankreich", format.format(sampleDate));\r
69         \r
70         // add test of basic cases\r
71 \r
72         //lang  YYYYMMM MMMd    MMMdhmm hmm hhmm    Full Date-Time\r
73         // 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
74         DateTimePatternGenerator enGen = DateTimePatternGenerator.getInstance(ULocale.ENGLISH);\r
75         TimeZone enZone = TimeZone.getTimeZone("Etc/GMT");\r
76         SimpleDateFormat enFormat = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, ULocale.ENGLISH);\r
77         enFormat.setTimeZone(enZone);\r
78         String[][] tests = {\r
79               {"yyyyMMMdd", "Oct 14, 1999"},\r
80               {"yyyyqqqq", "4th quarter 1999"},\r
81               {"yMMMdd", "Oct 14, 1999"},\r
82               {"EyyyyMMMdd", "Thu, Oct 14, 1999"},\r
83               {"yyyyMMdd", "10/14/1999"},\r
84               {"yyyyMMM", "Oct 1999"},\r
85               {"yyyyMM", "10/1999"},\r
86               {"yyMM", "10/99"},\r
87               {"yMMMMMd", "O 14, 1999"},  // narrow format\r
88               {"EEEEEMMMMMd", "T, O 14"},  // narrow format\r
89               {"MMMd", "Oct 14"},\r
90               {"MMMdhmm", "Oct 14 6:58 AM"},\r
91               {"EMMMdhmms", "Thu, Oct 14 6:58:59 AM"},\r
92               {"MMdhmm", "10/14 6:58 AM"},\r
93               {"EEEEMMMdhmms", "Thursday, Oct 14 6:58:59 AM"},\r
94               {"yyyyMMMddhhmmss", "Oct 14, 1999 06:58:59 AM"},\r
95               {"EyyyyMMMddhhmmss", "Thu, Oct 14, 1999 06:58:59 AM"},\r
96               {"hmm", "6:58 AM"},\r
97               {"hhmm", "06:58 AM"},\r
98               {"hhmmVVVV", "06:58 AM GMT+00:00"},\r
99         };\r
100         for (int i = 0; i < tests.length; ++i) {\r
101             final String testSkeleton = tests[i][0];\r
102             String pat = enGen.getBestPattern(testSkeleton);\r
103             enFormat.applyPattern(pat);\r
104             String formattedDate = enFormat.format(sampleDate);\r
105             assertEquals("Testing skeleton '" + testSkeleton + "' with  " + sampleDate, tests[i][1], formattedDate);\r
106         }\r
107     }\r
108 \r
109     public void TestRoot() {\r
110         DateTimePatternGenerator rootGen = DateTimePatternGenerator.getInstance(ULocale.ROOT);\r
111         SimpleDateFormat rootFormat = new SimpleDateFormat(rootGen.getBestPattern("yMdHms"), ULocale.ROOT);\r
112         rootFormat.setTimeZone(gmt);\r
113         assertEquals("root format: yMdHms", "1999-10-14 6:58:59", rootFormat.format(sampleDate));\r
114     }\r
115     \r
116     public void TestEmpty() {\r
117         // now nothing\r
118         DateTimePatternGenerator nullGen = DateTimePatternGenerator.getEmptyInstance();\r
119         SimpleDateFormat format = new SimpleDateFormat(nullGen.getBestPattern("yMdHms"), ULocale.ROOT);\r
120         TimeZone rootZone = TimeZone.getTimeZone("Etc/GMT");\r
121         format.setTimeZone(rootZone);\r
122     }\r
123 \r
124     public void TestPatternParser() {\r
125         StringBuffer buffer = new StringBuffer();\r
126         PatternTokenizer pp = new PatternTokenizer()\r
127         .setIgnorableCharacters(new UnicodeSet("[-]"))\r
128         .setSyntaxCharacters(new UnicodeSet("[a-zA-Z]"))\r
129         .setEscapeCharacters(new UnicodeSet("[b#]"))\r
130         .setUsingQuote(true);\r
131         logln("Using Quote");\r
132         for (int i = 0; i < patternTestData.length; ++i) {\r
133             String patternTest = (String) patternTestData[i];\r
134             CheckPattern(buffer, pp, patternTest);\r
135         }\r
136         String[] randomSet = {"abcdef", "$12!@#-", "'\\"};\r
137         for (int i = 0; i < RANDOM_COUNT; ++i) {\r
138             String patternTest = getRandomString(randomSet, 0, 10);\r
139             CheckPattern(buffer, pp, patternTest);\r
140         }\r
141         logln("Using Backslash");\r
142         pp.setUsingQuote(false).setUsingSlash(true);\r
143         for (int i = 0; i < patternTestData.length; ++i) {\r
144             String patternTest = (String) patternTestData[i];\r
145             CheckPattern(buffer, pp, patternTest);\r
146         }\r
147         for (int i = 0; i < RANDOM_COUNT; ++i) {\r
148             String patternTest = getRandomString(randomSet, 0, 10);\r
149             CheckPattern(buffer, pp, patternTest);\r
150         }\r
151     }\r
152     \r
153     Random random = new java.util.Random(-1);\r
154     \r
155     private String getRandomString(String[] randomList, int minLen, int maxLen) {\r
156         StringBuffer result = new StringBuffer();\r
157         int len = random.nextInt(maxLen + 1 - minLen) + minLen;\r
158         for (int i = minLen; i < len; ++ i) {\r
159             String source = randomList[random.nextInt(randomList.length)]; // don't bother with surrogates\r
160             char ch = source.charAt(random.nextInt(source.length()));\r
161             UTF16.append(result, ch);\r
162         }\r
163         return result.toString();\r
164     }\r
165     \r
166     private void CheckPattern(StringBuffer buffer, PatternTokenizer pp, String patternTest) {\r
167         pp.setPattern(patternTest);\r
168         if (DEBUG && isVerbose()) {\r
169             showItems(buffer, pp, patternTest);\r
170         }\r
171         String normalized = pp.setStart(0).normalize();\r
172         logln("input:\t<" + patternTest + ">" + "\tnormalized:\t<" + normalized + ">");\r
173         String doubleNormalized = pp.setPattern(normalized).normalize();\r
174         if (!normalized.equals(doubleNormalized)) {\r
175             errln("Normalization not idempotent:\t" + patternTest + "\tnormalized: " + normalized +  "\tnormalized2: " + doubleNormalized);\r
176             // allow for debugging at the point of failure\r
177             if (DEBUG) {\r
178                 pp.setPattern(patternTest);\r
179                 normalized = pp.setStart(0).normalize();\r
180                 pp.setPattern(normalized);\r
181                 showItems(buffer, pp, normalized);\r
182                 doubleNormalized = pp.normalize();\r
183             }\r
184         }\r
185     }\r
186 \r
187     private void showItems(StringBuffer buffer, PatternTokenizer pp, String patternTest) {\r
188         logln("input:\t<" + patternTest + ">");\r
189         while (true) {\r
190             buffer.setLength(0);\r
191             int status = pp.next(buffer);\r
192             if (status == PatternTokenizer.DONE) break;\r
193             String lit = "";\r
194             if (status != PatternTokenizer.SYNTAX ) {\r
195                 lit = "\t<" + pp.quoteLiteral(buffer) + ">";\r
196             }\r
197             logln("\t" + statusName[status] + "\t<" + buffer + ">" + lit);\r
198         }\r
199     }\r
200     \r
201     static final String[] statusName = {"DONE", "SYNTAX", "LITERAL", "BROKEN_QUOTE", "BROKEN_ESCAPE", "UNKNOWN"};\r
202     \r
203     public void TestBasic() {\r
204         ULocale uLocale = null;\r
205         DateTimePatternGenerator dtfg = null;\r
206         Date date = null;\r
207         for (int i = 0; i < dateTestData.length; ++i) {\r
208             if (dateTestData[i] instanceof ULocale) {\r
209                 uLocale = (ULocale) dateTestData[i];\r
210                 dtfg = DateTimePatternGenerator.getInstance(uLocale);\r
211                 if (GENERATE_TEST_DATA) logln("new ULocale(\"" + uLocale.toString() + "\"),");\r
212             } else if (dateTestData[i] instanceof Date) {\r
213                 date = (Date) dateTestData[i];\r
214                 if (GENERATE_TEST_DATA) logln("new Date(" + date.getTime()+ "L),");\r
215             } else if (dateTestData[i] instanceof String) {\r
216                 String testSkeleton = (String) dateTestData[i];\r
217                 String pattern = dtfg.getBestPattern(testSkeleton);\r
218                 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale);\r
219                 String formatted = sdf.format(date);\r
220                 if (GENERATE_TEST_DATA) logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},");\r
221                 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date));\r
222             } else {\r
223                 String[] testPair = (String[]) dateTestData[i];\r
224                 String testSkeleton = testPair[0];\r
225                 String testFormatted = testPair[1];\r
226                 String pattern = dtfg.getBestPattern(testSkeleton);\r
227                 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale);\r
228                 String formatted = sdf.format(date);\r
229                 if (GENERATE_TEST_DATA) {\r
230                     logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},");\r
231                 } else if (!formatted.equals(testFormatted)) {\r
232                     errln(uLocale + "\tformatted string doesn't match test case: " + testSkeleton + "\t generated: " +  pattern + "\t expected: " + testFormatted + "\t got: " + formatted);\r
233                     if (true) { // debug\r
234                         pattern = dtfg.getBestPattern(testSkeleton);\r
235                         sdf = new SimpleDateFormat(pattern, uLocale);\r
236                         formatted = sdf.format(date);\r
237                     }\r
238                 }\r
239                 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date));\r
240             }\r
241         }\r
242     }\r
243     \r
244     static final Object[] patternTestData = {\r
245         "'$f''#c",\r
246         "'' 'a",\r
247         "'.''.'",\r
248         "\\u0061\\\\",\r
249         "mm.dd 'dd ' x",\r
250         "'' ''",\r
251     };\r
252     \r
253     // can be generated by using GENERATE_TEST_DATA. Must be reviewed before adding\r
254     static final Object[] dateTestData = {\r
255         new Date(916300739000L), // 1999-01-13T23:58:59,0-0800\r
256         new ULocale("en_US"),\r
257         new String[] {"yM", "1/1999"},\r
258         new String[] {"yMMM", "Jan 1999"},\r
259         new String[] {"yMd", "1/13/1999"},\r
260         new String[] {"yMMMd", "Jan 13, 1999"},\r
261         new String[] {"Md", "1/13"},\r
262         new String[] {"MMMd", "Jan 13"},\r
263         new String[] {"yQQQ", "Q1 1999"},\r
264         new String[] {"jjmm", "11:58 PM"},\r
265         new String[] {"hhmm", "11:58 PM"},\r
266         new String[] {"HHmm", "23:58"},\r
267         new String[] {"mmss", "58:59"},\r
268         new ULocale("zh_Hans_CN"),\r
269         new String[] {"yM", "1999-1"},\r
270         new String[] {"yMMM", "1999-01"},\r
271         new String[] {"yMd", "1999\u5E741\u670813\u65E5"},\r
272         new String[] {"yMMMd", "1999\u5E7401\u670813\u65E5"},\r
273         new String[] {"Md", "1-13"},\r
274         new String[] {"MMMd", "01-13"},\r
275         new String[] {"yQQQ", "1999\u5E741\u5B63"},\r
276         new String[] {"hhmm", "\u4E0B\u534811:58"},\r
277         new String[] {"HHmm", "23:58"},\r
278         new String[] {"mmss", "58:59"},\r
279         new ULocale("de_DE"),\r
280         new String[] {"yM", "1999-1"},\r
281         new String[] {"yMMM", "Jan 1999"},\r
282         new String[] {"yMd", "13.1.1999"},\r
283         new String[] {"yMMMd", "13. Jan 1999"},\r
284         new String[] {"Md", "13.1."},   // 13.1\r
285         new String[] {"MMMd", "13. Jan"},\r
286         new String[] {"yQQQ", "Q1 1999"},\r
287         new String[] {"jjmm", "23:58"},\r
288         new String[] {"hhmm", "11:58 nachm."},\r
289         new String[] {"HHmm", "23:58"},\r
290         new String[] {"mmss", "58:59"},\r
291         new ULocale("fi"),\r
292         new String[] {"yM", "1/1999"},   // 1.1999\r
293         new String[] {"yMMM", "tammikuuta 1999"},  // tammi 1999\r
294         new String[] {"yMd", "13.1.1999"},\r
295         new String[] {"yMMMd", "13. tammikuuta 1999"},\r
296         new String[] {"Md", "13.1."},\r
297         new String[] {"MMMd", "13. tammikuuta"},\r
298         new String[] {"yQQQ", "1. nelj./1999"},  // 1. nelj. 1999\r
299         new String[] {"jjmm", "23.58"},\r
300         new String[] {"hhmm", "11.58 ip."},\r
301         new String[] {"HHmm", "23.58"},\r
302         new String[] {"mmss", "58.59"},\r
303     };\r
304     \r
305     public void DayMonthTest() {\r
306         final ULocale locale = ULocale.FRANCE;\r
307         \r
308         // set up the generator\r
309         DateTimePatternGenerator dtpgen\r
310           = DateTimePatternGenerator.getInstance(locale);\r
311         \r
312         // get a pattern for an abbreviated month and day\r
313         final String pattern = dtpgen.getBestPattern("MMMd");\r
314         SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale);\r
315         \r
316         // use it to format (or parse)\r
317         String formatted = formatter.format(new Date());\r
318         logln("formatted=" + formatted);\r
319         // for French, the result is "13 sept."\r
320     }\r
321     \r
322     public void TestOrdering() {\r
323         ULocale[] locales = ULocale.getAvailableLocales();\r
324         for (int i = 0; i < locales.length; ++i) {\r
325             for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) {\r
326                 for (int style2 = DateFormat.FULL; style2 < style1; ++style2) {\r
327                     checkCompatible(style1, style2, locales[i]);                    \r
328                 }               \r
329             }\r
330         }\r
331     }\r
332     \r
333     public void TestReplacingZoneString() {\r
334         Date testDate = new Date();\r
335         TimeZone testTimeZone = TimeZone.getTimeZone("America/New_York");\r
336         TimeZone bogusTimeZone = new SimpleTimeZone(1234, "Etc/Unknown");\r
337         Calendar calendar = Calendar.getInstance();\r
338         ParsePosition parsePosition = new ParsePosition(0);\r
339 \r
340         ULocale[] locales = ULocale.getAvailableLocales();\r
341         int count = 0;\r
342         for (int i = 0; i < locales.length; ++i) {\r
343             // skip the country locales unless we are doing exhaustive tests\r
344             if (getInclusion() < 6) {\r
345                 if (locales[i].getCountry().length() > 0) {\r
346                     continue;\r
347                 }\r
348             }\r
349             count++;\r
350             // Skipping some test case in the non-exhaustive mode to reduce the test time\r
351             //ticket#6503\r
352             if(params.inclusion<=5 && count%3!=0){\r
353                 continue;\r
354             }\r
355             logln(locales[i].toString());\r
356             DateTimePatternGenerator dtpgen\r
357             = DateTimePatternGenerator.getInstance(locales[i]);\r
358             \r
359             for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) {\r
360                 final SimpleDateFormat oldFormat = (SimpleDateFormat) DateFormat.getTimeInstance(style1, locales[i]);\r
361                 String pattern = oldFormat.toPattern();\r
362                 String newPattern = dtpgen.replaceFieldTypes(pattern, "VVVV"); // replaceZoneString(pattern, "VVVV");\r
363                 if (newPattern.equals(pattern)) {\r
364                     continue;\r
365                 }\r
366                 // verify that it roundtrips parsing\r
367                 SimpleDateFormat newFormat = new SimpleDateFormat(newPattern, locales[i]);\r
368                 newFormat.setTimeZone(testTimeZone);\r
369                 String formatted = newFormat.format(testDate);\r
370                 calendar.setTimeZone(bogusTimeZone);\r
371                 parsePosition.setIndex(0);\r
372                 newFormat.parse(formatted, calendar, parsePosition);\r
373                 if (parsePosition.getErrorIndex() >= 0) {\r
374                     errln("Failed parse with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted.substring(0,parsePosition.getErrorIndex()) + "{}" + formatted.substring(parsePosition.getErrorIndex()) + "\"");\r
375                 } else if (!calendar.getTimeZone().getID().equals(testTimeZone.getID())) {\r
376                     errln("Failed timezone roundtrip with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted + "\",\t" + calendar.getTimeZone().getID() + " != " + testTimeZone.getID());\r
377                 } else {\r
378                     logln(locales[i] + ":\t\"" + pattern + "\" => \t\"" + newPattern + "\"\t" + formatted);\r
379                 }\r
380             }\r
381         }\r
382     }\r
383     \r
384     public void TestVariableCharacters() {\r
385         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
386         for (char c = 0; c < 0xFF; ++c) {\r
387             boolean works = false;\r
388             try {\r
389                 VariableField vf = new VariableField(String.valueOf(c), true);\r
390                 logln("VariableField " + vf.toString());\r
391                 works = true;\r
392             } catch (Exception e) {}\r
393             if (works != valid.contains(c)) {\r
394                 if (works) {\r
395                     errln("VariableField can be created with illegal character: " + c);\r
396                 } else {\r
397                     errln("VariableField can't be created with legal character: " + c);\r
398                 }\r
399             }\r
400         }\r
401     }\r
402     \r
403     static String[] DATE_STYLE_NAMES = {\r
404         "FULL", "LONG", "MEDIUM", "SHORT"\r
405     };\r
406     \r
407     /**\r
408      * @param fullOrder\r
409      * @param longOrder\r
410      */\r
411     private void checkCompatible(int style1, int style2, ULocale uLocale) {\r
412         DateOrder order1 = getOrdering(style1, uLocale);\r
413         DateOrder order2 = getOrdering(style2, uLocale);\r
414         if (!order1.hasSameOrderAs(order2)) {\r
415             if (order1.monthLength == order2.monthLength) { // error if have same month length, different ordering\r
416                 if (skipIfBeforeICU(4,3,0)) {\r
417                     logln(showOrderComparison(uLocale, style1, style2, order1, order2));\r
418                 } else {\r
419                     errln(showOrderComparison(uLocale, style1, style2, order1, order2));\r
420                 }\r
421             } else if (isVerbose() && order1.monthLength > 2 && order2.monthLength > 2) { // warn if both are not numeric\r
422                 logln(showOrderComparison(uLocale, style1, style2, order1, order2));\r
423             }\r
424         }\r
425     }\r
426 \r
427     private String showOrderComparison(ULocale uLocale, int style1, int style2, DateOrder order1, DateOrder order2) {\r
428         String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(style1, uLocale)).toPattern();\r
429         String pattern2 = ((SimpleDateFormat) DateFormat.getDateInstance(style2, uLocale)).toPattern();\r
430         return "Mismatch in in ordering for " + uLocale + ": " + DATE_STYLE_NAMES[style1] + ": " + order1 + ", <" + pattern1 \r
431                 + ">; " \r
432                 + DATE_STYLE_NAMES[style2] + ": " + order2 + ", <" + pattern2 + ">; " ;\r
433     }\r
434 \r
435     /**\r
436      * Main date fields -- Poor-man's enum -- change to real enum when we get JDK 1.5\r
437      */\r
438     public static class DateFieldType {\r
439         private String name;\r
440         private DateFieldType(String string) {\r
441             name = string;\r
442         }\r
443         \r
444         public static DateFieldType \r
445         YEAR = new DateFieldType("YEAR"), \r
446         MONTH = new DateFieldType("MONTH"), \r
447         DAY = new DateFieldType("DAY");\r
448         \r
449         public String toString() {\r
450             return name;\r
451         }\r
452     }\r
453     \r
454     /**\r
455      * Simple struct for output from getOrdering\r
456      */\r
457     static class DateOrder {\r
458         int monthLength;\r
459         DateFieldType[] fields = new DateFieldType[3];\r
460         \r
461         public boolean isCompatible(DateOrder other) {\r
462             return monthLength == other.monthLength;\r
463         }\r
464         /**\r
465          * @param order2\r
466          * @return\r
467          */\r
468         public boolean hasSameOrderAs(DateOrder other) {\r
469             // TODO Auto-generated method stub\r
470             return fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2];\r
471         }\r
472         public String toString() {\r
473             return "{" + monthLength + ", " + fields[0]  + ", " + fields[1]  + ", " + fields[2] + "}";\r
474         }\r
475         public boolean equals(Object that) {\r
476             DateOrder other = (DateOrder) that;\r
477             return monthLength == other.monthLength && fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2];            \r
478         }\r
479     }\r
480     \r
481     DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser ();\r
482     DateTimePatternGenerator generator = DateTimePatternGenerator.getEmptyInstance();\r
483     \r
484     private Calendar sampleCalendar = new GregorianCalendar(1999, Calendar.OCTOBER, 13, 23, 58, 59);\r
485     private Date sampleDate = sampleCalendar.getTime();\r
486     private TimeZone gmt = TimeZone.getTimeZone("Etc/GMT");\r
487     \r
488     /**\r
489      * 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
490      * <pre>\r
491      * String pattern = ((SimpleDateFormat) DateFormat.getTimeInstance(style, locale)).toPattern();\r
492      * </pre>\r
493      * @param pattern original pattern to change, such as "HH:mm zzzz"\r
494      * @param newZone Must be: z, zzzz, Z, ZZZZ, v, vvvv, V, or VVVV\r
495      * @return\r
496      */\r
497     public String replaceZoneString(String pattern, String newZone) {\r
498         final List itemList = formatParser.set(pattern).getItems();\r
499         boolean changed = false;\r
500         for (int i = 0; i < itemList.size(); ++i) {\r
501             Object item = itemList.get(i);\r
502             if (item instanceof VariableField) {\r
503                 VariableField variableField = (VariableField) item;\r
504                 if (variableField.getType() == DateTimePatternGenerator.ZONE) {\r
505                     if (!variableField.toString().equals(newZone)) {\r
506                         changed = true;\r
507                         itemList.set(i, new VariableField(newZone, true));\r
508                     }\r
509                 }\r
510             }\r
511         }\r
512         return changed ? formatParser.toString() : pattern;\r
513     }\r
514     \r
515     public boolean containsZone(String pattern) {\r
516         for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) {\r
517             Object item = it.next();\r
518             if (item instanceof VariableField) {\r
519                 VariableField variableField = (VariableField) item;\r
520                 if (variableField.getType() == DateTimePatternGenerator.ZONE) {\r
521                     return true;\r
522                 }\r
523             }\r
524         }\r
525         return false;\r
526     }\r
527 \r
528     /**\r
529      * Get the ordering from a particular date format. Best is to use\r
530      * DateFormat.FULL to get the format with String form month (like "January")\r
531      * and DateFormat.SHORT for the numeric format order. They may be different.\r
532      * (Theoretically all 4 formats could be different but that never happens in\r
533      * practice.)\r
534      *\r
535      * @param style\r
536      *          DateFormat.FULL..DateFormat.SHORT\r
537      * @param locale\r
538      *          desired locale.\r
539      * @return\r
540      * @return list of ordered items DateFieldType (I\r
541      *         didn't know what form you really wanted so this is just a\r
542      *         stand-in.)\r
543      */\r
544   private DateOrder getOrdering(int style, ULocale locale) {\r
545       // and the date pattern\r
546       String pattern = ((SimpleDateFormat) DateFormat.getDateInstance(style, locale)).toPattern();\r
547       int count = 0;\r
548       DateOrder result = new DateOrder();\r
549      \r
550       for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) {\r
551           Object item = it.next();\r
552         if (!(item instanceof String)) {\r
553           // the first character of the variable field determines the type,\r
554           // according to CLDR.\r
555           String variableField = item.toString();\r
556           switch (variableField.charAt(0)) {\r
557             case 'y': case 'Y': case 'u':\r
558               result.fields[count++] = DateFieldType.YEAR;\r
559               break;\r
560             case 'M': case 'L':\r
561                 result.monthLength = variableField.length();\r
562                 if (result.monthLength < 2) {\r
563                     result.monthLength = 2;\r
564                 }\r
565                 result.fields[count++] = DateFieldType.MONTH;\r
566               break;\r
567             case 'd': case 'D': case 'F': case 'g':\r
568                 result.fields[count++] = DateFieldType.DAY;\r
569               break;\r
570           }\r
571         }\r
572       }\r
573       return result;\r
574     }\r
575 }\r
576 //eof\r