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