2 *******************************************************************************
\r
3 * Copyright (C) 2006-2009, 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.Date;
\r
12 import java.util.Iterator;
\r
13 import java.util.List;
\r
14 import java.util.Random;
\r
16 import com.ibm.icu.dev.test.TestFmwk;
\r
17 import com.ibm.icu.impl.PatternTokenizer;
\r
18 import com.ibm.icu.impl.Utility;
\r
19 import com.ibm.icu.text.DateFormat;
\r
20 import com.ibm.icu.text.DateTimePatternGenerator;
\r
21 import com.ibm.icu.text.SimpleDateFormat;
\r
22 import com.ibm.icu.text.UTF16;
\r
23 import com.ibm.icu.text.UnicodeSet;
\r
24 import com.ibm.icu.text.DateTimePatternGenerator.VariableField;
\r
25 import com.ibm.icu.util.Calendar;
\r
26 import com.ibm.icu.util.GregorianCalendar;
\r
27 import com.ibm.icu.util.SimpleTimeZone;
\r
28 import com.ibm.icu.util.TimeZone;
\r
29 import com.ibm.icu.util.ULocale;
\r
31 public class DateTimeGeneratorTest extends TestFmwk {
\r
32 public static boolean GENERATE_TEST_DATA = System.getProperty("GENERATE_TEST_DATA") != null;
\r
33 public static int RANDOM_COUNT = 1000;
\r
34 public static boolean DEBUG = false;
\r
36 public static void main(String[] args) throws Exception {
\r
37 new DateTimeGeneratorTest().run(args);
\r
40 public void TestSimple() {
\r
41 // some simple use cases
\r
42 ULocale locale = ULocale.GERMANY;
\r
43 TimeZone zone = TimeZone.getTimeZone("Europe/Paris");
\r
46 DateTimePatternGenerator gen = DateTimePatternGenerator.getInstance(locale);
\r
47 SimpleDateFormat format = new SimpleDateFormat(gen.getBestPattern("MMMddHmm"), locale);
\r
48 format.setTimeZone(zone);
\r
49 assertEquals("simple format: MMMddHmm", "14. Okt 8:58", format.format(sampleDate));
\r
50 // (a generator can be built from scratch, but that is not a typical use case)
\r
52 // modify the generator by adding patterns
\r
53 DateTimePatternGenerator.PatternInfo returnInfo = new DateTimePatternGenerator.PatternInfo();
\r
54 gen.addPattern("d'. von' MMMM", true, returnInfo);
\r
55 // the returnInfo is mostly useful for debugging problem cases
\r
56 format.applyPattern(gen.getBestPattern("MMMMddHmm"));
\r
57 assertEquals("modified format: MMMddHmm", "14. von Oktober 8:58", format.format(sampleDate));
\r
59 // get a pattern and modify it
\r
60 format = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);
\r
61 format.setTimeZone(zone);
\r
62 String pattern = format.toPattern();
\r
63 assertEquals("full-date", "Donnerstag, 14. Oktober 1999 08:58:59 Mitteleurop\u00E4ische Sommerzeit", format.format(sampleDate));
\r
65 // modify it to change the zone.
\r
66 String newPattern = gen.replaceFieldTypes(pattern, "vvvv");
\r
67 format.applyPattern(newPattern);
\r
68 assertEquals("full-date: modified zone", "Donnerstag, 14. Oktober 1999 08:58:59 Frankreich", format.format(sampleDate));
\r
70 // add test of basic cases
\r
72 //lang YYYYMMM MMMd MMMdhmm hmm hhmm Full Date-Time
\r
73 // en Mar 2007 Mar 4 6:05 PM Mar 4 6:05 PM 06:05 PM Sunday, March 4, 2007 6:05:05 PM PT
\r
74 DateTimePatternGenerator enGen = DateTimePatternGenerator.getInstance(ULocale.ENGLISH);
\r
75 TimeZone enZone = TimeZone.getTimeZone("Etc/GMT");
\r
76 SimpleDateFormat enFormat = (SimpleDateFormat)DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, ULocale.ENGLISH);
\r
77 enFormat.setTimeZone(enZone);
\r
78 String[][] tests = {
\r
79 {"yyyyMMMdd", "Oct 14, 1999"},
\r
80 {"yyyyqqqq", "4th quarter 1999"},
\r
81 {"yMMMdd", "Oct 14, 1999"},
\r
82 {"EyyyyMMMdd", "Thu, Oct 14, 1999"},
\r
83 {"yyyyMMdd", "10/14/1999"},
\r
84 {"yyyyMMM", "Oct 1999"},
\r
85 {"yyyyMM", "10/1999"},
\r
87 {"yMMMMMd", "O 14, 1999"}, // narrow format
\r
88 {"EEEEEMMMMMd", "T, O 14"}, // narrow format
\r
90 {"MMMdhmm", "Oct 14 6:58 AM"},
\r
91 {"EMMMdhmms", "Thu, Oct 14 6:58:59 AM"},
\r
92 {"MMdhmm", "10/14 6:58 AM"},
\r
93 {"EEEEMMMdhmms", "Thursday, Oct 14 6:58:59 AM"},
\r
94 {"yyyyMMMddhhmmss", "Oct 14, 1999 06:58:59 AM"},
\r
95 {"EyyyyMMMddhhmmss", "Thu, Oct 14, 1999 06:58:59 AM"},
\r
97 {"hhmm", "06:58 AM"},
\r
98 {"hhmmVVVV", "06:58 AM GMT+00:00"},
\r
100 for (int i = 0; i < tests.length; ++i) {
\r
101 final String testSkeleton = tests[i][0];
\r
102 String pat = enGen.getBestPattern(testSkeleton);
\r
103 enFormat.applyPattern(pat);
\r
104 String formattedDate = enFormat.format(sampleDate);
\r
105 assertEquals("Testing skeleton '" + testSkeleton + "' with " + sampleDate, tests[i][1], formattedDate);
\r
109 public void TestRoot() {
\r
110 DateTimePatternGenerator rootGen = DateTimePatternGenerator.getInstance(ULocale.ROOT);
\r
111 SimpleDateFormat rootFormat = new SimpleDateFormat(rootGen.getBestPattern("yMdHms"), ULocale.ROOT);
\r
112 rootFormat.setTimeZone(gmt);
\r
113 assertEquals("root format: yMdHms", "1999-10-14 6:58:59", rootFormat.format(sampleDate));
\r
116 public void TestEmpty() {
\r
118 DateTimePatternGenerator nullGen = DateTimePatternGenerator.getEmptyInstance();
\r
119 SimpleDateFormat format = new SimpleDateFormat(nullGen.getBestPattern("yMdHms"), ULocale.ROOT);
\r
120 TimeZone rootZone = TimeZone.getTimeZone("Etc/GMT");
\r
121 format.setTimeZone(rootZone);
\r
124 public void TestPatternParser() {
\r
125 StringBuffer buffer = new StringBuffer();
\r
126 PatternTokenizer pp = new PatternTokenizer()
\r
127 .setIgnorableCharacters(new UnicodeSet("[-]"))
\r
128 .setSyntaxCharacters(new UnicodeSet("[a-zA-Z]"))
\r
129 .setEscapeCharacters(new UnicodeSet("[b#]"))
\r
130 .setUsingQuote(true);
\r
131 logln("Using Quote");
\r
132 for (int i = 0; i < patternTestData.length; ++i) {
\r
133 String patternTest = (String) patternTestData[i];
\r
134 CheckPattern(buffer, pp, patternTest);
\r
136 String[] randomSet = {"abcdef", "$12!@#-", "'\\"};
\r
137 for (int i = 0; i < RANDOM_COUNT; ++i) {
\r
138 String patternTest = getRandomString(randomSet, 0, 10);
\r
139 CheckPattern(buffer, pp, patternTest);
\r
141 logln("Using Backslash");
\r
142 pp.setUsingQuote(false).setUsingSlash(true);
\r
143 for (int i = 0; i < patternTestData.length; ++i) {
\r
144 String patternTest = (String) patternTestData[i];
\r
145 CheckPattern(buffer, pp, patternTest);
\r
147 for (int i = 0; i < RANDOM_COUNT; ++i) {
\r
148 String patternTest = getRandomString(randomSet, 0, 10);
\r
149 CheckPattern(buffer, pp, patternTest);
\r
153 Random random = new java.util.Random(-1);
\r
155 private String getRandomString(String[] randomList, int minLen, int maxLen) {
\r
156 StringBuffer result = new StringBuffer();
\r
157 int len = random.nextInt(maxLen + 1 - minLen) + minLen;
\r
158 for (int i = minLen; i < len; ++ i) {
\r
159 String source = randomList[random.nextInt(randomList.length)]; // don't bother with surrogates
\r
160 char ch = source.charAt(random.nextInt(source.length()));
\r
161 UTF16.append(result, ch);
\r
163 return result.toString();
\r
166 private void CheckPattern(StringBuffer buffer, PatternTokenizer pp, String patternTest) {
\r
167 pp.setPattern(patternTest);
\r
168 if (DEBUG && isVerbose()) {
\r
169 showItems(buffer, pp, patternTest);
\r
171 String normalized = pp.setStart(0).normalize();
\r
172 logln("input:\t<" + patternTest + ">" + "\tnormalized:\t<" + normalized + ">");
\r
173 String doubleNormalized = pp.setPattern(normalized).normalize();
\r
174 if (!normalized.equals(doubleNormalized)) {
\r
175 errln("Normalization not idempotent:\t" + patternTest + "\tnormalized: " + normalized + "\tnormalized2: " + doubleNormalized);
\r
176 // allow for debugging at the point of failure
\r
178 pp.setPattern(patternTest);
\r
179 normalized = pp.setStart(0).normalize();
\r
180 pp.setPattern(normalized);
\r
181 showItems(buffer, pp, normalized);
\r
182 doubleNormalized = pp.normalize();
\r
187 private void showItems(StringBuffer buffer, PatternTokenizer pp, String patternTest) {
\r
188 logln("input:\t<" + patternTest + ">");
\r
190 buffer.setLength(0);
\r
191 int status = pp.next(buffer);
\r
192 if (status == PatternTokenizer.DONE) break;
\r
194 if (status != PatternTokenizer.SYNTAX ) {
\r
195 lit = "\t<" + pp.quoteLiteral(buffer) + ">";
\r
197 logln("\t" + statusName[status] + "\t<" + buffer + ">" + lit);
\r
201 static final String[] statusName = {"DONE", "SYNTAX", "LITERAL", "BROKEN_QUOTE", "BROKEN_ESCAPE", "UNKNOWN"};
\r
203 public void TestBasic() {
\r
204 ULocale uLocale = null;
\r
205 DateTimePatternGenerator dtfg = null;
\r
207 for (int i = 0; i < dateTestData.length; ++i) {
\r
208 if (dateTestData[i] instanceof ULocale) {
\r
209 uLocale = (ULocale) dateTestData[i];
\r
210 dtfg = DateTimePatternGenerator.getInstance(uLocale);
\r
211 if (GENERATE_TEST_DATA) logln("new ULocale(\"" + uLocale.toString() + "\"),");
\r
212 } else if (dateTestData[i] instanceof Date) {
\r
213 date = (Date) dateTestData[i];
\r
214 if (GENERATE_TEST_DATA) logln("new Date(" + date.getTime()+ "L),");
\r
215 } else if (dateTestData[i] instanceof String) {
\r
216 String testSkeleton = (String) dateTestData[i];
\r
217 String pattern = dtfg.getBestPattern(testSkeleton);
\r
218 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale);
\r
219 String formatted = sdf.format(date);
\r
220 if (GENERATE_TEST_DATA) logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},");
\r
221 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date));
\r
223 String[] testPair = (String[]) dateTestData[i];
\r
224 String testSkeleton = testPair[0];
\r
225 String testFormatted = testPair[1];
\r
226 String pattern = dtfg.getBestPattern(testSkeleton);
\r
227 SimpleDateFormat sdf = new SimpleDateFormat(pattern, uLocale);
\r
228 String formatted = sdf.format(date);
\r
229 if (GENERATE_TEST_DATA) {
\r
230 logln("new String[] {\"" + testSkeleton + "\", \"" + Utility.escape(formatted) + "\"},");
\r
231 } else if (!formatted.equals(testFormatted)) {
\r
232 errln(uLocale + "\tformatted string doesn't match test case: " + testSkeleton + "\t generated: " + pattern + "\t expected: " + testFormatted + "\t got: " + formatted);
\r
233 if (true) { // debug
\r
234 pattern = dtfg.getBestPattern(testSkeleton);
\r
235 sdf = new SimpleDateFormat(pattern, uLocale);
\r
236 formatted = sdf.format(date);
\r
239 //logln(uLocale + "\t" + testSkeleton + "\t" + pattern + "\t" + sdf.format(date));
\r
244 static final Object[] patternTestData = {
\r
253 // can be generated by using GENERATE_TEST_DATA. Must be reviewed before adding
\r
254 static final Object[] dateTestData = {
\r
255 new Date(916300739000L), // 1999-01-13T23:58:59,0-0800
\r
256 new ULocale("en_US"),
\r
257 new String[] {"yM", "1/1999"},
\r
258 new String[] {"yMMM", "Jan 1999"},
\r
259 new String[] {"yMd", "1/13/1999"},
\r
260 new String[] {"yMMMd", "Jan 13, 1999"},
\r
261 new String[] {"Md", "1/13"},
\r
262 new String[] {"MMMd", "Jan 13"},
\r
263 new String[] {"yQQQ", "Q1 1999"},
\r
264 new String[] {"jjmm", "11:58 PM"},
\r
265 new String[] {"hhmm", "11:58 PM"},
\r
266 new String[] {"HHmm", "23:58"},
\r
267 new String[] {"mmss", "58:59"},
\r
268 new ULocale("zh_Hans_CN"),
\r
269 new String[] {"yM", "1999-1"},
\r
270 new String[] {"yMMM", "1999-01"},
\r
271 new String[] {"yMd", "1999\u5E741\u670813\u65E5"},
\r
272 new String[] {"yMMMd", "1999\u5E7401\u670813\u65E5"},
\r
273 new String[] {"Md", "1-13"},
\r
274 new String[] {"MMMd", "01-13"},
\r
275 new String[] {"yQQQ", "1999\u5E741\u5B63"},
\r
276 new String[] {"hhmm", "\u4E0B\u534811:58"},
\r
277 new String[] {"HHmm", "23:58"},
\r
278 new String[] {"mmss", "58:59"},
\r
279 new ULocale("de_DE"),
\r
280 new String[] {"yM", "1999-1"},
\r
281 new String[] {"yMMM", "Jan 1999"},
\r
282 new String[] {"yMd", "13.1.1999"},
\r
283 new String[] {"yMMMd", "13. Jan 1999"},
\r
284 new String[] {"Md", "13.1."}, // 13.1
\r
285 new String[] {"MMMd", "13. Jan"},
\r
286 new String[] {"yQQQ", "Q1 1999"},
\r
287 new String[] {"jjmm", "23:58"},
\r
288 new String[] {"hhmm", "11:58 nachm."},
\r
289 new String[] {"HHmm", "23:58"},
\r
290 new String[] {"mmss", "58:59"},
\r
292 new String[] {"yM", "1/1999"}, // 1.1999
\r
293 new String[] {"yMMM", "tammikuuta 1999"}, // tammi 1999
\r
294 new String[] {"yMd", "13.1.1999"},
\r
295 new String[] {"yMMMd", "13. tammikuuta 1999"},
\r
296 new String[] {"Md", "13.1."},
\r
297 new String[] {"MMMd", "13. tammikuuta"},
\r
298 new String[] {"yQQQ", "1. nelj./1999"}, // 1. nelj. 1999
\r
299 new String[] {"jjmm", "23.58"},
\r
300 new String[] {"hhmm", "11.58 ip."},
\r
301 new String[] {"HHmm", "23.58"},
\r
302 new String[] {"mmss", "58.59"},
\r
305 public void DayMonthTest() {
\r
306 final ULocale locale = ULocale.FRANCE;
\r
308 // set up the generator
\r
309 DateTimePatternGenerator dtpgen
\r
310 = DateTimePatternGenerator.getInstance(locale);
\r
312 // get a pattern for an abbreviated month and day
\r
313 final String pattern = dtpgen.getBestPattern("MMMd");
\r
314 SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale);
\r
316 // use it to format (or parse)
\r
317 String formatted = formatter.format(new Date());
\r
318 logln("formatted=" + formatted);
\r
319 // for French, the result is "13 sept."
\r
322 public void TestOrdering() {
\r
323 ULocale[] locales = ULocale.getAvailableLocales();
\r
324 for (int i = 0; i < locales.length; ++i) {
\r
325 for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) {
\r
326 for (int style2 = DateFormat.FULL; style2 < style1; ++style2) {
\r
327 checkCompatible(style1, style2, locales[i]);
\r
333 public void TestReplacingZoneString() {
\r
334 Date testDate = new Date();
\r
335 TimeZone testTimeZone = TimeZone.getTimeZone("America/New_York");
\r
336 TimeZone bogusTimeZone = new SimpleTimeZone(1234, "Etc/Unknown");
\r
337 Calendar calendar = Calendar.getInstance();
\r
338 ParsePosition parsePosition = new ParsePosition(0);
\r
340 ULocale[] locales = ULocale.getAvailableLocales();
\r
342 for (int i = 0; i < locales.length; ++i) {
\r
343 // skip the country locales unless we are doing exhaustive tests
\r
344 if (getInclusion() < 6) {
\r
345 if (locales[i].getCountry().length() > 0) {
\r
350 // Skipping some test case in the non-exhaustive mode to reduce the test time
\r
352 if(params.inclusion<=5 && count%3!=0){
\r
355 logln(locales[i].toString());
\r
356 DateTimePatternGenerator dtpgen
\r
357 = DateTimePatternGenerator.getInstance(locales[i]);
\r
359 for (int style1 = DateFormat.FULL; style1 <= DateFormat.SHORT; ++style1) {
\r
360 final SimpleDateFormat oldFormat = (SimpleDateFormat) DateFormat.getTimeInstance(style1, locales[i]);
\r
361 String pattern = oldFormat.toPattern();
\r
362 String newPattern = dtpgen.replaceFieldTypes(pattern, "VVVV"); // replaceZoneString(pattern, "VVVV");
\r
363 if (newPattern.equals(pattern)) {
\r
366 // verify that it roundtrips parsing
\r
367 SimpleDateFormat newFormat = new SimpleDateFormat(newPattern, locales[i]);
\r
368 newFormat.setTimeZone(testTimeZone);
\r
369 String formatted = newFormat.format(testDate);
\r
370 calendar.setTimeZone(bogusTimeZone);
\r
371 parsePosition.setIndex(0);
\r
372 newFormat.parse(formatted, calendar, parsePosition);
\r
373 if (parsePosition.getErrorIndex() >= 0) {
\r
374 errln("Failed parse with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted.substring(0,parsePosition.getErrorIndex()) + "{}" + formatted.substring(parsePosition.getErrorIndex()) + "\"");
\r
375 } else if (!calendar.getTimeZone().getID().equals(testTimeZone.getID())) {
\r
376 errln("Failed timezone roundtrip with VVVV:\t" + locales[i] + ",\t\"" + pattern + "\",\t\"" + newPattern + "\",\t\"" + formatted + "\",\t" + calendar.getTimeZone().getID() + " != " + testTimeZone.getID());
\r
378 logln(locales[i] + ":\t\"" + pattern + "\" => \t\"" + newPattern + "\"\t" + formatted);
\r
384 public void TestVariableCharacters() {
\r
385 UnicodeSet valid = new UnicodeSet("[G y Y u Q q M L w W d D F g E e c a h H K k m s S A z Z v V]");
\r
386 for (char c = 0; c < 0xFF; ++c) {
\r
387 boolean works = false;
\r
389 VariableField vf = new VariableField(String.valueOf(c), true);
\r
390 logln("VariableField " + vf.toString());
\r
392 } catch (Exception e) {}
\r
393 if (works != valid.contains(c)) {
\r
395 errln("VariableField can be created with illegal character: " + c);
\r
397 errln("VariableField can't be created with legal character: " + c);
\r
403 static String[] DATE_STYLE_NAMES = {
\r
404 "FULL", "LONG", "MEDIUM", "SHORT"
\r
411 private void checkCompatible(int style1, int style2, ULocale uLocale) {
\r
412 DateOrder order1 = getOrdering(style1, uLocale);
\r
413 DateOrder order2 = getOrdering(style2, uLocale);
\r
414 if (!order1.hasSameOrderAs(order2)) {
\r
415 if (order1.monthLength == order2.monthLength) { // error if have same month length, different ordering
\r
416 if (skipIfBeforeICU(4,3,0)) {
\r
417 logln(showOrderComparison(uLocale, style1, style2, order1, order2));
\r
419 errln(showOrderComparison(uLocale, style1, style2, order1, order2));
\r
421 } else if (isVerbose() && order1.monthLength > 2 && order2.monthLength > 2) { // warn if both are not numeric
\r
422 logln(showOrderComparison(uLocale, style1, style2, order1, order2));
\r
427 private String showOrderComparison(ULocale uLocale, int style1, int style2, DateOrder order1, DateOrder order2) {
\r
428 String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(style1, uLocale)).toPattern();
\r
429 String pattern2 = ((SimpleDateFormat) DateFormat.getDateInstance(style2, uLocale)).toPattern();
\r
430 return "Mismatch in in ordering for " + uLocale + ": " + DATE_STYLE_NAMES[style1] + ": " + order1 + ", <" + pattern1
\r
432 + DATE_STYLE_NAMES[style2] + ": " + order2 + ", <" + pattern2 + ">; " ;
\r
436 * Main date fields -- Poor-man's enum -- change to real enum when we get JDK 1.5
\r
438 public static class DateFieldType {
\r
439 private String name;
\r
440 private DateFieldType(String string) {
\r
444 public static DateFieldType
\r
445 YEAR = new DateFieldType("YEAR"),
\r
446 MONTH = new DateFieldType("MONTH"),
\r
447 DAY = new DateFieldType("DAY");
\r
449 public String toString() {
\r
455 * Simple struct for output from getOrdering
\r
457 static class DateOrder {
\r
459 DateFieldType[] fields = new DateFieldType[3];
\r
461 public boolean isCompatible(DateOrder other) {
\r
462 return monthLength == other.monthLength;
\r
468 public boolean hasSameOrderAs(DateOrder other) {
\r
469 // TODO Auto-generated method stub
\r
470 return fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2];
\r
472 public String toString() {
\r
473 return "{" + monthLength + ", " + fields[0] + ", " + fields[1] + ", " + fields[2] + "}";
\r
475 public boolean equals(Object that) {
\r
476 DateOrder other = (DateOrder) that;
\r
477 return monthLength == other.monthLength && fields[0] == other.fields[0] && fields[1] == other.fields[1] && fields[2] == other.fields[2];
\r
481 DateTimePatternGenerator.FormatParser formatParser = new DateTimePatternGenerator.FormatParser ();
\r
482 DateTimePatternGenerator generator = DateTimePatternGenerator.getEmptyInstance();
\r
484 private Calendar sampleCalendar = new GregorianCalendar(1999, Calendar.OCTOBER, 13, 23, 58, 59);
\r
485 private Date sampleDate = sampleCalendar.getTime();
\r
486 private TimeZone gmt = TimeZone.getTimeZone("Etc/GMT");
\r
489 * Replace the zone string with a different type, eg v's for z's, etc. <p>Called with a pattern, such as one gotten from
\r
491 * String pattern = ((SimpleDateFormat) DateFormat.getTimeInstance(style, locale)).toPattern();
\r
493 * @param pattern original pattern to change, such as "HH:mm zzzz"
\r
494 * @param newZone Must be: z, zzzz, Z, ZZZZ, v, vvvv, V, or VVVV
\r
497 public String replaceZoneString(String pattern, String newZone) {
\r
498 final List itemList = formatParser.set(pattern).getItems();
\r
499 boolean changed = false;
\r
500 for (int i = 0; i < itemList.size(); ++i) {
\r
501 Object item = itemList.get(i);
\r
502 if (item instanceof VariableField) {
\r
503 VariableField variableField = (VariableField) item;
\r
504 if (variableField.getType() == DateTimePatternGenerator.ZONE) {
\r
505 if (!variableField.toString().equals(newZone)) {
\r
507 itemList.set(i, new VariableField(newZone, true));
\r
512 return changed ? formatParser.toString() : pattern;
\r
515 public boolean containsZone(String pattern) {
\r
516 for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) {
\r
517 Object item = it.next();
\r
518 if (item instanceof VariableField) {
\r
519 VariableField variableField = (VariableField) item;
\r
520 if (variableField.getType() == DateTimePatternGenerator.ZONE) {
\r
529 * Get the ordering from a particular date format. Best is to use
\r
530 * DateFormat.FULL to get the format with String form month (like "January")
\r
531 * and DateFormat.SHORT for the numeric format order. They may be different.
\r
532 * (Theoretically all 4 formats could be different but that never happens in
\r
536 * DateFormat.FULL..DateFormat.SHORT
\r
540 * @return list of ordered items DateFieldType (I
\r
541 * didn't know what form you really wanted so this is just a
\r
544 private DateOrder getOrdering(int style, ULocale locale) {
\r
545 // and the date pattern
\r
546 String pattern = ((SimpleDateFormat) DateFormat.getDateInstance(style, locale)).toPattern();
\r
548 DateOrder result = new DateOrder();
\r
550 for (Iterator it = formatParser.set(pattern).getItems().iterator(); it.hasNext();) {
\r
551 Object item = it.next();
\r
552 if (!(item instanceof String)) {
\r
553 // the first character of the variable field determines the type,
\r
554 // according to CLDR.
\r
555 String variableField = item.toString();
\r
556 switch (variableField.charAt(0)) {
\r
557 case 'y': case 'Y': case 'u':
\r
558 result.fields[count++] = DateFieldType.YEAR;
\r
560 case 'M': case 'L':
\r
561 result.monthLength = variableField.length();
\r
562 if (result.monthLength < 2) {
\r
563 result.monthLength = 2;
\r
565 result.fields[count++] = DateFieldType.MONTH;
\r
567 case 'd': case 'D': case 'F': case 'g':
\r
568 result.fields[count++] = DateFieldType.DAY;
\r