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