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