2 *******************************************************************************
\r
3 * Copyright (C) 2006-2010, Google, International Business Machines Corporation *
\r
4 * and others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.dev.test.format;
\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
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
38 public class DateTimeGeneratorTest extends TestFmwk {
\r
39 public static boolean GENERATE_TEST_DATA;
\r
42 GENERATE_TEST_DATA = System.getProperty("GENERATE_TEST_DATA") != null;
\r
43 } catch (SecurityException e) {
\r
44 GENERATE_TEST_DATA = false;
\r
47 public static int RANDOM_COUNT = 1000;
\r
48 public static boolean DEBUG = false;
\r
50 public static void main(String[] args) throws Exception {
\r
51 new DateTimeGeneratorTest().run(args);
\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
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
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
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
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
84 // add test of basic cases
\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
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
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
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
131 public void TestEmpty() {
\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
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
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
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
162 for (int i = 0; i < RANDOM_COUNT; ++i) {
\r
163 String patternTest = getRandomString(randomSet, 0, 10);
\r
164 CheckPattern(buffer, pp, patternTest);
\r
168 Random random = new java.util.Random(-1);
\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
178 return result.toString();
\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
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
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
202 private void showItems(StringBuffer buffer, PatternTokenizer pp, String patternTest) {
\r
203 logln("input:\t<" + patternTest + ">");
\r
205 buffer.setLength(0);
\r
206 int status = pp.next(buffer);
\r
207 if (status == PatternTokenizer.DONE) break;
\r
209 if (status != PatternTokenizer.SYNTAX ) {
\r
210 lit = "\t<" + pp.quoteLiteral(buffer) + ">";
\r
212 logln("\t" + statusName[status] + "\t<" + buffer + ">" + lit);
\r
216 static final String[] statusName = {"DONE", "SYNTAX", "LITERAL", "BROKEN_QUOTE", "BROKEN_ESCAPE", "UNKNOWN"};
\r
218 public void TestBasic() {
\r
219 ULocale uLocale = null;
\r
220 DateTimePatternGenerator dtfg = 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
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
254 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date));
\r
259 static final Object[] patternTestData = {
\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
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
377 public void DayMonthTest() {
\r
378 final ULocale locale = ULocale.FRANCE;
\r
380 // set up the generator
\r
381 DateTimePatternGenerator dtpgen
\r
382 = DateTimePatternGenerator.getInstance(locale);
\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
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
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
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
412 ULocale[] locales = ULocale.getAvailableLocales();
\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
422 // Skipping some test case in the non-exhaustive mode to reduce the test time
\r
424 if(params.inclusion<=5 && count%3!=0){
\r
427 logln(locales[i].toString());
\r
428 DateTimePatternGenerator dtpgen
\r
429 = DateTimePatternGenerator.getInstance(locales[i]);
\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
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
450 logln(locales[i] + ":\t\"" + pattern + "\" => \t\"" + newPattern + "\"\t" + formatted);
\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
461 VariableField vf = new VariableField(String.valueOf(c), true);
\r
462 logln("VariableField " + vf.toString());
\r
464 } catch (Exception e) {}
\r
465 if (works != valid.contains(c)) {
\r
467 errln("VariableField can be created with illegal character: " + c);
\r
469 errln("VariableField can't be created with legal character: " + c);
\r
475 static String[] DATE_STYLE_NAMES = {
\r
476 "FULL", "LONG", "MEDIUM", "SHORT"
\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
491 errln(showOrderComparison(uLocale, style1, style2, order1, order2));
\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
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
504 + DATE_STYLE_NAMES[style2] + ": " + order2 + ", <" + pattern2 + ">; " ;
\r
508 * Main date fields -- Poor-man's enum -- change to real enum when we get JDK 1.5
\r
510 public static class DateFieldType {
\r
511 private String name;
\r
512 private DateFieldType(String string) {
\r
516 public static DateFieldType
\r
517 YEAR = new DateFieldType("YEAR"),
\r
518 MONTH = new DateFieldType("MONTH"),
\r
519 DAY = new DateFieldType("DAY");
\r
521 public String toString() {
\r
527 * Simple struct for output from getOrdering
\r
529 static class DateOrder {
\r
531 DateFieldType[] fields = new DateFieldType[3];
\r
533 public boolean isCompatible(DateOrder other) {
\r
534 return monthLength == other.monthLength;
\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
544 public String toString() {
\r
545 return "{" + monthLength + ", " + fields[0] + ", " + fields[1] + ", " + fields[2] + "}";
\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
553 DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser ();
\r
554 DateTimePatternGenerator generator = DateTimePatternGenerator.getEmptyInstance();
\r
556 private Calendar sampleCalendar;
\r
558 sampleCalendar = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles"));
\r
559 sampleCalendar.set(1999, Calendar.OCTOBER, 13, 23, 58, 59);
\r
562 private Date sampleDate = sampleCalendar.getTime();
\r
563 private TimeZone gmt = TimeZone.getTimeZone("Etc/GMT");
\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
568 * String pattern = ((SimpleDateFormat) DateFormat.getTimeInstance(style, locale)).toPattern();
\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
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
584 itemList.set(i, new VariableField(newZone, true));
\r
589 return changed ? formatParser.toString() : pattern;
\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
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
613 * DateFormat.FULL..DateFormat.SHORT
\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
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
625 DateOrder result = new DateOrder();
\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
637 case 'M': case 'L':
\r
638 result.monthLength = variableField.length();
\r
639 if (result.monthLength < 2) {
\r
640 result.monthLength = 2;
\r
642 result.fields[count++] = DateFieldType.MONTH;
\r
644 case 'd': case 'D': case 'F': case 'g':
\r
645 result.fields[count++] = DateFieldType.DAY;
\r
652 /* Tests the method
\r
653 * public static DateTimePatternGenerator getInstance()
\r
655 public void TestGetInstance(){
\r
657 DateTimePatternGenerator.getInstance();
\r
658 } catch(Exception e){
\r
659 errln("DateTimePatternGenerator.getInstance() was not suppose to " +
\r
660 "return an exception.");
\r
664 /* Tests the method
\r
665 * public String getSkeleton(String pattern)
\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
681 /* Tests the method
\r
682 * public String getBaseSkeleton(String pattern)
\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
698 /* Tests the method
\r
699 * public Map<String, String> getSkeletons(Map<String, String> result)
\r
701 public void TestGetSkeletons(){
\r
702 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();
\r
703 // Tests when "if (result == null)" is true
\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
711 // Tests when "if (result == null)" is false
\r
712 Map<String,String> mm = new LinkedHashMap<String, String>();
\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
721 /* Tests the method
\r
722 * public Set<String> getBaseSkeletons(Set<String> result)
\r
724 public void TestGetBaseSkeletons(){
\r
725 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();
\r
726 // Tests when "if (result == null)" is true
\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
734 // Tests when "if (result == null)" is false
\r
735 Set<String> mm = new HashSet<String>();
\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
744 /* Tests the method
\r
745 * public String getDecimal()
\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
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
764 /* Tests the method
\r
765 * public Collection<String> getRedundants(Collection<String> output)
\r
767 public void TestGetRedundants(){
\r
768 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();
\r
770 // Tests when "if (output == null)" is true
\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
778 // Tests when "if (output == null)" is false
\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
789 /* Tests the method
\r
790 * public String getAppendItemFormat(int field)
\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
805 /* Tests the method
\r
806 * public String getAppendItemName(int field)
\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
821 /* Tests the method
\r
822 * public static boolean isSingleField(String skeleton)
\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
838 /* Tests the method
\r
839 * public Object freeze()
\r
840 * public Object cloneAsThawed()
\r
842 public void TestFreezeAndCloneAsThawed(){
\r
843 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();
\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
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
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
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
871 /* Tests the method
\r
872 * public Object clone()
\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
880 /* Tests the constructor
\r
881 * public VariableField(String string)
\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
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
895 for(int i=0; i<invalid.length; i++){
\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
904 /* Tests the method
\r
905 * public FormatParser set(String string, boolean strict)
\r
907 public void TestSet(){
\r
908 FormatParser fp = new FormatParser();
\r
909 //Tests when "if (string.length() == 0)" is true
\r
912 }catch(Exception e){
\r
913 errln("FormatParser.set(String,boolean) was not suppose to " +
\r
914 "return an exception.");
\r
918 /* Tests the method
\r
919 * public String toString()
\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
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
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
939 /* Tests the method
\r
940 * public boolean hasDateAndTimeFields()
\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
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
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
963 /* Tests the method
\r
964 * private void checkFrozen()
\r
965 * from public void setDateTimeFormat(String dateTimeFormat)
\r
967 public void TestCheckFrozen(){
\r
968 // Tests when "if (isFrozen())" is true
\r
969 DateTimePatternGenerator dt = DateTimePatternGenerator.getInstance();
\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
980 /* Tests the method
\r
981 * public String getFields(String pattern)
\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
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
1006 * Test case for DateFormatPatternGenerator threading problem #7169
\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
1014 for (int i = 0; i < 50; i++) {
\r
1015 DateTimePatternGenerator patternGenerator =
\r
1016 DateTimePatternGenerator.getFrozenInstance(ULocale.US);
\r
1017 patternGenerator.getBestPattern("MMMMd");
\r
1019 } catch (Exception e) {
\r
1020 errln("FAIL: Caught an exception (frozen)" + e);
\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
1028 } catch (Exception e) {
\r
1029 errln("FAIL: Caught an exception " + e);
\r
1034 for (Thread wk : workers) {
\r
1037 for (Thread wk : workers) {
\r
1040 } catch (InterruptedException ie) {
\r
1047 * Test handling of options
\r
1049 * For reference, as of ICU 4.3.3,
\r
1050 * root/gregorian has
\r
1054 * hms{"h:mm:ss a"}
\r
1055 * en/gregorian has
\r
1059 * be/gregorian has
\r
1060 * HHmmss{"HH.mm.ss"}
\r
1063 * hms{"h.mm.ss a"}
\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
1074 expectedPattern = expectedPat;
\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
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