1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 2008-2015, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6
7 #include "unicode/utypes.h"
8
9 #if !UCONFIG_NO_FORMATTING
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include "dtptngts.h"
14
15 #include "unicode/calendar.h"
16 #include "unicode/smpdtfmt.h"
17 #include "unicode/dtfmtsym.h"
18 #include "unicode/dtptngen.h"
19 #include "loctest.h"
20
21
22 // This is an API test, not a unit test. It doesn't test very many cases, and doesn't
23 // try to test the full functionality. It just calls each function in the class and
24 // verifies that it works on a basic level.
25
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)26 void IntlTestDateTimePatternGeneratorAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
27 {
28 if (exec) logln("TestSuite DateTimePatternGeneratorAPI");
29 switch (index) {
30 TESTCASE(0, testAPI);
31 TESTCASE(1, testOptions);
32 TESTCASE(2, testAllFieldPatterns);
33 default: name = ""; break;
34 }
35 }
36
37 #define MAX_LOCALE 11
38
39 /**
40 * Test various generic API methods of DateTimePatternGenerator for API coverage.
41 */
testAPI()42 void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
43 {
44 UnicodeString patternData[] = {
45 UnicodeString("yM"), // 00
46 UnicodeString("yMMM"), // 01
47 UnicodeString("yMd"), // 02
48 UnicodeString("yMMMd"), // 03
49 UnicodeString("Md"), // 04
50 UnicodeString("MMMd"), // 05
51 UnicodeString("MMMMd"), // 06
52 UnicodeString("yQQQ"), // 07
53 UnicodeString("hhmm"), // 08
54 UnicodeString("HHmm"), // 09
55 UnicodeString("jjmm"), // 10
56 UnicodeString("mmss"), // 11
57 UnicodeString("yyyyMMMM"), // 12
58 UnicodeString("MMMEd"), // 13
59 UnicodeString("Ed"), // 14
60 UnicodeString("jmmssSSS"), // 15
61 UnicodeString("JJmm"), // 16
62 UnicodeString(),
63 };
64
65 const char* testLocale[MAX_LOCALE][4] = {
66 {"en", "US", "", ""}, // 0
67 {"en", "US", "", "calendar=japanese"}, // 1
68 {"de", "DE", "", ""}, // 2
69 {"fi", "", "", ""}, // 3
70 {"es", "", "", ""}, // 4
71 {"ja", "", "", ""}, // 5
72 {"ja", "", "", "calendar=japanese"}, // 6
73 {"zh", "Hans", "CN", ""}, // 7
74 {"zh", "TW", "", "calendar=roc"}, // 8
75 {"ru", "", "", ""}, // 9
76 {"zh", "", "", "calendar=chinese"}, // 10
77 };
78
79 // For Weds, Jan 13, 1999, 23:58:59
80 UnicodeString patternResults[] = {
81 // en_US // 0 en_US
82 UnicodeString("1/1999"), // 00: yM
83 UnicodeString("Jan 1999"), // 01: yMMM
84 UnicodeString("1/13/1999"), // 02: yMd
85 UnicodeString("Jan 13, 1999"), // 03: yMMMd
86 UnicodeString("1/13"), // 04: Md
87 UnicodeString("Jan 13"), // 05: MMMd
88 UnicodeString("January 13"), // 06: MMMMd
89 UnicodeString("Q1 1999"), // 07: yQQQ
90 UnicodeString("11:58 PM"), // 08: hhmm
91 UnicodeString("23:58"), // 09: HHmm
92 UnicodeString("11:58 PM"), // 10: jjmm
93 UnicodeString("58:59"), // 11: mmss
94 UnicodeString("January 1999"), // 12: yyyyMMMM
95 UnicodeString("Wed, Jan 13"), // 13: MMMEd -> EEE, MMM d
96 UnicodeString("13 Wed"), // 14: Ed -> d EEE
97 UnicodeString("11:58:59.123 PM"), // 15: jmmssSSS -> "h:mm:ss.SSS a"
98 UnicodeString("11:58"), // 16: JJmm
99
100 // en_US@calendar=japanese // 1 en_US@calendar=japanese
101 UnicodeString("1/11 H"), // 0: yM
102 UnicodeString("Jan 11 Heisei"), // 1: yMMM
103 UnicodeString("1/13/11 H"), // 2: yMd
104 UnicodeString("Jan 13, 11 Heisei"), // 3: yMMMd
105 UnicodeString("1/13"), // 4: Md
106 UnicodeString("Jan 13"), // 5: MMMd
107 UnicodeString("January 13"), // 6: MMMMd
108 UnicodeString("Q1 11 Heisei"), // 7: yQQQ
109 UnicodeString("11:58 PM"), // 8: hhmm
110 UnicodeString("23:58"), // 9: HHmm
111 UnicodeString("11:58 PM"), // 10: jjmm
112 UnicodeString("58:59"), // 11: mmss
113 UnicodeString("January 11 Heisei"), // 12: yyyyMMMM
114 UnicodeString("Wed, Jan 13"), // 13: MMMEd -> EEE, MMM d"
115 UnicodeString("13 Wed"), // 14: Ed -> d EEE
116 UnicodeString("11:58:59.123 PM"), // 15: jmmssSSS -> "h:mm:ss.SSS a"
117 UnicodeString("11:58"), // 16: JJmm
118
119 // de_DE // 2 de_DE
120 UnicodeString("1.1999"), // 00: yM
121 UnicodeString("Jan. 1999"), // 01: yMMM
122 UnicodeString("13.1.1999"), // 02: yMd
123 UnicodeString("13. Jan. 1999"), // 03: yMMMd
124 UnicodeString("13.1."), // 04: Md
125 UnicodeString("13. Jan."), // 05: MMMd
126 UnicodeString("13. Januar"), // 06: MMMMd
127 UnicodeString("Q1 1999"), // 07: yQQQ
128 UnicodeString("11:58 nachm."), // 08: hhmm
129 UnicodeString("23:58"), // 09: HHmm
130 UnicodeString("23:58"), // 10: jjmm
131 UnicodeString("58:59"), // 11: mmss
132 UnicodeString("Januar 1999"), // 12: yyyyMMMM
133 UnicodeString("Mi., 13. Jan."), // 13: MMMEd -> EEE, d. MMM
134 UnicodeString("Mi., 13."), // 14: Ed -> EEE d.
135 UnicodeString("23:58:59,123"), // 15: jmmssSSS -> "HH:mm:ss,SSS"
136 UnicodeString("23:58"), // 16: JJmm
137
138 // fi // 3 fi
139 UnicodeString("1.1999"), // 00: yM (fixed expected result per ticket:6626:)
140 UnicodeString("tammi 1999"), // 01: yMMM
141 UnicodeString("13.1.1999"), // 02: yMd
142 UnicodeString("13. tammikuuta 1999"), // 03: yMMMd
143 UnicodeString("13.1."), // 04: Md
144 UnicodeString("13. tammikuuta"), // 05: MMMd
145 UnicodeString("13. tammikuuta"), // 06: MMMMd
146 UnicodeString("1. nelj. 1999"), // 07: yQQQ
147 UnicodeString("11.58 ip."), // 08: hhmm
148 UnicodeString("23.58"), // 09: HHmm
149 UnicodeString("23.58"), // 10: jjmm
150 UnicodeString("58.59"), // 11: mmss
151 UnicodeString("tammikuu 1999"), // 12: yyyyMMMM
152 UnicodeString("ke 13. tammikuuta"), // 13: MMMEd -> EEE d. MMM
153 UnicodeString("ke 13."), // 14: Ed -> ccc d.
154 UnicodeString("23.58.59,123"), // 15: jmmssSSS -> "H.mm.ss,SSS"
155 UnicodeString("23.58"), // 16: JJmm
156
157 // es // 4 es
158 UnicodeString("1/1999"), // 00: yM -> "M/y"
159 UnicodeString("ene. 1999"), // 01: yMMM -> "MMM y"
160 UnicodeString("13/1/1999"), // 02: yMd -> "d/M/y"
161 UnicodeString("13 ene. 1999"), // 03: yMMMd -> "d MMM y"
162 UnicodeString("13/1"), // 04: Md -> "d/M"
163 UnicodeString("13 ene."), // 05: MMMd -> "d 'de' MMM"
164 UnicodeString("13 de enero"), // 06: MMMMd -> "d 'de' MMMM"
165 UnicodeString("T1 1999"), // 07: yQQQ -> "QQQ y"
166 UnicodeString("11:58 p. m."), // 08: hhmm -> "hh:mm a"
167 UnicodeString("23:58"), // 09: HHmm -> "HH:mm"
168 UnicodeString("23:58"), // 10: jjmm -> "HH:mm"
169 UnicodeString("58:59"), // 11: mmss -> "mm:ss"
170 UnicodeString("enero de 1999"), // 12: yyyyMMMM -> "MMMM 'de' yyyy"
171 CharsToUnicodeString("mi\\u00E9., 13 ene."), // 13: MMMEd -> "E, d MMM"
172 CharsToUnicodeString("mi\\u00E9. 13"), // 14: Ed -> "EEE d"
173 UnicodeString("23:58:59,123"), // 15: jmmssSSS -> "H:mm:ss,SSS"
174 UnicodeString("23:58"), // 16: JJmm
175
176 // ja // 5 ja
177 UnicodeString("1999/1"), // 00: yM -> y/M
178 CharsToUnicodeString("1999\\u5E741\\u6708"), // 01: yMMM -> y\u5E74M\u6708
179 UnicodeString("1999/1/13"), // 02: yMd -> y/M/d
180 CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"), // 03: yMMMd -> y\u5E74M\u6708d\u65E5
181 UnicodeString("1/13"), // 04: Md -> M/d
182 CharsToUnicodeString("1\\u670813\\u65E5"), // 05: MMMd -> M\u6708d\u65E5
183 CharsToUnicodeString("1\\u670813\\u65E5"), // 06: MMMMd -> M\u6708d\u65E5
184 CharsToUnicodeString("1999/Q1"), // 07: yQQQ -> y/QQQ
185 CharsToUnicodeString("\\u5348\\u5F8C11:58"), // 08: hhmm
186 UnicodeString("23:58"), // 09: HHmm -> HH:mm
187 UnicodeString("23:58"), // 10: jjmm
188 UnicodeString("58:59"), // 11: mmss -> mm:ss
189 CharsToUnicodeString("1999\\u5E741\\u6708"), // 12: yyyyMMMM -> y\u5E74M\u6708
190 CharsToUnicodeString("1\\u670813\\u65E5(\\u6C34)"), // 13: MMMEd -> M\u6708d\u65E5(EEE)
191 CharsToUnicodeString("13\\u65E5(\\u6C34)"), // 14: Ed -> d\u65E5(EEE)
192 UnicodeString("23:58:59.123"), // 15: jmmssSSS -> "H:mm:ss.SSS"
193 UnicodeString("23:58"), // 16: JJmm
194
195 // ja@calendar=japanese // 6 ja@calendar=japanese
196 CharsToUnicodeString("\\u5E73\\u621011/1"), // 00: yM -> Gy/m
197 CharsToUnicodeString("\\u5E73\\u621011\\u5E741\\u6708"), // 01: yMMM -> Gy\u5E74M\u6708
198 CharsToUnicodeString("\\u5E73\\u621011/1/13"), // 02: yMd -> Gy/m/d
199 CharsToUnicodeString("\\u5E73\\u621011\\u5E741\\u670813\\u65E5"), // 03: yMMMd -> Gy\u5E74M\u6708d\u65E5
200 UnicodeString("1/13"), // 04: Md -> M/d
201 CharsToUnicodeString("1\\u670813\\u65E5"), // 05: MMMd -> M\u6708d\u65E5
202 CharsToUnicodeString("1\\u670813\\u65E5"), // 06: MMMMd -> M\u6708d\u65E5
203 CharsToUnicodeString("\\u5E73\\u621011/Q1"), // 07: yQQQ -> Gy/QQQ
204 CharsToUnicodeString("\\u5348\\u5F8C11:58"), // 08: hhmm ->
205 UnicodeString("23:58"), // 09: HHmm -> HH:mm (as for ja)
206 UnicodeString("23:58"), // 10: jjmm
207 UnicodeString("58:59"), // 11: mmss -> mm:ss (as for ja)
208 CharsToUnicodeString("\\u5E73\\u621011\\u5E741\\u6708"), // 12: yyyyMMMM -> Gyyyy\u5E74M\u6708
209 CharsToUnicodeString("1\\u670813\\u65E5(\\u6C34)"), // 13: MMMEd -> M\u6708d\u65E5(EEE)
210 CharsToUnicodeString("13\\u65E5(\\u6C34)"), // 14: Ed -> d\u65E5(EEE)
211 UnicodeString("23:58:59.123"), // 15: jmmssSSS -> "H:mm:ss.SSS"
212 UnicodeString("23:58"), // 16: JJmm
213
214 // zh_Hans_CN // 7 zh_Hans_CN
215 CharsToUnicodeString("1999\\u5E741\\u6708"), // 00: yM -> y\u5E74M\u6708
216 CharsToUnicodeString("1999\\u5E741\\u6708"), // 01: yMMM -> yyyy\u5E74MMM (fixed expected result per ticket:6626:)
217 CharsToUnicodeString("1999/1/13"), // 02: yMd
218 CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"), // 03: yMMMd -> yyyy\u5E74MMMd\u65E5 (fixed expected result per ticket:6626:)
219 UnicodeString("1/13"), // 04: Md
220 CharsToUnicodeString("1\\u670813\\u65E5"), // 05: MMMd -> M\u6708d\u65E5 (fixed expected result per ticket:6626:)
221 CharsToUnicodeString("1\\u670813\\u65E5"), // 06: MMMMd -> M\u6708d\u65E5
222 CharsToUnicodeString("1999\\u5E74\\u7B2C1\\u5B63\\u5EA6"), // 07: yQQQ
223 CharsToUnicodeString("\\u4E0B\\u534811:58"), // 08: hhmm
224 UnicodeString("23:58"), // 09: HHmm
225 CharsToUnicodeString("\\u4E0B\\u534811:58"), // 10: jjmm
226 UnicodeString("58:59"), // 11: mmss
227 CharsToUnicodeString("1999\\u5E741\\u6708"), // 12: yyyyMMMM -> yyyy\u5E74MMM
228 CharsToUnicodeString("1\\u670813\\u65E5\\u5468\\u4E09"), // 13: MMMEd -> MMMd\u65E5EEE
229 CharsToUnicodeString("13\\u65E5\\u5468\\u4E09"), // 14: Ed -> d\u65E5EEE
230 CharsToUnicodeString("\\u4E0B\\u534811:58:59.123"), // 15: jmmssSSS -> "ah:mm:ss.SSS"
231 UnicodeString("11:58"), // 16: JJmm
232
233 // zh_TW@calendar=roc // 8 zh_TW@calendar=roc
234 CharsToUnicodeString("\\u6C11\\u570B88/1"), // 00: yM -> Gy/M
235 CharsToUnicodeString("\\u6C11\\u570B88\\u5E741\\u6708"), // 01: yMMM -> Gy\u5E74M\u6708
236 CharsToUnicodeString("\\u6C11\\u570B88/1/13"), // 02: yMd -> Gy/M/d
237 CharsToUnicodeString("\\u6C11\\u570B88\\u5E741\\u670813\\u65E5"), // 03: yMMMd -> Gy\u5E74M\u6708d\u65E5
238 UnicodeString("1/13"), // 04: Md -> M/d
239 CharsToUnicodeString("1\\u670813\\u65E5"), // 05: MMMd ->M\u6708d\u65E5
240 CharsToUnicodeString("1\\u670813\\u65E5"), // 06: MMMMd ->M\u6708d\u65E5
241 CharsToUnicodeString("\\u6C11\\u570B88\\u5E741\\u5B63"), // 07: yQQQ -> Gy QQQ
242 CharsToUnicodeString("\\u4E0B\\u534811:58"), // 08: hhmm ->
243 UnicodeString("23:58"), // 09: HHmm ->
244 CharsToUnicodeString("\\u4E0B\\u534811:58"), // 10: jjmm
245 UnicodeString("58:59"), // 11: mmss ->
246 CharsToUnicodeString("\\u6C11\\u570B88\\u5E741\\u6708"), // 12: yyyyMMMM -> Gy\u5E74M\u670
247 CharsToUnicodeString("1\\u670813\\u65E5\\u9031\\u4E09"), // 13: MMMEd -> M\u6708d\u65E5EEE
248 CharsToUnicodeString("13\\u65E5\\uff08\\u9031\\u4E09\\uff09"), // 14: Ed -> d\u65E5\\uff08EEEi\\uff09
249 CharsToUnicodeString("\\u4E0B\\u534811:58:59.123"), // 15: jmmssSSS -> "ah:mm:ss.SSS"
250 UnicodeString("11:58"), // 16: JJmm
251
252 // ru // 9 ru
253 UnicodeString("01.1999"), // 00: yM -> MM.y
254 CharsToUnicodeString("\\u044F\\u043D\\u0432. 1999 \\u0433."), // 01: yMMM -> LLL y
255 UnicodeString("13.01.1999"), // 02: yMd -> dd.MM.y
256 CharsToUnicodeString("13 \\u044F\\u043D\\u0432. 1999 \\u0433."), // 03: yMMMd -> d MMM y
257 UnicodeString("13.01"), // 04: Md -> dd.MM
258 CharsToUnicodeString("13 \\u044F\\u043D\\u0432."), // 05: MMMd -> d MMM
259 CharsToUnicodeString("13 \\u044F\\u043D\\u0432\\u0430\\u0440\\u044F"), // 06: MMMMd -> d MMMM
260 CharsToUnicodeString("1-\\u0439 \\u043A\\u0432. 1999 \\u0433."), // 07: yQQQ -> y QQQ
261 CharsToUnicodeString("11:58 \\u041F\\u041F"), // 08: hhmm -> hh:mm a
262 UnicodeString("23:58"), // 09: HHmm -> HH:mm
263 UnicodeString("23:58"), // 10: jjmm -> HH:mm
264 UnicodeString("58:59"), // 11: mmss -> mm:ss
265 CharsToUnicodeString("\\u044F\\u043D\\u0432\\u0430\\u0440\\u044C 1999 \\u0433."), // 12: yyyyMMMM -> LLLL y
266 CharsToUnicodeString("\\u0441\\u0440, 13 \\u044F\\u043D\\u0432."), // 13: MMMEd -> ccc, d MMM
267 CharsToUnicodeString("\\u0441\\u0440, 13"), // 14: Ed -> EEE, d
268 UnicodeString("23:58:59,123"), // 15: jmmssSSS -> "H:mm:ss,SSS"
269 UnicodeString("23:58"), // 16: JJmm
270
271 // zh@calendar=chinese // 10 zh@calendar=chinese
272 CharsToUnicodeString("1998\\u620A\\u5BC5\\u5E74\\u51AC\\u6708"), // 00: yMMM
273 CharsToUnicodeString("1998\\u620A\\u5BC5\\u5E74\\u51AC\\u6708"), // 01: yMMM
274 CharsToUnicodeString("1998\\u5E74\\u51AC\\u670826"), // 02: yMMMd
275 CharsToUnicodeString("1998\\u5E74\\u51AC\\u670826"), // 03: yMMMd
276 UnicodeString("11-26"), // 04: Md
277 CharsToUnicodeString("\\u51AC\\u670826\\u65E5"), // 05: MMMd
278 CharsToUnicodeString("\\u51AC\\u670826\\u65E5"), // 06: MMMMd
279 CharsToUnicodeString("1998\\u620A\\u5BC5\\u5E74\\u7b2c\\u56db\\u5B63\\u5EA6"), // 07: yQQQ
280 CharsToUnicodeString("\\u4E0B\\u534811:58"), // 08: hhmm
281 UnicodeString("23:58"), // 09: HHmm
282 CharsToUnicodeString("\\u4E0B\\u534811:58"), // 10: jjmm
283 UnicodeString("58:59"), // 11: mmss
284 CharsToUnicodeString("1998\\u620A\\u5BC5\\u5E74\\u51AC\\u6708"), // 12: yyyyMMMM
285 CharsToUnicodeString("\\u51AC\\u670826\\u65E5\\u5468\\u4E09"), // 13: MMMEd
286 CharsToUnicodeString("26\\u65E5\\u5468\\u4E09"), // 14: Ed -> d\u65E5EEE
287 CharsToUnicodeString("\\u4E0B\\u534811:58:59.123"), // 15: jmmssSS
288 UnicodeString("11:58"), // 16: JJmm
289
290 UnicodeString(),
291 };
292
293 UnicodeString patternTests2[] = {
294 UnicodeString("yyyyMMMdd"),
295 UnicodeString("yyyyqqqq"),
296 UnicodeString("yMMMdd"),
297 UnicodeString("EyyyyMMMdd"),
298 UnicodeString("yyyyMMdd"),
299 UnicodeString("yyyyMMM"),
300 UnicodeString("yyyyMM"),
301 UnicodeString("yyMM"),
302 UnicodeString("yMMMMMd"),
303 UnicodeString("EEEEEMMMMMd"),
304 UnicodeString("MMMd"),
305 UnicodeString("MMMdhmm"),
306 UnicodeString("EMMMdhmms"),
307 UnicodeString("MMdhmm"),
308 UnicodeString("EEEEMMMdhmms"),
309 UnicodeString("yyyyMMMddhhmmss"),
310 UnicodeString("EyyyyMMMddhhmmss"),
311 UnicodeString("hmm"),
312 UnicodeString("hhmm"),
313 UnicodeString("hhmmVVVV"),
314 UnicodeString(""),
315 };
316 UnicodeString patternResults2[] = {
317 UnicodeString("Oct 14, 1999"),
318 UnicodeString("4th quarter 1999"),
319 UnicodeString("Oct 14, 1999"),
320 UnicodeString("Thu, Oct 14, 1999"),
321 UnicodeString("10/14/1999"),
322 UnicodeString("Oct 1999"),
323 UnicodeString("10/1999"),
324 UnicodeString("10/99"),
325 UnicodeString("O 14, 1999"),
326 UnicodeString("T, O 14"),
327 UnicodeString("Oct 14"),
328 UnicodeString("Oct 14, 6:58 AM"),
329 UnicodeString("Thu, Oct 14, 6:58:59 AM"),
330 UnicodeString("10/14, 6:58 AM"),
331 UnicodeString("Thursday, Oct 14, 6:58:59 AM"),
332 UnicodeString("Oct 14, 1999, 6:58:59 AM"),
333 UnicodeString("Thu, Oct 14, 1999, 6:58:59 AM"),
334 UnicodeString("6:58 AM"),
335 UnicodeString("6:58 AM"),
336 UnicodeString("6:58 AM GMT"),
337 UnicodeString(""),
338 };
339
340 // results for getSkeletons() and getPatternForSkeleton()
341 const UnicodeString testSkeletonsResults[] = {
342 UnicodeString("HH:mm"),
343 UnicodeString("MMMMd"),
344 UnicodeString("MMMMMdd"),
345 };
346
347 const UnicodeString testBaseSkeletonsResults[] = {
348 UnicodeString("Hm"),
349 UnicodeString("MMMMd"),
350 UnicodeString("MMMMMd"),
351 };
352
353 UnicodeString newDecimal(" "); // space
354 UnicodeString newAppendItemName("hrs.");
355 UnicodeString newAppendItemFormat("{1} {0}");
356 UnicodeString newDateTimeFormat("{1} {0}");
357 UErrorCode status = U_ZERO_ERROR;
358 UnicodeString conflictingPattern;
359 UDateTimePatternConflict conflictingStatus = UDATPG_NO_CONFLICT;
360 (void)conflictingStatus; // Suppress set but not used warning.
361
362 // ======= Test CreateInstance with default locale
363 logln("Testing DateTimePatternGenerator createInstance from default locale");
364
365 DateTimePatternGenerator *instFromDefaultLocale=DateTimePatternGenerator::createInstance(status);
366 if (U_FAILURE(status)) {
367 dataerrln("ERROR: Could not create DateTimePatternGenerator (default) - exitting");
368 return;
369 }
370 else {
371 delete instFromDefaultLocale;
372 }
373
374 // ======= Test CreateInstance with given locale
375 logln("Testing DateTimePatternGenerator createInstance from French locale");
376 status = U_ZERO_ERROR;
377 DateTimePatternGenerator *instFromLocale=DateTimePatternGenerator::createInstance(Locale::getFrench(), status);
378 if (U_FAILURE(status)) {
379 dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getFrench()) - exitting");
380 return;
381 }
382
383 // ======= Test clone DateTimePatternGenerator
384 logln("Testing DateTimePatternGenerator::clone()");
385 status = U_ZERO_ERROR;
386
387
388 UnicodeString decimalSymbol = instFromLocale->getDecimal();
389 UnicodeString newDecimalSymbol = UnicodeString("*");
390 decimalSymbol = instFromLocale->getDecimal();
391 instFromLocale->setDecimal(newDecimalSymbol);
392 DateTimePatternGenerator *cloneDTPatternGen=instFromLocale->clone();
393 decimalSymbol = cloneDTPatternGen->getDecimal();
394 if (decimalSymbol != newDecimalSymbol) {
395 errln("ERROR: inconsistency is found in cloned object.");
396 }
397 if ( !(*cloneDTPatternGen == *instFromLocale) ) {
398 errln("ERROR: inconsistency is found in cloned object.");
399 }
400
401 if ( *cloneDTPatternGen != *instFromLocale ) {
402 errln("ERROR: inconsistency is found in cloned object.");
403 }
404
405 delete instFromLocale;
406 delete cloneDTPatternGen;
407
408 // ======= Test simple use cases
409 logln("Testing simple use cases");
410 status = U_ZERO_ERROR;
411 Locale deLocale=Locale::getGermany();
412 UDate sampleDate=LocaleTest::date(99, 9, 13, 23, 58, 59);
413 DateTimePatternGenerator *gen = DateTimePatternGenerator::createInstance(deLocale, status);
414 if (U_FAILURE(status)) {
415 dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getGermany()) - exitting");
416 return;
417 }
418 UnicodeString findPattern = gen->getBestPattern(UnicodeString("MMMddHmm"), status);
419 SimpleDateFormat *format = new SimpleDateFormat(findPattern, deLocale, status);
420 if (U_FAILURE(status)) {
421 dataerrln("ERROR: Could not create SimpleDateFormat (Locale::getGermany())");
422 delete gen;
423 return;
424 }
425 TimeZone *zone = TimeZone::createTimeZone(UnicodeString("ECT"));
426 if (zone==NULL) {
427 dataerrln("ERROR: Could not create TimeZone ECT");
428 delete gen;
429 delete format;
430 return;
431 }
432 format->setTimeZone(*zone);
433 UnicodeString dateReturned, expectedResult;
434 dateReturned.remove();
435 dateReturned = format->format(sampleDate, dateReturned, status);
436 expectedResult=UnicodeString("14. Okt., 08:58", -1, US_INV);
437 if ( dateReturned != expectedResult ) {
438 errln("ERROR: Simple test in getBestPattern with Locale::getGermany()).");
439 }
440 // add new pattern
441 status = U_ZERO_ERROR;
442 conflictingStatus = gen->addPattern(UnicodeString("d'. von' MMMM", -1, US_INV), true, conflictingPattern, status);
443 if (U_FAILURE(status)) {
444 errln("ERROR: Could not addPattern - d\'. von\' MMMM");
445 }
446 status = U_ZERO_ERROR;
447 UnicodeString testPattern=gen->getBestPattern(UnicodeString("MMMMdd"), status);
448 testPattern=gen->getBestPattern(UnicodeString("MMMddHmm"), status);
449 format->applyPattern(gen->getBestPattern(UnicodeString("MMMMdHmm"), status));
450 dateReturned.remove();
451 dateReturned = format->format(sampleDate, dateReturned, status);
452 expectedResult=UnicodeString("14. von Oktober, 08:58", -1, US_INV);
453 if ( dateReturned != expectedResult ) {
454 errln(UnicodeString("ERROR: Simple test addPattern failed!: d\'. von\' MMMM Got: ") + dateReturned + UnicodeString(" Expected: ") + expectedResult);
455 }
456 delete format;
457
458 // get a pattern and modify it
459 format = (SimpleDateFormat *)DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
460 deLocale);
461 format->setTimeZone(*zone);
462 UnicodeString pattern;
463 pattern = format->toPattern(pattern);
464 dateReturned.remove();
465 dateReturned = format->format(sampleDate, dateReturned, status);
466 expectedResult=CharsToUnicodeString("Donnerstag, 14. Oktober 1999 um 08:58:59 Mitteleurop\\u00E4ische Sommerzeit");
467 if ( dateReturned != expectedResult ) {
468 errln("ERROR: Simple test uses full date format.");
469 errln(UnicodeString(" Got: ") + dateReturned + UnicodeString(" Expected: ") + expectedResult);
470 }
471
472 // modify it to change the zone.
473 UnicodeString newPattern = gen->replaceFieldTypes(pattern, UnicodeString("vvvv"), status);
474 format->applyPattern(newPattern);
475 dateReturned.remove();
476 dateReturned = format->format(sampleDate, dateReturned, status);
477 expectedResult=CharsToUnicodeString("Donnerstag, 14. Oktober 1999 um 08:58:59 Mitteleurop\\u00E4ische Zeit");
478 if ( dateReturned != expectedResult ) {
479 errln("ERROR: Simple test modify the timezone!");
480 errln(UnicodeString(" Got: ")+ dateReturned + UnicodeString(" Expected: ") + expectedResult);
481 }
482
483 // setDeciaml(), getDeciaml()
484 gen->setDecimal(newDecimal);
485 if (newDecimal != gen->getDecimal()) {
486 errln("ERROR: unexpected result from setDecimal() and getDecimal()!.\n");
487 }
488
489 // setAppenItemName() , getAppendItemName()
490 gen->setAppendItemName(UDATPG_HOUR_FIELD, newAppendItemName);
491 if (newAppendItemName != gen->getAppendItemName(UDATPG_HOUR_FIELD)) {
492 errln("ERROR: unexpected result from setAppendItemName() and getAppendItemName()!.\n");
493 }
494
495 // setAppenItemFormat() , getAppendItemFormat()
496 gen->setAppendItemFormat(UDATPG_HOUR_FIELD, newAppendItemFormat);
497 if (newAppendItemFormat != gen->getAppendItemFormat(UDATPG_HOUR_FIELD)) {
498 errln("ERROR: unexpected result from setAppendItemFormat() and getAppendItemFormat()!.\n");
499 }
500
501 // setDateTimeFormat() , getDateTimeFormat()
502 gen->setDateTimeFormat(newDateTimeFormat);
503 if (newDateTimeFormat != gen->getDateTimeFormat()) {
504 errln("ERROR: unexpected result from setDateTimeFormat() and getDateTimeFormat()!.\n");
505 }
506
507 // ======== Test getSkeleton and getBaseSkeleton
508 status = U_ZERO_ERROR;
509 pattern = UnicodeString("dd-MMM");
510 UnicodeString expectedSkeleton = UnicodeString("MMMdd");
511 UnicodeString expectedBaseSkeleton = UnicodeString("MMMd");
512 UnicodeString retSkeleton = gen->getSkeleton(pattern, status);
513 if(U_FAILURE(status) || retSkeleton != expectedSkeleton ) {
514 errln("ERROR: Unexpected result from getSkeleton().\n");
515 errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected: ") + expectedSkeleton );
516 }
517 retSkeleton = gen->getBaseSkeleton(pattern, status);
518 if(U_FAILURE(status) || retSkeleton != expectedBaseSkeleton) {
519 errln("ERROR: Unexpected result from getBaseSkeleton().\n");
520 errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected:")+ expectedBaseSkeleton);
521 }
522
523 pattern = UnicodeString("dd/MMMM/yy");
524 expectedSkeleton = UnicodeString("yyMMMMdd");
525 expectedBaseSkeleton = UnicodeString("yMMMMd");
526 retSkeleton = gen->getSkeleton(pattern, status);
527 if(U_FAILURE(status) || retSkeleton != expectedSkeleton ) {
528 errln("ERROR: Unexpected result from getSkeleton().\n");
529 errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected: ") + expectedSkeleton );
530 }
531 retSkeleton = gen->getBaseSkeleton(pattern, status);
532 if(U_FAILURE(status) || retSkeleton != expectedBaseSkeleton) {
533 errln("ERROR: Unexpected result from getBaseSkeleton().\n");
534 errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected:")+ expectedBaseSkeleton);
535 }
536 delete format;
537 delete zone;
538 delete gen;
539
540 {
541 // Trac# 6104
542 status = U_ZERO_ERROR;
543 pattern = UnicodeString("YYYYMMM");
544 UnicodeString expR = CharsToUnicodeString("1999\\u5E741\\u6708"); // fixed expected result per ticket:6626:
545 Locale loc("ja");
546 UDate testDate1= LocaleTest::date(99, 0, 13, 23, 58, 59);
547 DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
548 if(U_FAILURE(status)) {
549 dataerrln("ERROR: Could not create DateTimePatternGenerator");
550 return;
551 }
552 UnicodeString bPattern = patGen->getBestPattern(pattern, status);
553 UnicodeString rDate;
554 SimpleDateFormat sdf(bPattern, loc, status);
555 rDate.remove();
556 rDate = sdf.format(testDate1, rDate);
557
558 logln(UnicodeString(" ja locale with skeleton: YYYYMMM Best Pattern:") + bPattern);
559 logln(UnicodeString(" Formatted date:") + rDate);
560
561 if ( expR!= rDate ) {
562 errln(UnicodeString("\nERROR: Test Japanese month hack Got: ") + rDate +
563 UnicodeString(" Expected: ") + expR );
564 }
565
566 delete patGen;
567 }
568 { // Trac# 6104
569 Locale loc("zh");
570 UnicodeString expR = CharsToUnicodeString("1999\\u5E741\\u6708"); // fixed expected result per ticket:6626:
571 UDate testDate1= LocaleTest::date(99, 0, 13, 23, 58, 59);
572 DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
573 if(U_FAILURE(status)) {
574 dataerrln("ERROR: Could not create DateTimePatternGenerator");
575 return;
576 }
577 UnicodeString bPattern = patGen->getBestPattern(pattern, status);
578 UnicodeString rDate;
579 SimpleDateFormat sdf(bPattern, loc, status);
580 rDate.remove();
581 rDate = sdf.format(testDate1, rDate);
582
583 logln(UnicodeString(" zh locale with skeleton: YYYYMMM Best Pattern:") + bPattern);
584 logln(UnicodeString(" Formatted date:") + rDate);
585 if ( expR!= rDate ) {
586 errln(UnicodeString("\nERROR: Test Chinese month hack Got: ") + rDate +
587 UnicodeString(" Expected: ") + expR );
588 }
589 delete patGen;
590 }
591
592 {
593 // Trac# 6172 duplicate time pattern
594 status = U_ZERO_ERROR;
595 pattern = UnicodeString("hmv");
596 UnicodeString expR = UnicodeString("h:mm a v"); // avail formats has hm -> "h:mm a" (fixed expected result per ticket:6626:)
597 Locale loc("en");
598 DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
599 if(U_FAILURE(status)) {
600 dataerrln("ERROR: Could not create DateTimePatternGenerator");
601 return;
602 }
603 UnicodeString bPattern = patGen->getBestPattern(pattern, status);
604 logln(UnicodeString(" en locale with skeleton: hmv Best Pattern:") + bPattern);
605
606 if ( expR!= bPattern ) {
607 errln(UnicodeString("\nERROR: Test EN time format Got: ") + bPattern +
608 UnicodeString(" Expected: ") + expR );
609 }
610
611 delete patGen;
612 }
613
614
615 // ======= Test various skeletons.
616 logln("Testing DateTimePatternGenerator with various skeleton");
617
618 status = U_ZERO_ERROR;
619 int32_t localeIndex=0;
620 int32_t resultIndex=0;
621 UnicodeString resultDate;
622 UDate testDate= LocaleTest::date(99, 0, 13, 23, 58, 59) + 123.0;
623 while (localeIndex < MAX_LOCALE )
624 {
625 int32_t dataIndex=0;
626 UnicodeString bestPattern;
627
628 Locale loc(testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2], testLocale[localeIndex][3]);
629 logln("\n\n Locale: %s_%s_%s@%s", testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2], testLocale[localeIndex][3]);
630 DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
631 if(U_FAILURE(status)) {
632 dataerrln("ERROR: Could not create DateTimePatternGenerator with locale index:%d . - exitting\n", localeIndex);
633 return;
634 }
635 while (patternData[dataIndex].length() > 0) {
636 log(patternData[dataIndex]);
637 bestPattern = patGen->getBestPattern(patternData[dataIndex++], status);
638 logln(UnicodeString(" -> ") + bestPattern);
639
640 SimpleDateFormat sdf(bestPattern, loc, status);
641 resultDate.remove();
642 resultDate = sdf.format(testDate, resultDate);
643 if ( resultDate != patternResults[resultIndex] ) {
644 errln(UnicodeString("\nERROR: Test various skeletons[") + (dataIndex-1) + UnicodeString("], localeIndex ") + localeIndex +
645 UnicodeString(". Got: \"") + resultDate + UnicodeString("\" Expected: \"") + patternResults[resultIndex] + "\"" );
646 }
647
648 resultIndex++;
649 }
650 delete patGen;
651 localeIndex++;
652 }
653
654 // ======= More tests ticket#6110
655 logln("Testing DateTimePatternGenerator with various skeleton");
656
657 status = U_ZERO_ERROR;
658 localeIndex=0;
659 resultIndex=0;
660 testDate= LocaleTest::date(99, 9, 13, 23, 58, 59);
661 {
662 int32_t dataIndex=0;
663 UnicodeString bestPattern;
664 logln("\n\n Test various skeletons for English locale...");
665 DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(Locale::getEnglish(), status);
666 if(U_FAILURE(status)) {
667 dataerrln("ERROR: Could not create DateTimePatternGenerator with locale English . - exitting\n");
668 return;
669 }
670 TimeZone *enZone = TimeZone::createTimeZone(UnicodeString("ECT/GMT"));
671 if (enZone==NULL) {
672 dataerrln("ERROR: Could not create TimeZone ECT");
673 delete patGen;
674 return;
675 }
676 SimpleDateFormat *enFormat = (SimpleDateFormat *)DateFormat::createDateTimeInstance(DateFormat::kFull,
677 DateFormat::kFull, Locale::getEnglish());
678 enFormat->setTimeZone(*enZone);
679 while (patternTests2[dataIndex].length() > 0) {
680 logln(patternTests2[dataIndex]);
681 bestPattern = patGen->getBestPattern(patternTests2[dataIndex], status);
682 logln(UnicodeString(" -> ") + bestPattern);
683 enFormat->applyPattern(bestPattern);
684 resultDate.remove();
685 resultDate = enFormat->format(testDate, resultDate);
686 if ( resultDate != patternResults2[resultIndex] ) {
687 errln(UnicodeString("\nERROR: Test various skeletons[") + dataIndex
688 + UnicodeString("]. Got: ") + resultDate + UnicodeString(" Expected: ") +
689 patternResults2[resultIndex] );
690 }
691 dataIndex++;
692 resultIndex++;
693 }
694 delete patGen;
695 delete enZone;
696 delete enFormat;
697 }
698
699
700
701 // ======= Test random skeleton
702 DateTimePatternGenerator *randDTGen= DateTimePatternGenerator::createInstance(status);
703 if (U_FAILURE(status)) {
704 dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getFrench()) - exitting");
705 return;
706 }
707 UChar newChar;
708 int32_t i;
709 for (i=0; i<10; ++i) {
710 UnicodeString randomSkeleton;
711 int32_t len = rand() % 20;
712 for (int32_t j=0; j<len; ++j ) {
713 while ((newChar = (UChar)(rand()%0x7f))>=(UChar)0x20) {
714 randomSkeleton += newChar;
715 }
716 }
717 UnicodeString bestPattern = randDTGen->getBestPattern(randomSkeleton, status);
718 }
719 delete randDTGen;
720
721 // UnicodeString randomString=Unicode
722 // ======= Test getStaticClassID()
723
724 logln("Testing getStaticClassID()");
725 status = U_ZERO_ERROR;
726 DateTimePatternGenerator *test= DateTimePatternGenerator::createInstance(status);
727
728 if(test->getDynamicClassID() != DateTimePatternGenerator::getStaticClassID()) {
729 errln("ERROR: getDynamicClassID() didn't return the expected value");
730 }
731 delete test;
732
733 // ====== Test createEmptyInstance()
734
735 logln("Testing createEmptyInstance()");
736 status = U_ZERO_ERROR;
737
738 test = DateTimePatternGenerator::createEmptyInstance(status);
739 if(U_FAILURE(status)) {
740 errln("ERROR: Fail to create an empty instance ! - exitting.\n");
741 delete test;
742 return;
743 }
744
745 conflictingStatus = test->addPattern(UnicodeString("MMMMd"), true, conflictingPattern, status);
746 status = U_ZERO_ERROR;
747 testPattern=test->getBestPattern(UnicodeString("MMMMdd"), status);
748 conflictingStatus = test->addPattern(UnicodeString("HH:mm"), true, conflictingPattern, status);
749 conflictingStatus = test->addPattern(UnicodeString("MMMMMdd"), true, conflictingPattern, status); //duplicate pattern
750 StringEnumeration *output=NULL;
751 output = test->getRedundants(status);
752 expectedResult=UnicodeString("MMMMd");
753 if (output != NULL) {
754 output->reset(status);
755 const UnicodeString *dupPattern=output->snext(status);
756 if ( (dupPattern==NULL) || (*dupPattern != expectedResult) ) {
757 errln("ERROR: Fail in getRedundants !\n");
758 }
759 }
760
761 // ======== Test getSkeletons and getBaseSkeletons
762 StringEnumeration* ptrSkeletonEnum = test->getSkeletons(status);
763 if(U_FAILURE(status)) {
764 errln("ERROR: Fail to get skeletons !\n");
765 }
766 UnicodeString returnPattern, *ptrSkeleton;
767 ptrSkeletonEnum->reset(status);
768 int32_t count=ptrSkeletonEnum->count(status);
769 for (i=0; i<count; ++i) {
770 ptrSkeleton = (UnicodeString *)ptrSkeletonEnum->snext(status);
771 returnPattern = test->getPatternForSkeleton(*ptrSkeleton);
772 if ( returnPattern != testSkeletonsResults[i] ) {
773 errln(UnicodeString("ERROR: Unexpected result from getSkeletons and getPatternForSkeleton\nGot: ") + returnPattern
774 + UnicodeString("\nExpected: ") + testSkeletonsResults[i]
775 + UnicodeString("\n"));
776 }
777 }
778 StringEnumeration* ptrBaseSkeletonEnum = test->getBaseSkeletons(status);
779 if(U_FAILURE(status)) {
780 errln("ERROR: Fail to get base skeletons !\n");
781 }
782 count=ptrBaseSkeletonEnum->count(status);
783 for (i=0; i<count; ++i) {
784 ptrSkeleton = (UnicodeString *)ptrBaseSkeletonEnum->snext(status);
785 if ( *ptrSkeleton != testBaseSkeletonsResults[i] ) {
786 errln("ERROR: Unexpected result from getBaseSkeletons() !\n");
787 }
788 }
789
790 // ========= DateTimePatternGenerator sample code in Userguide
791 // set up the generator
792 Locale locale = Locale::getFrench();
793 status = U_ZERO_ERROR;
794 DateTimePatternGenerator *generator = DateTimePatternGenerator::createInstance( locale, status);
795
796 // get a pattern for an abbreviated month and day
797 pattern = generator->getBestPattern(UnicodeString("MMMd"), status);
798 SimpleDateFormat formatter(pattern, locale, status);
799
800 zone = TimeZone::createTimeZone(UnicodeString("GMT"));
801 formatter.setTimeZone(*zone);
802 // use it to format (or parse)
803 UnicodeString formatted;
804 formatted = formatter.format(Calendar::getNow(), formatted, status);
805 // for French, the result is "13 sept."
806 formatted.remove();
807 // cannot use the result from getNow() because the value change evreyday.
808 testDate= LocaleTest::date(99, 0, 13, 23, 58, 59);
809 formatted = formatter.format(testDate, formatted, status);
810 expectedResult=UnicodeString("14 janv.");
811 if ( formatted != expectedResult ) {
812 errln("ERROR: Userguide sample code result!");
813 errln(UnicodeString(" Got: ")+ formatted + UnicodeString(" Expected: ") + expectedResult);
814 }
815
816 delete zone;
817 delete output;
818 delete ptrSkeletonEnum;
819 delete ptrBaseSkeletonEnum;
820 delete test;
821 delete generator;
822 }
823
824 /**
825 * Test handling of options
826 *
827 * For reference, as of ICU 4.3.3,
828 * root/gregorian has
829 * Hm{"H:mm"}
830 * Hms{"H:mm:ss"}
831 * hm{"h:mm a"}
832 * hms{"h:mm:ss a"}
833 * en/gregorian has
834 * Hm{"H:mm"}
835 * Hms{"H:mm:ss"}
836 * hm{"h:mm a"}
837 * be/gregorian has
838 * HHmmss{"HH.mm.ss"}
839 * Hm{"HH.mm"}
840 * hm{"h.mm a"}
841 * hms{"h.mm.ss a"}
842 */
843 typedef struct DTPtnGenOptionsData {
844 const char *locale;
845 const char *skel;
846 const char *expectedPattern;
847 UDateTimePatternMatchOptions options;
848 } DTPtnGenOptionsData;
testOptions()849 void IntlTestDateTimePatternGeneratorAPI::testOptions(/*char *par*/)
850 {
851 DTPtnGenOptionsData testData[] = {
852 // locale skel expectedPattern options
853 { "en", "Hmm", "HH:mm", UDATPG_MATCH_NO_OPTIONS },
854 { "en", "HHmm", "HH:mm", UDATPG_MATCH_NO_OPTIONS },
855 { "en", "hhmm", "h:mm a", UDATPG_MATCH_NO_OPTIONS },
856 { "en", "Hmm", "HH:mm", UDATPG_MATCH_HOUR_FIELD_LENGTH },
857 { "en", "HHmm", "HH:mm", UDATPG_MATCH_HOUR_FIELD_LENGTH },
858 { "en", "hhmm", "hh:mm a", UDATPG_MATCH_HOUR_FIELD_LENGTH },
859 { "da", "Hmm", "HH.mm", UDATPG_MATCH_NO_OPTIONS },
860 { "da", "HHmm", "HH.mm", UDATPG_MATCH_NO_OPTIONS },
861 { "da", "hhmm", "h.mm a", UDATPG_MATCH_NO_OPTIONS },
862 { "da", "Hmm", "H.mm", UDATPG_MATCH_HOUR_FIELD_LENGTH },
863 { "da", "HHmm", "HH.mm", UDATPG_MATCH_HOUR_FIELD_LENGTH },
864 { "da", "hhmm", "hh.mm a", UDATPG_MATCH_HOUR_FIELD_LENGTH },
865 //
866 { "en", "yyyy", "yyyy", UDATPG_MATCH_NO_OPTIONS },
867 { "en", "YYYY", "YYYY", UDATPG_MATCH_NO_OPTIONS },
868 { "en", "U", "y", UDATPG_MATCH_NO_OPTIONS },
869 { "en@calendar=japanese", "yyyy", "y G", UDATPG_MATCH_NO_OPTIONS },
870 { "en@calendar=japanese", "YYYY", "Y G", UDATPG_MATCH_NO_OPTIONS },
871 { "en@calendar=japanese", "U", "y G", UDATPG_MATCH_NO_OPTIONS },
872 { "en@calendar=chinese", "yyyy", "r(U)", UDATPG_MATCH_NO_OPTIONS },
873 { "en@calendar=chinese", "YYYY", "Y(Y)", UDATPG_MATCH_NO_OPTIONS }, // not a good result, want r(Y) or r(U)
874 { "en@calendar=chinese", "U", "r(U)", UDATPG_MATCH_NO_OPTIONS },
875 { "en@calendar=chinese", "Gy", "r(U)", UDATPG_MATCH_NO_OPTIONS },
876 { "en@calendar=chinese", "GU", "r(U)", UDATPG_MATCH_NO_OPTIONS },
877 { "en@calendar=chinese", "ULLL", "MMM U", UDATPG_MATCH_NO_OPTIONS },
878 { "en@calendar=chinese", "yMMM", "MMM r(U)", UDATPG_MATCH_NO_OPTIONS },
879 { "en@calendar=chinese", "GUMMM", "MMM r(U)", UDATPG_MATCH_NO_OPTIONS },
880 { "zh@calendar=chinese", "yyyy", "rU\\u5E74", UDATPG_MATCH_NO_OPTIONS },
881 { "zh@calendar=chinese", "YYYY", "YY\\u5E74", UDATPG_MATCH_NO_OPTIONS }, // not a good result, may want r(Y) or r(U)
882 { "zh@calendar=chinese", "U", "rU\\u5E74", UDATPG_MATCH_NO_OPTIONS },
883 { "zh@calendar=chinese", "Gy", "rU\\u5E74", UDATPG_MATCH_NO_OPTIONS },
884 { "zh@calendar=chinese", "GU", "rU\\u5E74", UDATPG_MATCH_NO_OPTIONS },
885 { "zh@calendar=chinese", "ULLL", "U\\u5E74MMM", UDATPG_MATCH_NO_OPTIONS },
886 { "zh@calendar=chinese", "yMMM", "rU\\u5E74MMM", UDATPG_MATCH_NO_OPTIONS },
887 { "zh@calendar=chinese", "GUMMM", "rU\\u5E74MMM", UDATPG_MATCH_NO_OPTIONS },
888 };
889
890 int count = sizeof(testData) / sizeof(testData[0]);
891 const DTPtnGenOptionsData * testDataPtr = testData;
892
893 for (; count-- > 0; ++testDataPtr) {
894 UErrorCode status = U_ZERO_ERROR;
895
896 Locale locale(testDataPtr->locale);
897 UnicodeString skel(testDataPtr->skel);
898 UnicodeString expectedPattern(UnicodeString(testDataPtr->expectedPattern).unescape());
899 UDateTimePatternMatchOptions options = testDataPtr->options;
900
901 DateTimePatternGenerator * dtpgen = DateTimePatternGenerator::createInstance(locale, status);
902 if (U_FAILURE(status)) {
903 dataerrln("Unable to create DateTimePatternGenerator instance for locale(%s): %s", locale.getName(), u_errorName(status));
904 delete dtpgen;
905 continue;
906 }
907 UnicodeString pattern = dtpgen->getBestPattern(skel, options, status);
908 if (pattern.compare(expectedPattern) != 0) {
909 errln( UnicodeString("ERROR in getBestPattern, locale ") + UnicodeString(testDataPtr->locale) +
910 UnicodeString(", skeleton ") + skel +
911 ((options)?UnicodeString(", options!=0"):UnicodeString(", options==0")) +
912 UnicodeString(", expected pattern ") + expectedPattern +
913 UnicodeString(", got ") + pattern );
914 }
915 delete dtpgen;
916 }
917 }
918
919 /**
920 * Test that DTPG can handle all valid pattern character / length combinations
921 *
922 */
923 #define FIELD_LENGTHS_COUNT 6
924 #define FIELD_LENGTH_MAX 8
925 #define MUST_INCLUDE_COUNT 5
926
927 typedef struct AllFieldsTestItem {
928 char patternChar;
929 int8_t fieldLengths[FIELD_LENGTHS_COUNT+1]; // up to FIELD_LENGTHS_COUNT lengths to try
930 // (length <=FIELD_LENGTH_MAX) plus 0 terminator
931 char mustIncludeOneOf[MUST_INCLUDE_COUNT+1];// resulting pattern must include at least one of
932 // these as a pattern char (0-terminated list)
933 } AllFieldsTestItem;
934
testAllFieldPatterns()935 void IntlTestDateTimePatternGeneratorAPI::testAllFieldPatterns(/*char *par*/)
936 {
937 const char * localeNames[] = {
938 "root",
939 "root@calendar=japanese",
940 "root@calendar=chinese",
941 "en",
942 "en@calendar=japanese",
943 "en@calendar=chinese",
944 NULL // terminator
945 };
946 AllFieldsTestItem testData[] = {
947 //pat fieldLengths generated pattern must
948 //chr to test include one of these
949 { 'G', {1,2,3,4,5,0}, "G" }, // era
950 // year
951 { 'y', {1,2,3,4,0}, "yU" }, // year
952 { 'Y', {1,2,3,4,0}, "Y" }, // year for week of year
953 { 'u', {1,2,3,4,5,0}, "yuU" }, // extended year
954 { 'U', {1,2,3,4,5,0}, "yU" }, // cyclic year name
955 // quarter
956 { 'Q', {1,2,3,4,0}, "Qq" }, // x
957 { 'q', {1,2,3,4,0}, "Qq" }, // standalone
958 // month
959 { 'M', {1,2,3,4,5,0}, "ML" }, // x
960 { 'L', {1,2,3,4,5,0}, "ML" }, // standalone
961 // week
962 { 'w', {1,2,0}, "w" }, // week of year
963 { 'W', {1,0}, "W" }, // week of month
964 // day
965 { 'd', {1,2,0}, "d" }, // day of month
966 { 'D', {1,2,3,0}, "D" }, // day of year
967 { 'F', {1,0}, "F" }, // day of week in month
968 { 'g', {7,0}, "g" }, // modified julian day
969 // weekday
970 { 'E', {1,2,3,4,5,6}, "Eec" }, // day of week
971 { 'e', {1,2,3,4,5,6}, "Eec" }, // local day of week
972 { 'c', {1,2,3,4,5,6}, "Eec" }, // standalone local day of week
973 // day period
974 // { 'a', {1,0}, "a" }, // am or pm // not clear this one is supposed to work (it doesn't)
975 // hour
976 { 'h', {1,2,0}, "hK" }, // 12 (1-12)
977 { 'H', {1,2,0}, "Hk" }, // 24 (0-23)
978 { 'K', {1,2,0}, "hK" }, // 12 (0-11)
979 { 'k', {1,2,0}, "Hk" }, // 24 (1-24)
980 { 'j', {1,2,0}, "hHKk" }, // locale default
981 // minute
982 { 'm', {1,2,0}, "m" }, // x
983 // second & fractions
984 { 's', {1,2,0}, "s" }, // x
985 { 'S', {1,2,3,4,0}, "S" }, // fractional second
986 { 'A', {8,0}, "A" }, // milliseconds in day
987 // zone
988 { 'z', {1,2,3,4,0}, "z" }, // x
989 { 'Z', {1,2,3,4,5,0}, "Z" }, // x
990 { 'O', {1,4,0}, "O" }, // x
991 { 'v', {1,4,0}, "v" }, // x
992 { 'V', {1,2,3,4,0}, "V" }, // x
993 { 'X', {1,2,3,4,5,0}, "X" }, // x
994 { 'x', {1,2,3,4,5,0}, "x" }, // x
995 };
996
997 const char ** localeNamesPtr = localeNames;
998 const char * localeName;
999 while ( (localeName = *localeNamesPtr++) != NULL) {
1000 UErrorCode status = U_ZERO_ERROR;
1001 Locale locale = Locale::createFromName(localeName);
1002 DateTimePatternGenerator * dtpg = DateTimePatternGenerator::createInstance(locale, status);
1003 if (U_SUCCESS(status)) {
1004 const AllFieldsTestItem * testDataPtr = testData;
1005 int itemCount = sizeof(testData) / sizeof(testData[0]);
1006 for (; itemCount-- > 0; ++testDataPtr) {
1007 char skelBuf[FIELD_LENGTH_MAX];
1008 int32_t chrIndx, lenIndx;
1009 for (chrIndx = 0; chrIndx < FIELD_LENGTH_MAX; chrIndx++) {
1010 skelBuf[chrIndx] = testDataPtr->patternChar;
1011 }
1012 for (lenIndx = 0; lenIndx < FIELD_LENGTHS_COUNT; lenIndx++) {
1013 int32_t skelLen = testDataPtr->fieldLengths[lenIndx];
1014 if (skelLen <= 0) {
1015 break;
1016 }
1017 if (skelLen > FIELD_LENGTH_MAX) {
1018 continue;
1019 }
1020 UnicodeString skeleton(skelBuf, skelLen, US_INV);
1021 UnicodeString pattern = dtpg->getBestPattern(skeleton, status);
1022 if (U_FAILURE(status)) {
1023 errln("DateTimePatternGenerator getBestPattern for locale %s, skelChar %c skelLength %d fails: %s",
1024 locale.getName(), testDataPtr->patternChar, skelLen, u_errorName(status));
1025 } else if (pattern.length() <= 0) {
1026 errln("DateTimePatternGenerator getBestPattern for locale %s, skelChar %c skelLength %d produces 0-length pattern",
1027 locale.getName(), testDataPtr->patternChar, skelLen);
1028 } else {
1029 // test that resulting pattern has at least one char in mustIncludeOneOf
1030 UnicodeString mustIncludeOneOf(testDataPtr->mustIncludeOneOf, -1, US_INV);
1031 int32_t patIndx, patLen = pattern.length();
1032 UBool inQuoted = FALSE;
1033 for (patIndx = 0; patIndx < patLen; patIndx++) {
1034 UChar c = pattern.charAt(patIndx);
1035 if (c == 0x27) {
1036 inQuoted = !inQuoted;
1037 } else if (!inQuoted && c <= 0x007A && c >= 0x0041) {
1038 if (mustIncludeOneOf.indexOf(c) >= 0) {
1039 break;
1040 }
1041 }
1042 }
1043 if (patIndx >= patLen) {
1044 errln(UnicodeString("DateTimePatternGenerator getBestPattern for locale ") +
1045 UnicodeString(locale.getName(),-1,US_INV) +
1046 ", skeleton " + skeleton +
1047 ", produces pattern without required chars: " + pattern);
1048 }
1049
1050 }
1051 }
1052 }
1053 delete dtpg;
1054 } else {
1055 dataerrln("Create DateTimePatternGenerator instance for locale(%s) fails: %s",
1056 locale.getName(), u_errorName(status));
1057 }
1058 }
1059 }
1060 #endif /* #if !UCONFIG_NO_FORMATTING */
1061