1/* GENERATED SOURCE. DO NOT MODIFY. */ 2// © 2016 and later: Unicode, Inc. and others. 3// License & terms of use: http://www.unicode.org/copyright.html#License 4/* 5 ******************************************************************************* 6 * Copyright (C) 2006-2016, Google, International Business Machines Corporation 7 * and others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 11package android.icu.dev.test.format; 12 13import java.text.ParsePosition; 14import java.util.Collection; 15import java.util.Date; 16import java.util.HashSet; 17import java.util.Iterator; 18import java.util.LinkedHashMap; 19import java.util.LinkedHashSet; 20import java.util.List; 21import java.util.Locale; 22import java.util.Map; 23import java.util.Random; 24import java.util.Set; 25 26import org.junit.Test; 27 28import android.icu.dev.test.TestFmwk; 29import android.icu.impl.PatternTokenizer; 30import android.icu.impl.Utility; 31import android.icu.text.DateFormat; 32import android.icu.text.DateTimePatternGenerator; 33import android.icu.text.DateTimePatternGenerator.FormatParser; 34import android.icu.text.DateTimePatternGenerator.VariableField; 35import android.icu.text.SimpleDateFormat; 36import android.icu.text.UTF16; 37import android.icu.text.UnicodeSet; 38import android.icu.util.Calendar; 39import android.icu.util.GregorianCalendar; 40import android.icu.util.SimpleTimeZone; 41import android.icu.util.TimeZone; 42import android.icu.util.ULocale; 43 44public class DateTimeGeneratorTest extends TestFmwk { 45 public static boolean GENERATE_TEST_DATA; 46 static { 47 try { 48 GENERATE_TEST_DATA = System.getProperty("GENERATE_TEST_DATA") != null; 49 } catch (SecurityException e) { 50 GENERATE_TEST_DATA = false; 51 } 52 }; 53 public static int RANDOM_COUNT = 1000; 54 public static boolean DEBUG = false; 55 56 @Test 57 public void TestC() { 58 String[][] tests = { 59 {"zh", "Cm", "Bh:mm"}, 60 {"de", "Cm", "HH:mm"}, 61 {"en", "Cm", "h:mm a"}, 62 {"en-BN", "Cm", "h:mm b"}, 63 {"gu-IN", "Cm", "h:mm B"}, 64 {"und-IN", "Cm", "h:mm a"}, 65 }; 66 for (String[] test : tests) { 67 DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(ULocale.forLanguageTag(test[0])); 68 String skeleton = test[1]; 69 String pattern = gen.getBestPattern(skeleton); 70 assertEquals(test[0] + "/" + skeleton, test[2], pattern); 71 } 72 } 73 74 @Test 75 public void TestSimple() { 76 // some simple use cases 77 ULocale locale = ULocale.GERMANY; 78 TimeZone zone = TimeZone.getTimeZone("Europe/Paris"); 79 80 // make from locale 81 DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(locale); 82 SimpleDateFormat format = new SimpleDateFormat(gen.getBestPattern("MMMddHmm"), locale); 83 format.setTimeZone(zone); 84 assertEquals("simple format: MMMddHmm", "14. Okt., 08:58", format.format(sampleDate)); 85 // (a generator can be built from scratch, but that is not a typical use case) 86 87 // modify the generator by adding patterns 88 DateTimePatternGenerator.PatternInfo returnInfo = new DateTimePatternGenerator.PatternInfo(); 89 gen.addPattern("d'. von' MMMM", true, returnInfo); 90 // the returnInfo is mostly useful for debugging problem cases 91 format.applyPattern(gen.getBestPattern("MMMMdHmm")); 92 assertEquals("modified format: MMMdHmm", "14. von Oktober, 08:58", format.format(sampleDate)); 93 94 // get a pattern and modify it 95 format = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale); 96 format.setTimeZone(zone); 97 String pattern = format.toPattern(); 98 assertEquals("full-date", "Donnerstag, 14. Oktober 1999 um 08:58:59 Mitteleurop\u00E4ische Sommerzeit", format.format(sampleDate)); 99 100 // modify it to change the zone. 101 String newPattern = gen.replaceFieldTypes(pattern, "vvvv"); 102 format.applyPattern(newPattern); 103 assertEquals("full-date: modified zone", "Donnerstag, 14. Oktober 1999 um 08:58:59 Mitteleurop\u00E4ische Zeit", format.format(sampleDate)); 104 105 // add test of basic cases 106 107 //lang YYYYMMM MMMd MMMdhmm hmm hhmm Full Date-Time 108 // 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 109 DateTimePatternGenerator enGen = DateTimePatternGenerator.getInstance(ULocale.ENGLISH); 110 TimeZone enZone = TimeZone.getTimeZone("Etc/GMT"); 111 SimpleDateFormat enFormat = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, ULocale.ENGLISH); 112 enFormat.setTimeZone(enZone); 113 String[][] tests = { 114 {"yyyyMMMdd", "Oct 14, 1999"}, 115 {"yyyyqqqq", "4th quarter 1999"}, 116 {"yMMMdd", "Oct 14, 1999"}, 117 {"EyyyyMMMdd", "Thu, Oct 14, 1999"}, 118 {"yyyyMMdd", "10/14/1999"}, 119 {"yyyyMMM", "Oct 1999"}, 120 {"yyyyMM", "10/1999"}, 121 {"yyMM", "10/99"}, 122 {"yMMMMMd", "O 14, 1999"}, // narrow format 123 {"EEEEEMMMMMd", "T, O 14"}, // narrow format 124 {"MMMd", "Oct 14"}, 125 {"MMMdhmm", "Oct 14, 6:58 AM"}, 126 {"EMMMdhmms", "Thu, Oct 14, 6:58:59 AM"}, 127 {"MMdhmm", "10/14, 6:58 AM"}, 128 {"EEEEMMMdhmms", "Thursday, Oct 14, 6:58:59 AM"}, 129 {"yyyyMMMddhhmmss", "Oct 14, 1999, 6:58:59 AM"}, // (fixed expected result per ticket 6872<-7180) 130 {"EyyyyMMMddhhmmss", "Thu, Oct 14, 1999, 6:58:59 AM"}, // (fixed expected result per ticket 6872<-7180) 131 {"hmm", "6:58 AM"}, 132 {"hhmm", "6:58 AM"}, // (fixed expected result per ticket 6872<-7180) 133 {"hhmmVVVV", "6:58 AM GMT"}, // (fixed expected result per ticket 6872<-7180) 134 }; 135 for (int i = 0; i < tests.length; ++i) { 136 final String testSkeleton = tests[i][0]; 137 String pat = enGen.getBestPattern(testSkeleton); 138 enFormat.applyPattern(pat); 139 String formattedDate = enFormat.format(sampleDate); 140 assertEquals("Testing skeleton '" + testSkeleton + "' with " + sampleDate, tests[i][1], formattedDate); 141 } 142 } 143 144 @Test 145 public void TestRoot() { 146 DateTimePatternGenerator rootGen = DateTimePatternGenerator.getInstance(ULocale.ROOT); 147 SimpleDateFormat rootFormat = new SimpleDateFormat(rootGen.getBestPattern("yMdHms"), ULocale.ROOT); 148 rootFormat.setTimeZone(gmt); 149 // *** expected result should be "1999-10-14 6:58:59" with current data, changed test temporarily to match current result, needs investigation 150 assertEquals("root format: yMdHms", "1999-10-14 06:58:59", rootFormat.format(sampleDate)); 151 } 152 153 @Test 154 public void TestEmpty() { 155 // now nothing 156 DateTimePatternGenerator nullGen = DateTimePatternGenerator.getEmptyInstance(); 157 SimpleDateFormat format = new SimpleDateFormat(nullGen.getBestPattern("yMdHms"), ULocale.ROOT); 158 TimeZone rootZone = TimeZone.getTimeZone("Etc/GMT"); 159 format.setTimeZone(rootZone); 160 } 161 162 @Test 163 public void TestPatternParser() { 164 StringBuffer buffer = new StringBuffer(); 165 PatternTokenizer pp = new PatternTokenizer() 166 .setIgnorableCharacters(new UnicodeSet("[-]")) 167 .setSyntaxCharacters(new UnicodeSet("[a-zA-Z]")) 168 .setEscapeCharacters(new UnicodeSet("[b#]")) 169 .setUsingQuote(true); 170 logln("Using Quote"); 171 for (int i = 0; i < patternTestData.length; ++i) { 172 String patternTest = (String) patternTestData[i]; 173 CheckPattern(buffer, pp, patternTest); 174 } 175 String[] randomSet = {"abcdef", "$12!@#-", "'\\"}; 176 for (int i = 0; i < RANDOM_COUNT; ++i) { 177 String patternTest = getRandomString(randomSet, 0, 10); 178 CheckPattern(buffer, pp, patternTest); 179 } 180 logln("Using Backslash"); 181 pp.setUsingQuote(false).setUsingSlash(true); 182 for (int i = 0; i < patternTestData.length; ++i) { 183 String patternTest = (String) patternTestData[i]; 184 CheckPattern(buffer, pp, patternTest); 185 } 186 for (int i = 0; i < RANDOM_COUNT; ++i) { 187 String patternTest = getRandomString(randomSet, 0, 10); 188 CheckPattern(buffer, pp, patternTest); 189 } 190 } 191 192 Random random = new java.util.Random(-1); 193 194 private String getRandomString(String[] randomList, int minLen, int maxLen) { 195 StringBuffer result = new StringBuffer(); 196 int len = random.nextInt(maxLen + 1 - minLen) + minLen; 197 for (int i = minLen; i < len; ++ i) { 198 String source = randomList[random.nextInt(randomList.length)]; // don't bother with surrogates 199 char ch = source.charAt(random.nextInt(source.length())); 200 UTF16.append(result, ch); 201 } 202 return result.toString(); 203 } 204 205 private void CheckPattern(StringBuffer buffer, PatternTokenizer pp, String patternTest) { 206 pp.setPattern(patternTest); 207 if (DEBUG && isVerbose()) { 208 showItems(buffer, pp, patternTest); 209 } 210 String normalized = pp.setStart(0).normalize(); 211 logln("input:\t<" + patternTest + ">" + "\tnormalized:\t<" + normalized + ">"); 212 String doubleNormalized = pp.setPattern(normalized).normalize(); 213 if (!normalized.equals(doubleNormalized)) { 214 errln("Normalization not idempotent:\t" + patternTest + "\tnormalized: " + normalized + "\tnormalized2: " + doubleNormalized); 215 // allow for debugging at the point of failure 216 if (DEBUG) { 217 pp.setPattern(patternTest); 218 normalized = pp.setStart(0).normalize(); 219 pp.setPattern(normalized); 220 showItems(buffer, pp, normalized); 221 doubleNormalized = pp.normalize(); 222 } 223 } 224 } 225 226 private void showItems(StringBuffer buffer, PatternTokenizer pp, String patternTest) { 227 logln("input:\t<" + patternTest + ">"); 228 while (true) { 229 buffer.setLength(0); 230 int status = pp.next(buffer); 231 if (status == PatternTokenizer.DONE) break; 232 String lit = ""; 233 if (status != PatternTokenizer.SYNTAX ) { 234 lit = "\t<" + pp.quoteLiteral(buffer) + ">"; 235 } 236 logln("\t" + statusName[status] + "\t<" + buffer + ">" + lit); 237 } 238 } 239 240 static final String[] statusName = {"DONE", "SYNTAX", "LITERAL", "BROKEN_QUOTE", "BROKEN_ESCAPE", "UNKNOWN"}; 241 242 @Test 243 public void TestBasic() { 244 ULocale uLocale = null; 245 DateTimePatternGenerator dtfg = null; 246 Date date = null; 247 for (int i = 0; i < dateTestData.length; ++i) { 248 if (dateTestData[i] instanceof ULocale) { 249 uLocale = (ULocale) dateTestData[i]; 250 dtfg = DateTimePatternGenerator.getInstance(uLocale); 251 if (GENERATE_TEST_DATA) logln("new ULocale(\"" + uLocale.toString() + "\"),"); 252 } else if (dateTestData[i] instanceof Date) { 253 date = (Date) dateTestData[i]; 254 if (GENERATE_TEST_DATA) logln("new Date(" + date.getTime()+ "L),"); 255 } else if (dateTestData[i] instanceof String) { 256 String testSkeleton = (String) dateTestData[i]; 257 String pattern = dtfg.getBestPattern(testSkeleton); 258 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale); 259 String formatted = sdf.format(date); 260 if (GENERATE_TEST_DATA) logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},"); 261 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date)); 262 } else { 263 String[] testPair = (String[]) dateTestData[i]; 264 String testSkeleton = testPair[0]; 265 String testFormatted = testPair[1]; 266 String pattern = dtfg.getBestPattern(testSkeleton); 267 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale); 268 String formatted = sdf.format(date); 269 if (GENERATE_TEST_DATA) { 270 logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},"); 271 } else if (!formatted.equals(testFormatted)) { 272 errln(uLocale + "\tformatted string doesn't match test case: " + testSkeleton + "\t generated: " + pattern + "\t expected: " + testFormatted + "\t got: " + formatted); 273 if (true) { // debug 274 pattern = dtfg.getBestPattern(testSkeleton); 275 sdf = new SimpleDateFormat(pattern, uLocale); 276 formatted = sdf.format(date); 277 } 278 } 279 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date)); 280 } 281 } 282 } 283 284 static final Object[] patternTestData = { 285 "'$f''#c", 286 "'' 'a", 287 "'.''.'", 288 "\\u0061\\\\", 289 "mm.dd 'dd ' x", 290 "'' ''", 291 }; 292 293 // can be generated by using GENERATE_TEST_DATA. Must be reviewed before adding 294 static final Object[] dateTestData = { 295 new Date(916300739123L), // 1999-01-13T23:58:59.123,0-0800 296 297 new ULocale("en_US"), 298 new String[] {"yM", "1/1999"}, 299 new String[] {"yMMM", "Jan 1999"}, 300 new String[] {"yMd", "1/13/1999"}, 301 new String[] {"yMMMd", "Jan 13, 1999"}, 302 new String[] {"Md", "1/13"}, 303 new String[] {"MMMd", "Jan 13"}, 304 new String[] {"MMMMd", "January 13"}, 305 new String[] {"yQQQ", "Q1 1999"}, 306 new String[] {"hhmm", "11:58 PM"}, 307 new String[] {"HHmm", "23:58"}, 308 new String[] {"jjmm", "11:58 PM"}, 309 new String[] {"mmss", "58:59"}, 310 new String[] {"yyyyMMMM", "January 1999"}, // (new item for testing 6872<-5702) 311 new String[] {"MMMEd", "Wed, Jan 13"}, 312 new String[] {"Ed", "13 Wed"}, 313 new String[] {"jmmssSSS", "11:58:59.123 PM"}, 314 new String[] {"JJmm", "11:58"}, 315 316 new ULocale("en_US@calendar=japanese"), // (new locale for testing ticket 6872<-5702) 317 new String[] {"yM", "1/11 H"}, 318 new String[] {"yMMM", "Jan 11 Heisei"}, 319 new String[] {"yMd", "1/13/11 H"}, 320 new String[] {"yMMMd", "Jan 13, 11 Heisei"}, 321 new String[] {"Md", "1/13"}, 322 new String[] {"MMMd", "Jan 13"}, 323 new String[] {"MMMMd", "January 13"}, 324 new String[] {"yQQQ", "Q1 11 Heisei"}, 325 new String[] {"hhmm", "11:58 PM"}, 326 new String[] {"HHmm", "23:58"}, 327 new String[] {"jjmm", "11:58 PM"}, 328 new String[] {"mmss", "58:59"}, 329 new String[] {"yyyyMMMM", "January 11 Heisei"}, 330 new String[] {"MMMEd", "Wed, Jan 13"}, 331 new String[] {"Ed", "13 Wed"}, 332 new String[] {"jmmssSSS", "11:58:59.123 PM"}, 333 new String[] {"JJmm", "11:58"}, 334 335 new ULocale("de_DE"), 336 new String[] {"yM", "1.1999"}, 337 new String[] {"yMMM", "Jan. 1999"}, 338 new String[] {"yMd", "13.1.1999"}, 339 new String[] {"yMMMd", "13. Jan. 1999"}, 340 new String[] {"Md", "13.1."}, // 13.1 341 new String[] {"MMMd", "13. Jan."}, 342 new String[] {"MMMMd", "13. Januar"}, 343 new String[] {"yQQQ", "Q1 1999"}, 344 new String[] {"hhmm", "11:58 nachm."}, 345 new String[] {"HHmm", "23:58"}, 346 new String[] {"jjmm", "23:58"}, 347 new String[] {"mmss", "58:59"}, 348 new String[] {"yyyyMMMM", "Januar 1999"}, // (new item for testing 6872<-5702) 349 new String[] {"MMMEd", "Mi., 13. Jan."}, 350 new String[] {"Ed", "Mi., 13."}, 351 new String[] {"jmmssSSS", "23:58:59,123"}, 352 new String[] {"JJmm", "23:58"}, 353 354 new ULocale("fi"), 355 new String[] {"yM", "1.1999"}, // (fixed expected result per ticket 6872<-6626) 356 new String[] {"yMMM", "tammi 1999"}, // (fixed expected result per ticket 6872<-7007) 357 new String[] {"yMd", "13.1.1999"}, 358 new String[] {"yMMMd", "13. tammik. 1999"}, 359 new String[] {"Md", "13.1."}, 360 new String[] {"MMMd", "13. tammik."}, 361 new String[] {"MMMMd", "13. tammikuuta"}, 362 new String[] {"yQQQ", "1. nelj. 1999"}, 363 new String[] {"hhmm", "11.58 ip."}, 364 new String[] {"HHmm", "23.58"}, 365 new String[] {"jjmm", "23.58"}, 366 new String[] {"mmss", "58.59"}, 367 new String[] {"yyyyMMMM", "tammikuu 1999"}, // (new item for testing 6872<-5702,7007) 368 new String[] {"MMMEd", "ke 13. tammik."}, 369 new String[] {"Ed", "ke 13."}, 370 new String[] {"jmmssSSS", "23.58.59,123"}, 371 new String[] {"JJmm", "23.58"}, 372 373 new ULocale("es"), 374 new String[] {"yM", "1/1999"}, 375 new String[] {"yMMM", "ene. 1999"}, 376 new String[] {"yMd", "13/1/1999"}, 377 new String[] {"yMMMd", "13 ene. 1999"}, 378 new String[] {"Md", "13/1"}, 379 new String[] {"MMMd", "13 ene."}, 380 new String[] {"MMMMd", "13 de enero"}, 381 new String[] {"yQQQ", "T1 1999"}, 382 new String[] {"hhmm", "11:58 p. m."}, 383 new String[] {"HHmm", "23:58"}, 384 new String[] {"jjmm", "23:58"}, 385 new String[] {"mmss", "58:59"}, 386 new String[] {"yyyyMMMM", "enero de 1999"}, 387 new String[] {"MMMEd", "mi\u00E9., 13 ene."}, 388 new String[] {"Ed", "mi\u00E9. 13"}, 389 new String[] {"jmmssSSS", "23:58:59,123"}, 390 new String[] {"JJmm", "23:58"}, 391 392 new ULocale("ja"), // (new locale for testing ticket 6872<-6626) 393 new String[] {"yM", "1999/1"}, 394 new String[] {"yMMM", "1999\u5E741\u6708"}, 395 new String[] {"yMd", "1999/1/13"}, 396 new String[] {"yMMMd", "1999\u5E741\u670813\u65E5"}, 397 new String[] {"Md", "1/13"}, 398 new String[] {"MMMd", "1\u670813\u65E5"}, 399 new String[] {"MMMMd", "1\u670813\u65E5"}, 400 new String[] {"yQQQ", "1999/Q1"}, 401 new String[] {"hhmm", "\u5348\u5F8C11:58"}, 402 new String[] {"HHmm", "23:58"}, 403 new String[] {"jjmm", "23:58"}, 404 new String[] {"mmss", "58:59"}, 405 new String[] {"yyyyMMMM", "1999\u5E741\u6708"}, // (new item for testing 6872<-5702) 406 new String[] {"MMMEd", "1\u670813\u65E5(\u6C34)"}, 407 new String[] {"Ed", "13\u65E5(\u6C34)"}, 408 new String[] {"jmmssSSS", "23:58:59.123"}, 409 new String[] {"JJmm", "23:58"}, 410 411 new ULocale("ja@calendar=japanese"), // (new locale for testing ticket 6872<-5702) 412 new String[] {"yM", "\u5E73\u621011/1"}, 413 new String[] {"yMMM", "\u5E73\u621011\u5E741\u6708"}, 414 new String[] {"yMd", "\u5E73\u621011/1/13"}, 415 new String[] {"yMMMd", "\u5E73\u621011\u5E741\u670813\u65E5"}, 416 new String[] {"Md", "1/13"}, 417 new String[] {"MMMd", "1\u670813\u65E5"}, 418 new String[] {"MMMMd", "1\u670813\u65E5"}, 419 new String[] {"yQQQ", "\u5E73\u621011/Q1"}, 420 new String[] {"hhmm", "\u5348\u5F8C11:58"}, 421 new String[] {"HHmm", "23:58"}, 422 new String[] {"jjmm", "23:58"}, 423 new String[] {"mmss", "58:59"}, 424 new String[] {"yyyyMMMM", "\u5E73\u621011\u5E741\u6708"}, 425 new String[] {"MMMEd", "1\u670813\u65E5(\u6C34)"}, 426 new String[] {"Ed", "13\u65E5(\u6C34)"}, 427 new String[] {"jmmssSSS", "23:58:59.123"}, 428 new String[] {"JJmm", "23:58"}, 429 430 new ULocale("zh_Hans_CN"), 431 new String[] {"yM", "1999\u5E741\u6708"}, 432 new String[] {"yMMM", "1999\u5E741\u6708"}, // (fixed expected result per ticket 6872<-6626) 433 new String[] {"yMd", "1999/1/13"}, 434 new String[] {"yMMMd", "1999\u5E741\u670813\u65E5"}, // (fixed expected result per ticket 6872<-6626) 435 new String[] {"Md", "1/13"}, 436 new String[] {"MMMd", "1\u670813\u65E5"}, // (fixed expected result per ticket 6872<-6626) 437 new String[] {"MMMMd", "1\u670813\u65E5"}, 438 new String[] {"yQQQ", "1999\u5E74\u7B2C1\u5B63\u5EA6"}, 439 new String[] {"hhmm", "\u4E0B\u534811:58"}, 440 new String[] {"HHmm", "23:58"}, 441 new String[] {"jjmm", "\u4E0B\u534811:58"}, 442 new String[] {"mmss", "58:59"}, 443 new String[] {"yyyyMMMM", "1999\u5E741\u6708"}, // (new item for testing 6872<-5702) 444 new String[] {"MMMEd", "1\u670813\u65E5\u5468\u4E09"}, 445 new String[] {"Ed", "13\u65E5\u5468\u4E09"}, 446 new String[] {"jmmssSSS", "\u4E0B\u534811:58:59.123"}, 447 new String[] {"JJmm", "11:58"}, 448 449 new ULocale("zh_TW@calendar=roc"), // (new locale for testing ticket 6872<-5702) 450 new String[] {"yM", "\u6C11\u570B88/1"}, 451 new String[] {"yMMM", "\u6C11\u570B88\u5E741\u6708"}, 452 new String[] {"yMd", "\u6C11\u570B88/1/13"}, 453 new String[] {"yMMMd", "\u6C11\u570B88\u5E741\u670813\u65E5"}, 454 new String[] {"Md", "1/13"}, 455 new String[] {"MMMd", "1\u670813\u65E5"}, 456 new String[] {"MMMMd", "1\u670813\u65E5"}, 457 new String[] {"yQQQ", "\u6C11\u570B88\u5E741\u5B63"}, 458 new String[] {"hhmm", "\u4E0B\u534811:58"}, 459 new String[] {"HHmm", "23:58"}, 460 new String[] {"jjmm", "\u4E0B\u534811:58"}, 461 new String[] {"mmss", "58:59"}, 462 new String[] {"yyyyMMMM", "\u6C11\u570B88\u5E741\u6708"}, 463 new String[] {"MMMEd", "1\u670813\u65E5\u9031\u4E09"}, 464 new String[] {"Ed", "13 \u9031\u4E09"}, 465 new String[] {"jmmssSSS", "\u4E0B\u534811:58:59.123"}, 466 new String[] {"JJmm", "11:58"}, 467 468 new ULocale("ru"), 469 new String[] {"yM", "01.1999"}, 470 new String[] {"yMMM", "\u044F\u043D\u0432. 1999 \u0433."}, 471 new String[] {"yMd", "13.01.1999"}, 472 new String[] {"yMMMd", "13 \u044F\u043D\u0432. 1999 \u0433."}, 473 new String[] {"Md", "13.01"}, 474 new String[] {"MMMd", "13 \u044F\u043D\u0432."}, 475 new String[] {"MMMMd", "13 \u044F\u043D\u0432\u0430\u0440\u044F"}, 476 new String[] {"yQQQ", "1-\u0439 \u043A\u0432. 1999 \u0433."}, 477 new String[] {"hhmm", "11:58 \u041F\u041F"}, 478 new String[] {"HHmm", "23:58"}, 479 new String[] {"jjmm", "23:58"}, 480 new String[] {"mmss", "58:59"}, 481 new String[] {"yyyyMMMM", "\u044F\u043D\u0432\u0430\u0440\u044C 1999 \u0433."}, 482 new String[] {"MMMEd", "\u0441\u0440, 13 \u044F\u043D\u0432."}, 483 new String[] {"Ed", "\u0441\u0440, 13"}, 484 new String[] {"jmmssSSS", "23:58:59,123"}, 485 new String[] {"JJmm", "23:58"}, 486 487 new ULocale("zh@calendar=chinese"), 488 new String[] {"yM", "1998\u620A\u5BC5\u5E74\u5341\u4E00\u6708"}, 489 new String[] {"yMMM", "1998\u620A\u5BC5\u5E74\u5341\u4E00\u6708"}, 490 new String[] {"yMd", "1998\u5E74\u5341\u4E00\u670826"}, 491 new String[] {"yMMMd", "1998\u5E74\u5341\u4E00\u670826"}, 492 new String[] {"Md", "11-26"}, 493 new String[] {"MMMd", "\u5341\u4E00\u670826\u65E5"}, 494 new String[] {"MMMMd", "\u5341\u4E00\u670826\u65E5"}, 495 new String[] {"yQQQ", "1998\u620A\u5BC5\u5E74\u7B2C\u56DB\u5B63\u5EA6"}, 496 new String[] {"hhmm", "\u4E0B\u534811:58"}, 497 new String[] {"HHmm", "23:58"}, 498 new String[] {"jjmm", "\u4E0B\u534811:58"}, 499 new String[] {"mmss", "58:59"}, 500 new String[] {"yyyyMMMM", "1998\u620A\u5BC5\u5E74\u5341\u4E00\u6708"}, 501 new String[] {"MMMEd", "\u5341\u4E00\u670826\u65E5\u5468\u4E09"}, 502 new String[] {"Ed", "26\u65E5\u5468\u4E09"}, 503 new String[] {"jmmssSSS", "\u4E0B\u534811:58:59.123"}, 504 new String[] {"JJmm", "11:58"}, 505 }; 506 507 @Test 508 public void DayMonthTest() { 509 final ULocale locale = ULocale.FRANCE; 510 511 // set up the generator 512 DateTimePatternGenerator dtpgen 513 = DateTimePatternGenerator.getInstance(locale); 514 515 // get a pattern for an abbreviated month and day 516 final String pattern = dtpgen.getBestPattern("MMMd"); 517 SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale); 518 519 // use it to format (or parse) 520 String formatted = formatter.format(new Date()); 521 logln("formatted=" + formatted); 522 // for French, the result is "13 sept." 523 } 524 525 @Test 526 public void TestOrdering() { 527 ULocale[] locales = ULocale.getAvailableLocales(); 528 for (int i = 0; i < locales.length; ++i) { 529 for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) { 530 for (int style2 = DateFormat.FULL; style2 < style1; ++style2) { 531 checkCompatible(style1, style2, locales[i]); 532 } 533 } 534 } 535 } 536 537 @Test 538 public void TestReplacingZoneString() { 539 Date testDate = new Date(); 540 TimeZone testTimeZone = TimeZone.getTimeZone("America/New_York"); 541 TimeZone bogusTimeZone = new SimpleTimeZone(1234, "Etc/Unknown"); 542 Calendar calendar = Calendar.getInstance(); 543 ParsePosition parsePosition = new ParsePosition(0); 544 545 ULocale[] locales = ULocale.getAvailableLocales(); 546 int count = 0; 547 for (int i = 0; i < locales.length; ++i) { 548 // skip the country locales unless we are doing exhaustive tests 549 if (getExhaustiveness() < 6) { 550 if (locales[i].getCountry().length() > 0) { 551 continue; 552 } 553 } 554 count++; 555 // Skipping some test case in the non-exhaustive mode to reduce the test time 556 //ticket#6503 557 if(getExhaustiveness()<=5 && count%3!=0){ 558 continue; 559 } 560 logln(locales[i].toString()); 561 DateTimePatternGenerator dtpgen 562 = DateTimePatternGenerator.getInstance(locales[i]); 563 564 for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) { 565 final SimpleDateFormat oldFormat = (SimpleDateFormat) DateFormat.getTimeInstance(style1, locales[i]); 566 String pattern = oldFormat.toPattern(); 567 String newPattern = dtpgen.replaceFieldTypes(pattern, "VVVV"); // replaceZoneString(pattern, "VVVV"); 568 if (newPattern.equals(pattern)) { 569 continue; 570 } 571 // verify that it roundtrips parsing 572 SimpleDateFormat newFormat = new SimpleDateFormat(newPattern, locales[i]); 573 newFormat.setTimeZone(testTimeZone); 574 String formatted = newFormat.format(testDate); 575 calendar.setTimeZone(bogusTimeZone); 576 parsePosition.setIndex(0); 577 newFormat.parse(formatted, calendar, parsePosition); 578 if (parsePosition.getErrorIndex() >= 0) { 579 errln("Failed parse with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted.substring(0,parsePosition.getErrorIndex()) + "{}" + formatted.substring(parsePosition.getErrorIndex()) + "\""); 580 } else if (!calendar.getTimeZone().getID().equals(testTimeZone.getID())) { 581 errln("Failed timezone roundtrip with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted + "\",\t" + calendar.getTimeZone().getID() + " != " + testTimeZone.getID()); 582 } else { 583 logln(locales[i] + ":\t\"" + pattern + "\" => \t\"" + newPattern + "\"\t" + formatted); 584 } 585 } 586 } 587 } 588 589 @Test 590 public void TestVariableCharacters() { 591 UnicodeSet valid = new UnicodeSet("[G y Y u U r Q q M L l w W d D F g E e c a h H K k m s S A z Z O v V X x]"); 592 for (char c = 0; c < 0xFF; ++c) { 593 boolean works = false; 594 try { 595 VariableField vf = new VariableField(String.valueOf(c), true); 596 logln("VariableField " + vf.toString()); 597 works = true; 598 } catch (Exception e) {} 599 if (works != valid.contains(c)) { 600 if (works) { 601 errln("VariableField can be created with illegal character: " + c); 602 } else { 603 errln("VariableField can't be created with legal character: " + c); 604 } 605 } 606 } 607 } 608 609 static String[] DATE_STYLE_NAMES = { 610 "FULL", "LONG", "MEDIUM", "SHORT" 611 }; 612 613 /** 614 * @param fullOrder 615 * @param longOrder 616 */ 617 private void checkCompatible(int style1, int style2, ULocale uLocale) { 618 DateOrder order1 = getOrdering(style1, uLocale); 619 DateOrder order2 = getOrdering(style2, uLocale); 620 if (!order1.hasSameOrderAs(order2)) { 621 // Note: This test case was updated by #6806 and no longer reports 622 // ordering difference as an error case. 623 logln(showOrderComparison(uLocale, style1, style2, order1, order2)); 624 } 625 } 626 627 private String showOrderComparison(ULocale uLocale, int style1, int style2, DateOrder order1, DateOrder order2) { 628 String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(style1, uLocale)).toPattern(); 629 String pattern2 = ((SimpleDateFormat) DateFormat.getDateInstance(style2, uLocale)).toPattern(); 630 return "Mismatch in in ordering for " + uLocale + ": " + DATE_STYLE_NAMES[style1] + ": " + order1 + ", <" + pattern1 631 + ">; " 632 + DATE_STYLE_NAMES[style2] + ": " + order2 + ", <" + pattern2 + ">; " ; 633 } 634 635 /** 636 * Main date fields -- Poor-man's enum -- change to real enum when we get JDK 1.5 637 */ 638 public static class DateFieldType { 639 private String name; 640 private DateFieldType(String string) { 641 name = string; 642 } 643 644 public static DateFieldType 645 YEAR = new DateFieldType("YEAR"), 646 MONTH = new DateFieldType("MONTH"), 647 DAY = new DateFieldType("DAY"); 648 649 @Override 650 public String toString() { 651 return name; 652 } 653 } 654 655 /** 656 * Simple struct for output from getOrdering 657 */ 658 static class DateOrder { 659 int monthLength; 660 DateFieldType[] fields = new DateFieldType[3]; 661 662 public boolean isCompatible(DateOrder other) { 663 return monthLength == other.monthLength; 664 } 665 /** 666 * @param order2 667 * @return 668 */ 669 public boolean hasSameOrderAs(DateOrder other) { 670 // TODO Auto-generated method stub 671 return fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2]; 672 } 673 @Override 674 public String toString() { 675 return "{" + monthLength + ", " + fields[0] + ", " + fields[1] + ", " + fields[2] + "}"; 676 } 677 @Override 678 public boolean equals(Object that) { 679 DateOrder other = (DateOrder) that; 680 return monthLength == other.monthLength && fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2]; 681 } 682 } 683 684 DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser (); 685 DateTimePatternGenerator generator = DateTimePatternGenerator.getEmptyInstance(); 686 687 private Calendar sampleCalendar; 688 { 689 sampleCalendar = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles")); 690 sampleCalendar.set(1999, Calendar.OCTOBER, 13, 23, 58, 59); 691 } 692 693 private Date sampleDate = sampleCalendar.getTime(); 694 private TimeZone gmt = TimeZone.getTimeZone("Etc/GMT"); 695 696 /** 697 * 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 698 * <pre> 699 * String pattern = ((SimpleDateFormat) DateFormat.getTimeInstance(style, locale)).toPattern(); 700 * </pre> 701 * @param pattern original pattern to change, such as "HH:mm zzzz" 702 * @param newZone Must be: z, zzzz, Z, ZZZZ, v, vvvv, V, or VVVV 703 * @return 704 */ 705 public String replaceZoneString(String pattern, String newZone) { 706 final List itemList = formatParser.set(pattern).getItems(); 707 boolean changed = false; 708 for (int i = 0; i < itemList.size(); ++i) { 709 Object item = itemList.get(i); 710 if (item instanceof VariableField) { 711 VariableField variableField = (VariableField) item; 712 if (variableField.getType() == DateTimePatternGenerator.ZONE) { 713 if (!variableField.toString().equals(newZone)) { 714 changed = true; 715 itemList.set(i, new VariableField(newZone, true)); 716 } 717 } 718 } 719 } 720 return changed ? formatParser.toString() : pattern; 721 } 722 723 public boolean containsZone(String pattern) { 724 for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) { 725 Object item = it.next(); 726 if (item instanceof VariableField) { 727 VariableField variableField = (VariableField) item; 728 if (variableField.getType() == DateTimePatternGenerator.ZONE) { 729 return true; 730 } 731 } 732 } 733 return false; 734 } 735 736 /** 737 * Get the ordering from a particular date format. Best is to use 738 * DateFormat.FULL to get the format with String form month (like "January") 739 * and DateFormat.SHORT for the numeric format order. They may be different. 740 * (Theoretically all 4 formats could be different but that never happens in 741 * practice.) 742 * 743 * @param style 744 * DateFormat.FULL..DateFormat.SHORT 745 * @param locale 746 * desired locale. 747 * @return 748 * @return list of ordered items DateFieldType (I 749 * didn't know what form you really wanted so this is just a 750 * stand-in.) 751 */ 752 private DateOrder getOrdering(int style, ULocale locale) { 753 // and the date pattern 754 String pattern = ((SimpleDateFormat) DateFormat.getDateInstance(style, locale)).toPattern(); 755 int count = 0; 756 DateOrder result = new DateOrder(); 757 758 for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) { 759 Object item = it.next(); 760 if (!(item instanceof String)) { 761 // the first character of the variable field determines the type, 762 // according to CLDR. 763 String variableField = item.toString(); 764 switch (variableField.charAt(0)) { 765 case 'y': case 'Y': case 'u': 766 result.fields[count++] = DateFieldType.YEAR; 767 break; 768 case 'M': case 'L': 769 result.monthLength = variableField.length(); 770 if (result.monthLength < 2) { 771 result.monthLength = 2; 772 } 773 result.fields[count++] = DateFieldType.MONTH; 774 break; 775 case 'd': case 'D': case 'F': case 'g': 776 result.fields[count++] = DateFieldType.DAY; 777 break; 778 } 779 } 780 } 781 return result; 782 } 783 784 /* Tests the method 785 * public static DateTimePatternGenerator getInstance() 786 */ 787 @Test 788 public void TestGetInstance(){ 789 try{ 790 DateTimePatternGenerator.getInstance(); 791 } catch(Exception e){ 792 errln("DateTimePatternGenerator.getInstance() was not suppose to " + 793 "return an exception."); 794 } 795 } 796 797 /* Tests the method 798 * public String getSkeleton(String pattern) 799 */ 800 @Test 801 public void TestGetSkeleton(){ 802 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 803 String[] cases = {"MMDD","MMMDD","MMM-DD","DD/MMM","ddM","MMMMd"}; 804 String[] results = {"MMDD","MMMDD","MMMDD","MMMDD","Mdd","MMMMd"}; 805 for(int i=0; i<cases.length; i++){ 806 if(!dtpg.getSkeleton(cases[i]).equals(results[i])){ 807 errln("DateTimePatternGenerator.getSkeleton(String) did " + 808 "return the expected result when passing " + cases[i] + 809 " and expected " + results[i] + " but got " + 810 dtpg.getSkeleton(cases[i])); 811 } 812 } 813 } 814 815 /* Tests the method 816 * public String getCanonicalSkeletonAllowingDuplicates(String pattern) 817 */ 818 public void TestGetCanonicalSkeletonAllowingDuplicates(){ 819 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 820 String[] cases = {"GyQMwEdaHmsSv","LegH","Legh"}; 821 String[] results = {"GyQMwEdHmsSv","MEdH","MEdh"}; 822 for(int i=0; i<cases.length; i++){ 823 if(!dtpg.getCanonicalSkeletonAllowingDuplicates(cases[i]).equals(results[i])){ 824 errln("DateTimePatternGenerator.getCanonicalSkeletonAllowingDuplicates(String) did " + 825 "return the expected result when passing " + cases[i] + 826 " and expected " + results[i] + " but got " + 827 dtpg.getCanonicalSkeletonAllowingDuplicates(cases[i])); 828 } 829 } 830 } 831 832 /* Tests the method 833 * public String getBaseSkeleton(String pattern) 834 */ 835 @Test 836 public void TestGetBaseSkeleton(){ 837 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 838 String[] cases = {"MMDD","MMMDD","MMM-DD","DD/MMM","ddM","MMMMd"}; 839 String[] results = {"MD","MMMD","MMMD","MMMD","Md","MMMMd"}; 840 for(int i=0; i<cases.length; i++){ 841 if(!dtpg.getBaseSkeleton(cases[i]).equals(results[i])){ 842 errln("DateTimePatternGenerator.getSkeleton(String) did " + 843 "return the expected result when passing " + cases[i] + 844 " and expected " + results[i] + " but got " + 845 dtpg.getBaseSkeleton(cases[i])); 846 } 847 } 848 } 849 850 /* Tests the method 851 * public Map<String, String> getSkeletons(Map<String, String> result) 852 */ 853 @Test 854 public void TestGetSkeletons(){ 855 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 856 // Tests when "if (result == null)" is true 857 try{ 858 dtpg.getSkeletons(null); 859 } catch(Exception e){ 860 errln("DateTimePatternGenerator.getSkeletons(Map) was suppose to " + 861 "return a new LinkedHashMap for a null parameter."); 862 } 863 864 // Tests when "if (result == null)" is false 865 Map<String,String> mm = new LinkedHashMap<String, String>(); 866 try{ 867 dtpg.getSkeletons(mm); 868 } catch(Exception e){ 869 errln("DateTimePatternGenerator.getSkeletons(Map) was suppose to " + 870 "return a new LinkedHashMap for a LinkedHashMap parameter."); 871 } 872 } 873 874 /* Tests the method 875 * public Set<String> getBaseSkeletons(Set<String> result) 876 */ 877 @Test 878 public void TestGetBaseSkeletons(){ 879 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 880 // Tests when "if (result == null)" is true 881 try{ 882 dtpg.getBaseSkeletons(null); 883 } catch(Exception e){ 884 errln("DateTimePatternGenerator.getBaseSkeletons(Map) was suppose to " + 885 "return a new LinkedHashMap for a null parameter."); 886 } 887 888 // Tests when "if (result == null)" is false 889 Set<String> mm = new HashSet<String>(); 890 try{ 891 dtpg.getBaseSkeletons(mm); 892 } catch(Exception e){ 893 errln("DateTimePatternGenerator.getBaseSkeletons(Map) was suppose to " + 894 "return a new LinkedHashMap for a HashSet parameter."); 895 } 896 } 897 898 /* Tests the method 899 * public String getDecimal() 900 */ 901 @Test 902 public void TestGetDecimal(){ 903 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 904 if(!dtpg.getDecimal().equals(".")){ 905 errln("DateTimePatternGenerator.getDecimal() was to return '.' " + 906 "when the object gets a new instance."); 907 } 908 909 String[] cases = {",","-","","*","&","a","0"}; 910 for(int i=0; i<cases.length; i++){ 911 dtpg.setDecimal(cases[i]); 912 if(!dtpg.getDecimal().equals(cases[i])){ 913 errln("DateTimePatternGenerator.getDecimal() was to return " + cases[i] + 914 "when setting decimal with " + cases[i]); 915 } 916 } 917 } 918 919 /* Tests the method 920 * public Collection<String> getRedundants(Collection<String> output) 921 */ 922 @Test 923 public void TestGetRedundants(){ 924 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 925 926 // Tests when "if (output == null)" is true 927 try{ 928 dtpg.getRedundants(null); 929 } catch(Exception e){ 930 errln("DateTimeGenerator.getRedundants was not supposed to return " + 931 "an exception when passing a null parameter: " + e); 932 } 933 934 // Tests when "if (output == null)" is false 935 try{ 936 Collection<String> out = new LinkedHashSet<String>(); 937 dtpg.getRedundants(out); 938 } catch(Exception e){ 939 errln("DateTimeGenerator.getRedundants was not supposed to return " + 940 "an exception when passing a new LinkedHashSet<String>() parameter: " + e); 941 } 942 } 943 944 /* Tests the method 945 * public String setAppendItemFormat(int field) 946 */ 947 @Test 948 public void TestSetAppendItemFormat(){ 949 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 950 String[] cases = {"d","u","m","m","y"}; 951 for(int i=0; i<cases.length; i++){ 952 dtpg.setAppendItemFormat(i, cases[i]); 953 if(!dtpg.getAppendItemFormat(i).equals(cases[i])){ 954 errln("DateTimePatternGenerator.getAppendItemFormat(int field) " + 955 "did not return as expected. Value set at " + i + " was " + 956 cases[i] + " but got back " + dtpg.getAppendItemFormat(i)); 957 } 958 } 959 } 960 961 /* Tests the method 962 * public String getAppendItemFormat(int field) 963 */ 964 @Test 965 public void TestGetAppendItemFormat(){ 966 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(ULocale.ENGLISH); 967 int[] fields = {DateTimePatternGenerator.ERA,DateTimePatternGenerator.DAY,DateTimePatternGenerator.SECOND}; 968 String[] results = {"{0} {1}","{0} ({2}: {1})","{0} ({2}: {1})"}; 969 for(int i=0; i<fields.length; i++){ 970 if(!dtpg.getAppendItemFormat(fields[i]).equals(results[i])){ 971 errln("DateTimePatternGenerator.getAppendItemFormat(int field) " + 972 "did not return as expected. For field " + fields[i] + ", was expecting " + 973 results[i] + " but got back " + dtpg.getAppendItemFormat(fields[i])); 974 } 975 } 976 } 977 978 /* Tests the method 979 * public String getAppendItemName(int field) 980 */ 981 private final class AppendItemName { 982 public int field; 983 public String name; 984 public AppendItemName(int f, String n) { 985 field = f; 986 name = n; 987 } 988 } 989 990 @Test 991 public void TestGetAppendItemName(){ 992 final AppendItemName[] appendItemNames = { 993 new AppendItemName( DateTimePatternGenerator.YEAR, "vuosi" ), 994 new AppendItemName( DateTimePatternGenerator.MONTH, "kuukausi" ), 995 new AppendItemName( DateTimePatternGenerator.WEEKDAY, "viikonp\u00E4iv\u00E4" ), 996 new AppendItemName( DateTimePatternGenerator.DAY, "p\u00E4iv\u00E4" ), 997 new AppendItemName( DateTimePatternGenerator.HOUR, "tunti" ), 998 }; 999 1000 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 1001 String[] cases = {"d","u","m","m","y"}; 1002 for(int i=0; i<cases.length; i++){ 1003 dtpg.setAppendItemName(i, cases[i]); 1004 if(!dtpg.getAppendItemName(i).equals(cases[i])){ 1005 errln("DateTimePatternGenerator.getAppendItemFormat(int field) " + 1006 "did not return as expected. Value set at " + i + " was " + 1007 cases[i] + " but got back " + dtpg.getAppendItemName(i)); 1008 } 1009 } 1010 1011 DateTimePatternGenerator dtpgfi = DateTimePatternGenerator.getInstance(ULocale.forLanguageTag("fi")); 1012 for (AppendItemName appendItemName: appendItemNames) { 1013 String name = dtpgfi.getAppendItemName(appendItemName.field); 1014 if (!name.equals(appendItemName.name)) { 1015 errln("DateTimePatternGenerator.getAppendItemName returns invalid name for field " + appendItemName.field 1016 + ": got " + name + " but expected " + appendItemName.name); 1017 } 1018 } 1019 } 1020 1021 /* Tests the method 1022 * public static boolean isSingleField(String skeleton) 1023 */ 1024 @SuppressWarnings("static-access") 1025 @Test 1026 public void TestIsSingleField(){ 1027 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 1028 String[] cases = {" ", "m","mm","md","mmd","mmdd"}; 1029 boolean[] results = {true,true,true,false,false,false}; 1030 for(int i=0; i<cases.length; i++){ 1031 if(dtpg.isSingleField(cases[i]) != results[i]){ 1032 errln("DateTimePatternGenerator.isSingleField(String skeleton) " + 1033 "did not return as expected. Value passed was " + cases[i] + 1034 " but got back " + dtpg.isSingleField(cases[i])); 1035 } 1036 } 1037 } 1038 1039 /* Tests the method 1040 * public Object freeze() 1041 * public Object cloneAsThawed() 1042 */ 1043 @Test 1044 public void TestFreezeAndCloneAsThawed(){ 1045 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 1046 1047 if(dtpg.isFrozen() != false){ 1048 errln("DateTimePatternGenerator.isFrozen() is suppose to return false " + 1049 "for a DateTimePatternGenerator object that was just " + 1050 "created."); 1051 } 1052 1053 dtpg.freeze(); 1054 if(dtpg.isFrozen() != true){ 1055 errln("DateTimePatternGenerator.isFrozen() is suppose to return true " + 1056 "for a DateTimePatternGenerator object that was just " + 1057 "created and freeze."); 1058 } 1059 1060 DateTimePatternGenerator dtpg2 = dtpg.cloneAsThawed(); 1061 if(dtpg.isFrozen() != false){ 1062 errln("DateTimePatternGenerator.isFrozen() is suppose to return false " + 1063 "for a DateTimePatternGenerator object that was just " + 1064 "clone as thawed."); 1065 } 1066 if(dtpg2.isFrozen() != false){ 1067 errln("DateTimePatternGenerator.isFrozen() is suppose to return false " + 1068 "for a second DateTimePatternGenerator object that was just " + 1069 "clone as thawed."); 1070 } 1071 } 1072 1073 /* Tests the method 1074 * public Object clone() 1075 */ 1076 @Test 1077 public void TestClone(){ 1078 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); 1079 DateTimePatternGenerator dtpg2 = (DateTimePatternGenerator) dtpg.clone(); 1080 dtpg = (DateTimePatternGenerator) dtpg2.clone(); 1081 } 1082 1083 /* Tests the constructor 1084 * public VariableField(String string) 1085 */ 1086 //TODO(junit) why is this "unused" 1087 @SuppressWarnings("unused") 1088 @Test 1089 public void TestVariableField_String(){ 1090 String[] cases = {"d","mm","aa"}; 1091 String[] invalid = {null,"","dummy"}; 1092 for(int i=0; i<cases.length; i++){ 1093 try{ 1094 VariableField vf = new VariableField(cases[i]); 1095 } catch(Exception e){ 1096 errln("VariableField constructor was not suppose to return " + 1097 "an exception when created when passing " + cases[i]); 1098 } 1099 } 1100 for(int i=0; i<invalid.length; i++){ 1101 try{ 1102 VariableField vf = new VariableField(invalid[i]); 1103 errln("VariableField constructor was suppose to return " + 1104 "an exception when created when passing " + invalid[i]); 1105 } catch(Exception e){} 1106 } 1107 } 1108 1109 /* Tests the method 1110 * public FormatParser set(String string, boolean strict) 1111 */ 1112 @Test 1113 public void TestSet(){ 1114 FormatParser fp = new FormatParser(); 1115 //Tests when "if (string.length() == 0)" is true 1116 try{ 1117 fp.set("",true); 1118 }catch(Exception e){ 1119 errln("FormatParser.set(String,boolean) was not suppose to " + 1120 "return an exception."); 1121 } 1122 } 1123 1124 /* Tests the method 1125 * public String toString() 1126 */ 1127 @Test 1128 public void TestToString(){ 1129 FormatParser fp = new FormatParser(); 1130 if(!fp.toString().equals("")){ 1131 errln("FormatParser.toString() was suppose to return an " + 1132 "empty string for a new FormatParser object."); 1133 } 1134 1135 String[] cases = {"m","d","y","mm","mmm","mm dd","mm':'dd","mm-dd-yyyy"}; 1136 String[] results = {"m","d","y","mm","mmm","mm dd","mm:dd","mm-dd-yyyy"}; 1137 for(int i=0; i<cases.length; i++){ 1138 fp.set(cases[i]); 1139 if(!fp.toString().equals(results[i])){ 1140 errln("FormatParser.toString() was suppose to return " + results[i] + 1141 " after setting the object. Got: " + fp.toString()); 1142 } 1143 } 1144 } 1145 1146 /* Tests the method 1147 * public boolean hasDateAndTimeFields() 1148 */ 1149 @Test 1150 public void TestHasDateAndTimeFields(){ 1151 FormatParser fp = new FormatParser(); 1152 if(fp.hasDateAndTimeFields() != false){ 1153 errln("FormatParser.hasDateAndTimeFields() was suppose to return " + 1154 "false when a new object is created."); 1155 } 1156 1157 String[] cases = {"MMDDYY", "HHMMSS", "", "MM/DD/YYYY HH:MM:SS", 1158 "MMDDYY HHMMSS", "HHMMSS MMDDYYYY", "HMS MDY"}; 1159 boolean[] results = {false,true,false,true,true,true,true}; 1160 for(int i=0; i<cases.length; i++){ 1161 fp.set(cases[i]); 1162 if(fp.hasDateAndTimeFields() != results[i]){ 1163 errln("FormatParser.hasDateAndTimeFields() was suppose to " + 1164 "return " + results[i] + " but returned " + 1165 fp.hasDateAndTimeFields() + " for parameter " + 1166 cases[i] + " that is set to FormatParser."); 1167 } 1168 } 1169 } 1170 1171 /* Tests the method 1172 * private void checkFrozen() 1173 * from public void setDateTimeFormat(String dateTimeFormat) 1174 */ 1175 @Test 1176 public void TestCheckFrozen(){ 1177 // Tests when "if (isFrozen())" is true 1178 DateTimePatternGenerator dt = DateTimePatternGenerator.getInstance(); 1179 try{ 1180 dt.freeze(); 1181 dt.setDateTimeFormat("MMDDYYYY"); 1182 errln("DateTimePatternGenerator.checkFrozen() was suppose to " + 1183 "return an exception when trying to setDateTimeFormat " + 1184 "for a frozen object."); 1185 } catch(Exception e){} 1186 dt = dt.cloneAsThawed(); 1187 } 1188 1189 /* Tests the method 1190 * public String getFields(String pattern) 1191 */ 1192 @Test 1193 public void TestGetFields(){ 1194 DateTimePatternGenerator dt = DateTimePatternGenerator.getInstance(); 1195 String[] cases = {"MMDDYY", "HHMMSS", "", "MM/DD/YYYY HH:MM:SS", 1196 "MMDDYY HHMMSS", "HHMMSS MMDDYYYY", "HMS MDY"}; 1197 String[] results = {"{Month:N}{Day_Of_Year:N}{Year:N}", 1198 "{Hour:N}{Month:N}{Fractional_Second:N}","", 1199 "{Month:N}/{Day_Of_Year:N}/{Year:N} {Hour:N}:{Month:N}:{Fractional_Second:N}", 1200 "{Month:N}{Day_Of_Year:N}{Year:N} {Hour:N}{Month:N}{Fractional_Second:N}", 1201 "{Hour:N}{Month:N}{Fractional_Second:N} {Month:N}{Day_Of_Year:N}{Year:N}", 1202 "{Hour:N}{Month:N}{Fractional_Second:N} {Month:N}{Day_Of_Year:N}{Year:N}"}; 1203 for(int i=0; i<cases.length; i++){ 1204 if(!dt.getFields(cases[i]).equals(results[i])) { 1205 errln("DateTimePatternGenerator.getFields(String) did not " + 1206 "not return an expected result when passing " + cases[i] + 1207 ". Got " + dt.getFields(cases[i]) + " but expected " + 1208 results[i]); 1209 } 1210 } 1211 } 1212 1213 /* 1214 * Test case for DateFormatPatternGenerator threading problem #7169 1215 */ 1216 @Test 1217 public void TestT7169() { 1218 Thread[] workers = new Thread[10]; 1219 for (int i = 0 ; i < workers.length; i++) { 1220 workers[i] = new Thread(new Runnable() { 1221 @Override 1222 public void run() { 1223 try { 1224 for (int i = 0; i < 50; i++) { 1225 DateTimePatternGenerator patternGenerator = 1226 DateTimePatternGenerator.getFrozenInstance(ULocale.US); 1227 patternGenerator.getBestPattern("MMMMd"); 1228 } 1229 } catch (Exception e) { 1230 errln("FAIL: Caught an exception (frozen)" + e); 1231 } 1232 try { 1233 for (int i = 0; i < 50; i++) { 1234 DateTimePatternGenerator patternGenerator = 1235 DateTimePatternGenerator.getInstance(ULocale.US); 1236 patternGenerator.getBestPattern("MMMMd"); 1237 } 1238 } catch (Exception e) { 1239 errln("FAIL: Caught an exception " + e); 1240 } 1241 } 1242 }); 1243 } 1244 for (Thread wk : workers) { 1245 wk.start(); 1246 } 1247 for (Thread wk : workers) { 1248 try { 1249 wk.join(); 1250 } catch (InterruptedException ie) { 1251 1252 } 1253 } 1254 } 1255 1256 /** 1257 * Test handling of options 1258 * 1259 * For reference, as of ICU 4.3.3, 1260 * root/gregorian has 1261 * Hm{"H:mm"} 1262 * Hms{"H:mm:ss"} 1263 * hm{"h:mm a"} 1264 * hms{"h:mm:ss a"} 1265 * en/gregorian has 1266 * Hm{"H:mm"} 1267 * Hms{"H:mm:ss"} 1268 * hm{"h:mm a"} 1269 * be/gregorian has 1270 * HHmmss{"HH.mm.ss"} 1271 * Hm{"HH.mm"} 1272 * hm{"h.mm a"} 1273 * hms{"h.mm.ss a"} 1274 */ 1275 private final class TestOptionsItem { 1276 public String locale; 1277 public String skeleton; 1278 public String expectedPattern; 1279 public int options; 1280 // Simple constructor 1281 public TestOptionsItem(String loc, String skel, String expectedPat, int opts) { 1282 locale = loc; 1283 skeleton = skel; 1284 expectedPattern = expectedPat; 1285 options = opts; 1286 } 1287 } 1288 @Test 1289 public void TestOptions() { 1290 final TestOptionsItem[] testOptionsData = { 1291 new TestOptionsItem( "en", "Hmm", "HH:mm", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1292 new TestOptionsItem( "en", "HHmm", "HH:mm", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1293 new TestOptionsItem( "en", "hhmm", "h:mm a", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1294 new TestOptionsItem( "en", "Hmm", "HH:mm", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ), 1295 new TestOptionsItem( "en", "HHmm", "HH:mm", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ), 1296 new TestOptionsItem( "en", "hhmm", "hh:mm a", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ), 1297 new TestOptionsItem( "da", "Hmm", "HH.mm", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1298 new TestOptionsItem( "da", "HHmm", "HH.mm", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1299 new TestOptionsItem( "da", "hhmm", "h.mm a", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1300 new TestOptionsItem( "da", "Hmm", "H.mm", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ), 1301 new TestOptionsItem( "da", "HHmm", "HH.mm", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ), 1302 new TestOptionsItem( "da", "hhmm", "hh.mm a", DateTimePatternGenerator.MATCH_HOUR_FIELD_LENGTH ), 1303 // 1304 new TestOptionsItem( "en", "yyyy", "yyyy", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1305 new TestOptionsItem( "en", "YYYY", "YYYY", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1306 new TestOptionsItem( "en", "U", "y", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1307 new TestOptionsItem( "en@calendar=japanese", "yyyy", "y G", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1308 new TestOptionsItem( "en@calendar=japanese", "YYYY", "Y G", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1309 new TestOptionsItem( "en@calendar=japanese", "U", "y G", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1310 new TestOptionsItem( "en@calendar=chinese", "yyyy", "r(U)", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1311 new TestOptionsItem( "en@calendar=chinese", "YYYY", "Y(Y)", DateTimePatternGenerator.MATCH_NO_OPTIONS ), // not a good result, want r(Y) or r(U) 1312 new TestOptionsItem( "en@calendar=chinese", "U", "r(U)", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1313 new TestOptionsItem( "en@calendar=chinese", "Gy", "r(U)", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1314 new TestOptionsItem( "en@calendar=chinese", "GU", "r(U)", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1315 new TestOptionsItem( "en@calendar=chinese", "ULLL", "MMM U", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1316 new TestOptionsItem( "en@calendar=chinese", "yMMM", "MMM r(U)", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1317 new TestOptionsItem( "en@calendar=chinese", "GUMMM", "MMM r(U)", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1318 new TestOptionsItem( "zh@calendar=chinese", "yyyy", "rU\u5E74", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1319 new TestOptionsItem( "zh@calendar=chinese", "YYYY", "YY\u5E74", DateTimePatternGenerator.MATCH_NO_OPTIONS ), // not a good result, want r(Y) or r(U) 1320 new TestOptionsItem( "zh@calendar=chinese", "U", "rU\u5E74", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1321 new TestOptionsItem( "zh@calendar=chinese", "Gy", "rU\u5E74", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1322 new TestOptionsItem( "zh@calendar=chinese", "GU", "rU\u5E74", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1323 new TestOptionsItem( "zh@calendar=chinese", "ULLL", "U\u5E74MMM", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1324 new TestOptionsItem( "zh@calendar=chinese", "yMMM", "rU\u5E74MMM", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1325 new TestOptionsItem( "zh@calendar=chinese", "GUMMM", "rU\u5E74MMM", DateTimePatternGenerator.MATCH_NO_OPTIONS ), 1326 }; 1327 1328 for (int i = 0; i < testOptionsData.length; ++i) { 1329 ULocale uloc = new ULocale(testOptionsData[i].locale); 1330 DateTimePatternGenerator dtpgen = DateTimePatternGenerator.getInstance(uloc); 1331 String pattern = dtpgen.getBestPattern(testOptionsData[i].skeleton, testOptionsData[i].options); 1332 if (pattern.compareTo(testOptionsData[i].expectedPattern) != 0) { 1333 errln("Locale " + testOptionsData[i].locale + ", skeleton " + testOptionsData[i].skeleton + 1334 ", options " + ((testOptionsData[i].options != 0)? "!=0": "==0") + 1335 ", expected pattern " + testOptionsData[i].expectedPattern + ", got " + pattern); 1336 } 1337 } 1338 } 1339 1340 /** 1341 * Test that DTPG can handle all valid pattern character / length combinations 1342 */ 1343 private final class AllFieldsTestItem { 1344 public char patternChar; 1345 public int[] fieldLengths; 1346 public String mustIncludeOneOf; 1347 // Simple constructor 1348 public AllFieldsTestItem(char pC, int[] fL, String mI) { 1349 patternChar = pC; 1350 fieldLengths = fL; 1351 mustIncludeOneOf = mI; 1352 } 1353 } 1354 1355 @Test 1356 public void TestAllFieldPatterns() { 1357 String[] localeNames = { 1358 "root", 1359 "root@calendar=japanese", 1360 "root@calendar=chinese", 1361 "en", 1362 "en@calendar=japanese", 1363 "en@calendar=chinese", 1364 }; 1365 final AllFieldsTestItem[] testItems = { 1366 // pat fieldLengths generated pattern must 1367 // chr to test include one of these 1368 new AllFieldsTestItem( 'G', new int[]{1,2,3,4,5}, "G" ), // era 1369 // year 1370 new AllFieldsTestItem( 'y', new int[]{1,2,3,4}, "yU" ), // year 1371 new AllFieldsTestItem( 'Y', new int[]{1,2,3,4}, "Y" ), // year for week of year 1372 new AllFieldsTestItem( 'u', new int[]{1,2,3,4,5}, "yuU" ), // extended year 1373 new AllFieldsTestItem( 'U', new int[]{1,2,3,4,5}, "yU" ), // cyclic year name 1374 // quarter 1375 new AllFieldsTestItem( 'Q', new int[]{1,2,3,4}, "Qq" ), // x 1376 new AllFieldsTestItem( 'q', new int[]{1,2,3,4}, "Qq" ), // standalone 1377 // month 1378 new AllFieldsTestItem( 'M', new int[]{1,2,3,4,5}, "ML" ), // x 1379 new AllFieldsTestItem( 'L', new int[]{1,2,3,4,5}, "ML" ), // standalone 1380 // week 1381 new AllFieldsTestItem( 'w', new int[]{1,2}, "w" ), // week of year 1382 new AllFieldsTestItem( 'W', new int[]{1}, "W" ), // week of month 1383 // day 1384 new AllFieldsTestItem( 'd', new int[]{1,2}, "d" ), // day of month 1385 new AllFieldsTestItem( 'D', new int[]{1,2,3}, "D" ), // day of year 1386 new AllFieldsTestItem( 'F', new int[]{1}, "F" ), // day of week in month 1387 new AllFieldsTestItem( 'g', new int[]{7}, "g" ), // modified julian day 1388 // weekday 1389 new AllFieldsTestItem( 'E', new int[]{1,2,3,4,5,6}, "Eec" ), // day of week 1390 new AllFieldsTestItem( 'e', new int[]{1,2,3,4,5,6}, "Eec" ), // local day of week 1391 new AllFieldsTestItem( 'c', new int[]{1,2,3,4,5,6}, "Eec" ), // standalone local day of week 1392 // day period 1393 // new AllFieldsTestItem( 'a', new int[]{1}, "a" ), // am or pm // not clear this one is supposed to work (it doesn't) 1394 // hour 1395 new AllFieldsTestItem( 'h', new int[]{1,2}, "hK" ), // 12 (1-12) 1396 new AllFieldsTestItem( 'H', new int[]{1,2}, "Hk" ), // 24 (0-23) 1397 new AllFieldsTestItem( 'K', new int[]{1,2}, "hK" ), // 12 (0-11) 1398 new AllFieldsTestItem( 'k', new int[]{1,2}, "Hk" ), // 24 (1-24) 1399 new AllFieldsTestItem( 'j', new int[]{1,2}, "hHKk" ), // locale default 1400 // minute 1401 new AllFieldsTestItem( 'm', new int[]{1,2}, "m" ), // x 1402 // second & fractions 1403 new AllFieldsTestItem( 's', new int[]{1,2}, "s" ), // x 1404 new AllFieldsTestItem( 'S', new int[]{1,2,3,4}, "S" ), // fractional second 1405 new AllFieldsTestItem( 'A', new int[]{8}, "A" ), // milliseconds in day 1406 // zone 1407 new AllFieldsTestItem( 'z', new int[]{1,2,3,4}, "z" ), // x 1408 new AllFieldsTestItem( 'Z', new int[]{1,2,3,4,5}, "Z" ), // x 1409 new AllFieldsTestItem( 'O', new int[]{1,4}, "O" ), // x 1410 new AllFieldsTestItem( 'v', new int[]{1,4}, "v" ), // x 1411 new AllFieldsTestItem( 'V', new int[]{1,2,3,4}, "V" ), // x 1412 new AllFieldsTestItem( 'X', new int[]{1,2,3,4,5}, "X" ), // x 1413 new AllFieldsTestItem( 'x', new int[]{1,2,3,4,5}, "x" ), // x 1414 }; 1415 final int FIELD_LENGTH_MAX = 8; 1416 1417 for (String localeName: localeNames) { 1418 ULocale uloc = new ULocale(localeName); 1419 DateTimePatternGenerator dtpgen = DateTimePatternGenerator.getInstance(uloc); 1420 for (AllFieldsTestItem testItem: testItems) { 1421 char[] skelBuf = new char[FIELD_LENGTH_MAX]; 1422 for (int chrIndx = 0; chrIndx < FIELD_LENGTH_MAX; chrIndx++) { 1423 skelBuf[chrIndx] = testItem.patternChar; 1424 } 1425 for (int lenIndx = 0; lenIndx < testItem.fieldLengths.length; lenIndx++) { 1426 int skelLen = testItem.fieldLengths[lenIndx]; 1427 if (skelLen > FIELD_LENGTH_MAX) { 1428 continue; 1429 }; 1430 String skeleton = new String(skelBuf, 0, skelLen); 1431 String pattern = dtpgen.getBestPattern(skeleton); 1432 if (pattern.length() <= 0) { 1433 errln("DateTimePatternGenerator getBestPattern for locale " + localeName + 1434 ", skeleton " + skeleton + ", produces 0-length pattern"); 1435 } else { 1436 // test that resulting pattern has at least one char in mustIncludeOneOf 1437 boolean inQuoted = false; 1438 int patIndx, patLen = pattern.length(); 1439 for (patIndx = 0; patIndx < patLen; patIndx++) { 1440 char c = pattern.charAt(patIndx); 1441 if (c == '\'') { 1442 inQuoted = !inQuoted; 1443 } else if (!inQuoted && c <= 'z' && c >= 'A') { 1444 if (testItem.mustIncludeOneOf.indexOf(c) >= 0) { 1445 break; 1446 } 1447 } 1448 } 1449 if (patIndx >= patLen) { 1450 errln("DateTimePatternGenerator getBestPattern for locale " + localeName + 1451 ", skeleton " + skeleton + 1452 ", produces pattern without required chars: " + pattern); 1453 } 1454 } 1455 } 1456 } 1457 } 1458 } 1459 1460 @Test 1461 public void TestJavaLocale() { 1462 DateTimePatternGenerator genUloc = DateTimePatternGenerator.getInstance(ULocale.GERMANY); 1463 DateTimePatternGenerator genLoc = DateTimePatternGenerator.getInstance(Locale.GERMANY); 1464 1465 final String pat = "yMdHms"; 1466 String patUloc = genUloc.getBestPattern(pat); 1467 String patLoc = genLoc.getBestPattern(pat); 1468 1469 assertEquals("German pattern 'yMdHms' - getInstance with Java Locale", patUloc, patLoc); 1470 } 1471 1472 /* Tests the method 1473 * public static int getAppendFormatNumber(String string) 1474 */ 1475 @Test 1476 public void TestGetAppendFormatNumber(){ 1477 int fieldNum; 1478 fieldNum = DateTimePatternGenerator.getAppendFormatNumber("Era"); 1479 assertEquals("DateTimePatternGenerator.getAppendFormatNumber for Era", 0, fieldNum); 1480 fieldNum = DateTimePatternGenerator.getAppendFormatNumber("Timezone"); 1481 assertEquals("DateTimePatternGenerator.getAppendFormatNumber for Timezone", 15, fieldNum); 1482 } 1483 1484 /* 1485 * Coverage for methods otherwise not covered by other tests. 1486 */ 1487 @Test 1488 public void TestCoverage() { 1489 DateTimePatternGenerator dtpg; 1490 1491 // DateTimePatternGenerator#getDefaultHourFormatChar 1492 // DateTimePatternGenerator#setDefaultHourFormatChar 1493 { 1494 dtpg = DateTimePatternGenerator.getEmptyInstance(); 1495 assertEquals("Default hour char on empty instance", 'H', dtpg.getDefaultHourFormatChar()); 1496 dtpg.setDefaultHourFormatChar('e'); 1497 assertEquals("Default hour char after explicit set", 'e', dtpg.getDefaultHourFormatChar()); 1498 dtpg = DateTimePatternGenerator.getInstance(ULocale.ENGLISH); 1499 assertEquals("Default hour char on populated English instance", 'h', dtpg.getDefaultHourFormatChar()); 1500 } 1501 1502 // DateTimePatternGenerator#getSkeletonAllowingDuplicates 1503 // DateTimePatternGenerator#getCanonicalSkeletonAllowingDuplicates 1504 // DateTimePatternGenerator#getCanonicalChar 1505 { 1506 dtpg = DateTimePatternGenerator.getInstance(ULocale.ENGLISH); 1507 assertEquals("Example skeleton with no duplicate fields", "MMMdd", dtpg.getSkeleton("dd/MMM")); 1508 assertEquals("Should return same result as getSkeleton with no duplicate fields", 1509 dtpg.getSkeleton("dd/MMM"), dtpg.getSkeletonAllowingDuplicates("dd/MMM")); 1510 1511 try { 1512 dtpg.getSkeleton("dd/MMM Zz"); 1513 fail("getSkeleton should throw upon duplicate fields"); 1514 } catch(IllegalArgumentException e) { 1515 assertEquals("getSkeleton should throw upon duplicate fields", 1516 "Conflicting fields:\tZ, z\t in dd/MMM Zz", e.getMessage()); 1517 } 1518 1519 assertEquals("Should not throw upon duplicate fields", 1520 "MMMddZ", dtpg.getSkeletonAllowingDuplicates("dd/MMM Zz")); 1521 assertEquals("Should not throw upon duplicate fields and should return Canonical fields", 1522 "MMMddv", dtpg.getCanonicalSkeletonAllowingDuplicates("dd/MMM Zz")); 1523 } 1524 1525 // DistanceInfo#toString 1526 // DateTimePatternGenerator#showMask 1527 try { 1528 String actual = invokeToString("android.icu.text.DateTimePatternGenerator$DistanceInfo"); 1529 assertEquals("DistanceInfo toString", "missingFieldMask: , extraFieldMask: ", actual); 1530 } catch(Exception e) { 1531 errln("Couldn't call DistanceInfo.toString(): " + e.toString()); 1532 } 1533 1534 // DateTimePatternGenerator#skeletonsAreSimilar 1535 // DateTimePatternGenerator#getSet 1536 { 1537 dtpg = DateTimePatternGenerator.getInstance(ULocale.ENGLISH); 1538 assertTrue("Trivial skeletonsAreSimilar", dtpg.skeletonsAreSimilar("MMMdd", "MMMdd")); 1539 assertTrue("Different number of chars in skeletonsAreSimilar", dtpg.skeletonsAreSimilar("Mddd", "MMMdd")); 1540 assertFalse("Failure case for skeletonsAreSimilar", dtpg.skeletonsAreSimilar("mmDD", "MMMdd")); 1541 } 1542 } 1543 1544 @Test 1545 public void TestEmptyInstance() { 1546 DateTimePatternGenerator dtpg = DateTimePatternGenerator.getEmptyInstance(); 1547 String skeleton = "GrMMd"; 1548 String message = "DTPG getEmptyInstance should not throw exceptions on basic operations and should conform to " 1549 + "the example in setAppendItemFormat"; 1550 assertEquals(message, "G ├'F7': d┤ ├'F3': MM┤ ├'F1': y┤", dtpg.getBestPattern(skeleton)); 1551 dtpg.addPattern("d-MM-yyyy", false, new DateTimePatternGenerator.PatternInfo()); 1552 assertEquals(message, "d-MM-y ├'F0': G┤", dtpg.getBestPattern(skeleton)); 1553 dtpg.setAppendItemFormat(DateTimePatternGenerator.ERA, "{0}, {1}"); 1554 assertEquals(message, "d-MM-y, G", dtpg.getBestPattern(skeleton)); 1555 } 1556} 1557