1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 2008-2010, 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
26void 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        default: name = ""; break;
33    }
34}
35
36#define MAX_LOCALE   9
37
38/**
39 * Test various generic API methods of DateTimePatternGenerator for API coverage.
40 */
41void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
42{
43    UnicodeString patternData[] = {
44        UnicodeString("yM"),        // 00
45        UnicodeString("yMMM"),      // 01
46        UnicodeString("yMd"),       // 02
47        UnicodeString("yMMMd"),     // 03
48        UnicodeString("Md"),        // 04
49        UnicodeString("MMMd"),      // 05
50        UnicodeString("yQQQ"),      // 06
51        UnicodeString("hhmm"),      // 07
52        UnicodeString("HHmm"),      // 08
53        UnicodeString("jjmm"),      // 09
54        UnicodeString("mmss"),      // 10
55        UnicodeString("yyyyMMMM"),  // 11
56        UnicodeString("MMMEd"),     // 12
57        UnicodeString("Ed"),        // 13
58        UnicodeString(),
59     };
60
61    const char* testLocale[MAX_LOCALE][4] = {
62        {"en", "US", "", ""},                   // 0
63        {"en", "US", "", "calendar=japanese"},  // 1
64        {"de", "DE", "", ""},                   // 2
65        {"fi", "", "", ""},                     // 3
66        {"ja", "", "", ""},                     // 4
67        {"ja", "", "", "calendar=japanese"},    // 5
68        {"zh", "Hans", "CN", ""},               // 6
69        {"zh", "TW", "", "calendar=roc"},       // 7
70        {"ru", "", "", ""},                     // 8
71     };
72
73    // For Weds, Jan 13, 1999, 23:58:59
74    UnicodeString patternResults[] = {
75        // en_US                                              // 0 en_US
76        UnicodeString("1/1999"),                              // 00: yM
77        UnicodeString("Jan 1999"),                            // 01: yMMM
78        UnicodeString("1/13/1999"),                           // 02: yMd
79        UnicodeString("Jan 13, 1999"),                        // 03: yMMMd
80        UnicodeString("1/13"),                                // 04: Md
81        UnicodeString("Jan 13"),                              // 05: MMMd
82        UnicodeString("Q1 1999"),                             // 06: yQQQ
83        UnicodeString("11:58 PM"),                            // 07: hhmm
84        UnicodeString("23:58"),                               // 08: HHmm
85        UnicodeString("11:58 PM"),                            // 09: jjmm
86        UnicodeString("58:59"),                               // 10: mmss
87        UnicodeString("January 1999"),                        // 11: yyyyMMMM
88        UnicodeString("Wed, Jan 13"),                         // 12: MMMEd -> EEE, MMM d"
89        UnicodeString("13 Wed"),                              // 13: Ed    -> d EEE
90
91        // en_US@calendar=japanese                            // 1 en_US@calendar=japanese
92        UnicodeString("1/11 Heisei"),                         //  0: yM
93        UnicodeString("Jan 11 Heisei"),                       //  1: yMMM
94        UnicodeString("H 11-01-13"),                          //  2: yMd
95        UnicodeString("H 11 Jan 13"),                         //  3: yMMMd
96        UnicodeString("1/13"),                                //  4: Md
97        UnicodeString("Jan 13"),                              //  5: MMMd
98        UnicodeString("Q1 11 Heisei"),                        //  6: yQQQ
99        UnicodeString("11:58 PM"),                            //  7: hhmm
100        UnicodeString("23:58"),                               //  8: HHmm
101        UnicodeString("11:58 PM"),                            //  9: jjmm
102        UnicodeString("58:59"),                               // 10: mmss
103        UnicodeString("January 11 Heisei"),                   // 11: yyyyMMMM
104        UnicodeString("Wed, Jan 13"),                         // 12: MMMEd -> EEE, MMM d"
105        UnicodeString("13 Wed"),                              // 13: Ed    -> d EEE
106
107        // de_DE                                              // 2 de_DE
108        UnicodeString("1.1999"),                              // 00: yM
109        UnicodeString("Jan 1999"),                            // 01: yMMM
110        UnicodeString("13.1.1999"),                           // 02: yMd
111        UnicodeString("13. Jan 1999"),                        // 03: yMMMd
112        UnicodeString("13.1."),                               // 04: Md
113        UnicodeString("13. Jan"),                             // 05: MMMd
114        UnicodeString("Q1 1999"),                             // 06: yQQQ
115        UnicodeString("11:58 nachm."),                        // 07: hhmm
116        UnicodeString("23:58"),                               // 08: HHmm
117        UnicodeString("23:58"),                               // 09: jjmm
118        UnicodeString("58:59"),                               // 10: mmss
119        UnicodeString("Januar 1999"),                         // 11: yyyyMMMM
120        UnicodeString("Mi., 13. Jan"),                        // 12: MMMEd -> EEE, d. MMM
121        UnicodeString("Mi., 13."),                             // 13: Ed   -> EEE, d.
122
123        // fi                                                 // 3 fi
124        UnicodeString("1.1999"),                              // 00: yM (fixed expected result per ticket:6626:)
125        UnicodeString("tammi 1999"),                          // 01: yMMM
126        UnicodeString("13.1.1999"),                           // 02: yMd
127        UnicodeString("13. tammikuuta 1999"),                 // 03: yMMMd
128        UnicodeString("13.1."),                               // 04: Md
129        UnicodeString("13. tammikuuta"),                      // 05: MMMd
130        UnicodeString("1. nelj. 1999"),                       // 06: yQQQ
131        UnicodeString("11.58 ip."),                           // 07: hhmm
132        UnicodeString("23.58"),                               // 08: HHmm
133        UnicodeString("23.58"),                               // 09: jjmm
134        UnicodeString("58.59"),                               // 10: mmss
135        UnicodeString("tammikuu 1999"),                       // 11: yyyyMMMM
136        UnicodeString("ke 13. tammikuuta"),                   // 12: MMMEd -> EEE d. MMM
137        UnicodeString("ke 13."),                              // 13: Ed    -> ccc d.
138
139        // ja                                                             // 4 ja
140        UnicodeString("1999/1"),                                          // 00: yM    -> y/M
141        CharsToUnicodeString("1999\\u5E741\\u6708"),                      // 01: yMMM  -> y\u5E74M\u6708
142        UnicodeString("1999/1/13"),                                       // 02: yMd   -> y/M/d
143        CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"),             // 03: yMMMd -> y\u5E74M\u6708d\u65E5
144        UnicodeString("1/13"),                                            // 04: Md    -> M/d
145        CharsToUnicodeString("1\\u670813\\u65E5"),                        // 05: MMMd  -> M\u6708d\u65E5
146        UnicodeString("1999Q1"),                                          // 06: yQQQ  -> yQQQ
147        CharsToUnicodeString("\\u5348\\u5F8C11:58"),                      // 07: hhmm
148        UnicodeString("23:58"),                                           // 08: HHmm  -> HH:mm
149        UnicodeString("23:58"),                                           // 09: jjmm
150        UnicodeString("58:59"),                                           // 10: mmss  -> mm:ss
151        CharsToUnicodeString("1999\\u5E741\\u6708"),                      // 11: yyyyMMMM  -> y\u5E74M\u6708
152        CharsToUnicodeString("1\\u670813\\u65E5(\\u6C34)"),               // 12: MMMEd -> M\u6708d\u65E5(EEE)
153        CharsToUnicodeString("13\\u65E5(\\u6C34)"),                       // 13: Ed    -> d\u65E5(EEE)
154
155        // ja@calendar=japanese                                           // 5 ja@calendar=japanese
156        CharsToUnicodeString("\\u5E73\\u621011/1"),                       // 00: yM    -> Gy/m
157        CharsToUnicodeString("\\u5E73\\u621011\\u5E741\\u6708"),          // 01: yMMM  -> Gy\u5E74M\u6708
158        CharsToUnicodeString("\\u5E73\\u621011/1/13"),                    // 02: yMd   -> Gy/m/d
159        CharsToUnicodeString("\\u5E73\\u621011\\u5E741\\u670813\\u65E5"), // 03: yMMMd -> Gy\u5E74M\u6708d\u65E5
160        UnicodeString("1/13"),                                            // 04: Md    -> M/d
161        CharsToUnicodeString("1\\u670813\\u65E5"),                        // 05: MMMd  -> M\u6708d\u65E5
162        CharsToUnicodeString("\\u5E73\\u621011/Q1"),                      // 06: yQQQ  -> Gy/QQQ
163        CharsToUnicodeString("\\u5348\\u5F8C11:58"),                      // 07: hhmm  ->
164        UnicodeString("23:58"),                                           // 08: HHmm  -> HH:mm          (as for ja)
165        UnicodeString("23:58"),                                           // 09: jjmm
166        UnicodeString("58:59"),                                           // 10: mmss  -> mm:ss          (as for ja)
167        CharsToUnicodeString("\\u5E73\\u621011\\u5E741\\u6708"),          // 11: yyyyMMMM  -> Gyyyy\u5E74M\u6708
168        CharsToUnicodeString("1\\u670813\\u65E5(\\u6C34)"),               // 12: MMMEd -> M\u6708d\u65E5(EEE)
169        CharsToUnicodeString("13\\u65E5(\\u6C34)"),                       // 13: Ed    -> d\u65E5(EEE)
170
171        // zh_Hans_CN                                                     // 6 zh_Hans_CN
172        UnicodeString("1999-1", -1, US_INV),                              // 00: yM
173        CharsToUnicodeString("1999\\u5E741\\u6708"),                      // 01: yMMM  -> yyyy\u5E74MMM (fixed expected result per ticket:6626:)
174        CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"),             // 02: yMd
175        CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"),             // 03: yMMMd -> yyyy\u5E74MMMd\u65E5 (fixed expected result per ticket:6626:)
176        UnicodeString("1-13"),                                            // 04: Md
177        CharsToUnicodeString("1\\u670813\\u65E5"),                        // 05: MMMd  -> MMMd\u65E5 (fixed expected result per ticket:6626:)
178        CharsToUnicodeString("1999\\u5E741\\u5B63"),                      // 06: yQQQ
179        CharsToUnicodeString("\\u4E0B\\u534811:58"),                      // 07: hhmm
180        UnicodeString("23:58"),                                           // 08: HHmm
181        CharsToUnicodeString("\\u4E0B\\u534811:58"),                      // 09: jjmm
182        UnicodeString("58:59"),                                           // 10: mmss
183        CharsToUnicodeString("1999\\u5E741\\u6708"),                      // 11: yyyyMMMM  -> yyyy\u5E74MMM
184        CharsToUnicodeString("1\\u670813\\u65E5\\u5468\\u4E09"),          // 12: MMMEd -> MMMd\u65E5EEE
185        CharsToUnicodeString("13\\u65E5\\u5468\\u4E09"),                  // 13: Ed    -> d\u65E5EEE
186
187        // zh_TW@calendar=roc                                             // 7 zh_TW@calendar=roc
188        CharsToUnicodeString("\\u6C11\\u570B88/1"),                       // 00: yM    -> Gy/M
189        CharsToUnicodeString("\\u6C11\\u570B88\\u5E741\\u6708"),          // 01: yMMM  -> Gy\u5E74M\u6708
190        CharsToUnicodeString("\\u6C11\\u570B88/1/13"),                    // 02: yMd   -> Gy/M/d
191        CharsToUnicodeString("\\u6C11\\u570B88\\u5E741\\u670813\\u65E5"), // 03: yMMMd -> Gy\u5E74M\u6708d\u65E5
192        UnicodeString("1/13"),                                            // 04: Md    -> M/d
193        CharsToUnicodeString("1\\u670813\\u65E5"),                        // 05: MMMd  ->M\u6708d\u65E5
194        CharsToUnicodeString("\\u6C11\\u570B88 1\\u5B63"),                // 06: yQQQ  -> Gy QQQ
195        CharsToUnicodeString("\\u4E0B\\u534811:58"),                      // 07: hhmm  ->
196        UnicodeString("23:58"),                                           // 08: HHmm  ->
197        CharsToUnicodeString("\\u4E0B\\u534811:58"),                      // 09: jjmm
198        UnicodeString("58:59"),                                           // 10: mmss  ->
199        CharsToUnicodeString("\\u6C11\\u570B88\\u5E741\\u6708"),          // 11: yyyyMMMM  -> Gy\u5E74M\u670
200        CharsToUnicodeString("1\\u670813\\u65E5\\u9031\\u4E09"),          // 12: MMMEd -> M\u6708d\u65E5EEE
201        CharsToUnicodeString("13\\u65E5(\\u9031\\u4E09)"),                // 13: Ed    -> d\u65E5(EEE)
202
203        // ru                                                             // 8 ru
204        UnicodeString("1.1999"),                                          // 00: yM    -> M.y
205        CharsToUnicodeString("\\u044F\\u043D\\u0432. 1999"),              // 01: yMMM  -> LLL y
206        UnicodeString("13.1.1999"),                                       // 02: yMd   -> d.M.y
207        CharsToUnicodeString("13 \\u044F\\u043D\\u0432. 1999\\u00A0\\u0433."), // 03: yMMMd -> d MMM y
208        UnicodeString("13.1"),                                            // 04: Md    -> d.M
209        CharsToUnicodeString("13 \\u044F\\u043D\\u0432."),                // 05: MMMd  -> d MMM
210        CharsToUnicodeString("1999 1-\\u0439 \\u043A\\u0432."),           // 06: yQQQ  -> y QQQ
211        UnicodeString("11:58 PM"),                                        // 07: hhmm  -> hh:mm a
212        UnicodeString("23:58"),                                           // 08: HHmm  -> HH:mm
213        UnicodeString("23:58"),                                           // 09: jjmm  -> HH:mm
214        UnicodeString("58:59"),                                           // 10: mmss  -> mm:ss
215        CharsToUnicodeString("\\u042F\\u043D\\u0432\\u0430\\u0440\\u044C 1999"), // 11: yyyyMMMM -> LLLL y
216        CharsToUnicodeString("\\u0421\\u0440, 13 \\u044F\\u043D\\u0432."), // 12: MMMEd -> ccc, d MMM
217        CharsToUnicodeString("\\u0441\\u0440, 13"),                       // 13: Ed    -> EEE, d
218
219        UnicodeString(),
220    };
221
222    UnicodeString patternTests2[] = {
223        UnicodeString("yyyyMMMdd"),
224        UnicodeString("yyyyqqqq"),
225        UnicodeString("yMMMdd"),
226        UnicodeString("EyyyyMMMdd"),
227        UnicodeString("yyyyMMdd"),
228        UnicodeString("yyyyMMM"),
229        UnicodeString("yyyyMM"),
230        UnicodeString("yyMM"),
231        UnicodeString("yMMMMMd"),
232        UnicodeString("EEEEEMMMMMd"),
233        UnicodeString("MMMd"),
234        UnicodeString("MMMdhmm"),
235        UnicodeString("EMMMdhmms"),
236        UnicodeString("MMdhmm"),
237        UnicodeString("EEEEMMMdhmms"),
238        UnicodeString("yyyyMMMddhhmmss"),
239        UnicodeString("EyyyyMMMddhhmmss"),
240        UnicodeString("hmm"),
241        UnicodeString("hhmm"),
242        UnicodeString("hhmmVVVV"),
243        UnicodeString(""),
244    };
245    UnicodeString patternResults2[] = {
246        UnicodeString("Oct 14, 1999"),
247        UnicodeString("4th quarter 1999"),
248        UnicodeString("Oct 14, 1999"),
249        UnicodeString("Thu, Oct 14, 1999"),
250        UnicodeString("10/14/1999"),
251        UnicodeString("Oct 1999"),
252        UnicodeString("10/1999"),
253        UnicodeString("10/99"),
254        UnicodeString("O 14, 1999"),
255        UnicodeString("T, O 14"),
256        UnicodeString("Oct 14"),
257        UnicodeString("Oct 14 6:58 AM"),
258        UnicodeString("Thu, Oct 14 6:58:59 AM"),
259        UnicodeString("10/14 6:58 AM"),
260        UnicodeString("Thursday, Oct 14 6:58:59 AM"),
261        UnicodeString("Oct 14, 1999 6:58:59 AM"),
262        UnicodeString("Thu, Oct 14, 1999 6:58:59 AM"),
263        UnicodeString("6:58 AM"),
264        UnicodeString("6:58 AM"),
265        UnicodeString("6:58 AM GMT+00:00"),
266        UnicodeString(""),
267    };
268
269    // results for getSkeletons() and getPatternForSkeleton()
270    const UnicodeString testSkeletonsResults[] = {
271        UnicodeString("HH:mm"),
272        UnicodeString("MMMMd"),
273        UnicodeString("MMMMMd"),
274    };
275
276    const UnicodeString testBaseSkeletonsResults[] = {
277        UnicodeString("Hm"),
278        UnicodeString("MMMd"),
279        UnicodeString("MMMd"),
280    };
281
282    UnicodeString newDecimal(" "); // space
283    UnicodeString newAppendItemName("hrs.");
284    UnicodeString newAppendItemFormat("{1} {0}");
285    UnicodeString newDateTimeFormat("{1} {0}");
286    UErrorCode status = U_ZERO_ERROR;
287    UnicodeString conflictingPattern;
288    UDateTimePatternConflict conflictingStatus;
289
290    // ======= Test CreateInstance with default locale
291    logln("Testing DateTimePatternGenerator createInstance from default locale");
292
293    DateTimePatternGenerator *instFromDefaultLocale=DateTimePatternGenerator::createInstance(status);
294    if (U_FAILURE(status)) {
295        dataerrln("ERROR: Could not create DateTimePatternGenerator (default) - exitting");
296        return;
297    }
298    else {
299        delete instFromDefaultLocale;
300    }
301
302    // ======= Test CreateInstance with given locale
303    logln("Testing DateTimePatternGenerator createInstance from French locale");
304    status = U_ZERO_ERROR;
305    DateTimePatternGenerator *instFromLocale=DateTimePatternGenerator::createInstance(Locale::getFrench(), status);
306    if (U_FAILURE(status)) {
307        dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getFrench()) - exitting");
308        return;
309    }
310
311    // ======= Test clone DateTimePatternGenerator
312    logln("Testing DateTimePatternGenerator::clone()");
313    status = U_ZERO_ERROR;
314
315
316    UnicodeString decimalSymbol = instFromLocale->getDecimal();
317    UnicodeString newDecimalSymbol = UnicodeString("*");
318    decimalSymbol = instFromLocale->getDecimal();
319    instFromLocale->setDecimal(newDecimalSymbol);
320    DateTimePatternGenerator *cloneDTPatternGen=instFromLocale->clone();
321    decimalSymbol = cloneDTPatternGen->getDecimal();
322    if (decimalSymbol != newDecimalSymbol) {
323        errln("ERROR: inconsistency is found in cloned object.");
324    }
325    if ( !(*cloneDTPatternGen == *instFromLocale) ) {
326        errln("ERROR: inconsistency is found in cloned object.");
327    }
328
329    if ( *cloneDTPatternGen != *instFromLocale ) {
330        errln("ERROR: inconsistency is found in cloned object.");
331    }
332
333    delete instFromLocale;
334    delete cloneDTPatternGen;
335
336    // ======= Test simple use cases
337    logln("Testing simple use cases");
338    status = U_ZERO_ERROR;
339    Locale deLocale=Locale::getGermany();
340    UDate sampleDate=LocaleTest::date(99, 9, 13, 23, 58, 59);
341    DateTimePatternGenerator *gen = DateTimePatternGenerator::createInstance(deLocale, status);
342    if (U_FAILURE(status)) {
343        dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getGermany()) - exitting");
344        return;
345    }
346    UnicodeString findPattern = gen->getBestPattern(UnicodeString("MMMddHmm"), status);
347    SimpleDateFormat *format = new SimpleDateFormat(findPattern, deLocale, status);
348    if (U_FAILURE(status)) {
349        dataerrln("ERROR: Could not create SimpleDateFormat (Locale::getGermany())");
350        delete gen;
351        return;
352    }
353    TimeZone *zone = TimeZone::createTimeZone(UnicodeString("ECT"));
354    if (zone==NULL) {
355        dataerrln("ERROR: Could not create TimeZone ECT");
356        delete gen;
357        delete format;
358        return;
359    }
360    format->setTimeZone(*zone);
361    UnicodeString dateReturned, expectedResult;
362    dateReturned.remove();
363    dateReturned = format->format(sampleDate, dateReturned, status);
364    expectedResult=UnicodeString("14. Okt 08:58", -1, US_INV);
365    if ( dateReturned != expectedResult ) {
366        errln("ERROR: Simple test in getBestPattern with Locale::getGermany()).");
367    }
368    // add new pattern
369    status = U_ZERO_ERROR;
370    conflictingStatus = gen->addPattern(UnicodeString("d'. von' MMMM", -1, US_INV), true, conflictingPattern, status);
371    if (U_FAILURE(status)) {
372        errln("ERROR: Could not addPattern - d\'. von\' MMMM");
373    }
374    status = U_ZERO_ERROR;
375    UnicodeString testPattern=gen->getBestPattern(UnicodeString("MMMMdd"), status);
376    testPattern=gen->getBestPattern(UnicodeString("MMMddHmm"), status);
377    format->applyPattern(gen->getBestPattern(UnicodeString("MMMMdHmm"), status));
378    dateReturned.remove();
379    dateReturned = format->format(sampleDate, dateReturned, status);
380    expectedResult=UnicodeString("14. von Oktober 08:58", -1, US_INV);
381    if ( dateReturned != expectedResult ) {
382        errln(UnicodeString("ERROR: Simple test addPattern failed!: d\'. von\' MMMM   Got: ") + dateReturned + UnicodeString(" Expected: ") + expectedResult);
383    }
384    delete format;
385
386    // get a pattern and modify it
387    format = (SimpleDateFormat *)DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
388                                                                  deLocale);
389    format->setTimeZone(*zone);
390    UnicodeString pattern;
391    pattern = format->toPattern(pattern);
392    dateReturned.remove();
393    dateReturned = format->format(sampleDate, dateReturned, status);
394    expectedResult=CharsToUnicodeString("Donnerstag, 14. Oktober 1999 08:58:59 Mitteleurop\\u00E4ische Sommerzeit");
395    if ( dateReturned != expectedResult ) {
396        errln("ERROR: Simple test uses full date format.");
397        errln(UnicodeString(" Got: ") + dateReturned + UnicodeString(" Expected: ") + expectedResult);
398    }
399
400    // modify it to change the zone.
401    UnicodeString newPattern = gen->replaceFieldTypes(pattern, UnicodeString("vvvv"), status);
402    format->applyPattern(newPattern);
403    dateReturned.remove();
404    dateReturned = format->format(sampleDate, dateReturned, status);
405    expectedResult=UnicodeString("Donnerstag, 14. Oktober 1999 08:58:59 (Frankreich)");
406    if ( dateReturned != expectedResult ) {
407        errln("ERROR: Simple test modify the timezone!");
408        errln(UnicodeString(" Got: ")+ dateReturned + UnicodeString(" Expected: ") + expectedResult);
409    }
410
411    // setDeciaml(), getDeciaml()
412    gen->setDecimal(newDecimal);
413    if (newDecimal != gen->getDecimal()) {
414        errln("ERROR: unexpected result from setDecimal() and getDecimal()!.\n");
415    }
416
417    // setAppenItemName() , getAppendItemName()
418    gen->setAppendItemName(UDATPG_HOUR_FIELD, newAppendItemName);
419    if (newAppendItemName != gen->getAppendItemName(UDATPG_HOUR_FIELD)) {
420        errln("ERROR: unexpected result from setAppendItemName() and getAppendItemName()!.\n");
421    }
422
423    // setAppenItemFormat() , getAppendItemFormat()
424    gen->setAppendItemFormat(UDATPG_HOUR_FIELD, newAppendItemFormat);
425    if (newAppendItemFormat != gen->getAppendItemFormat(UDATPG_HOUR_FIELD)) {
426        errln("ERROR: unexpected result from setAppendItemFormat() and getAppendItemFormat()!.\n");
427    }
428
429    // setDateTimeFormat() , getDateTimeFormat()
430    gen->setDateTimeFormat(newDateTimeFormat);
431    if (newDateTimeFormat != gen->getDateTimeFormat()) {
432        errln("ERROR: unexpected result from setDateTimeFormat() and getDateTimeFormat()!.\n");
433    }
434
435    // ======== Test getSkeleton and getBaseSkeleton
436    status = U_ZERO_ERROR;
437    pattern = UnicodeString("dd-MMM");
438    UnicodeString expectedSkeleton = UnicodeString("MMMdd");
439    UnicodeString expectedBaseSkeleton = UnicodeString("MMMd");
440    UnicodeString retSkeleton = gen->getSkeleton(pattern, status);
441    if(U_FAILURE(status) || retSkeleton != expectedSkeleton ) {
442         errln("ERROR: Unexpected result from getSkeleton().\n");
443         errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected: ") + expectedSkeleton );
444    }
445    retSkeleton = gen->getBaseSkeleton(pattern, status);
446    if(U_FAILURE(status) || retSkeleton !=  expectedBaseSkeleton) {
447         errln("ERROR: Unexpected result from getBaseSkeleton().\n");
448         errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected:")+ expectedBaseSkeleton);
449    }
450
451    pattern = UnicodeString("dd/MMMM/yy");
452    expectedSkeleton = UnicodeString("yyMMMMdd");
453    expectedBaseSkeleton = UnicodeString("yMMMd");
454    retSkeleton = gen->getSkeleton(pattern, status);
455    if(U_FAILURE(status) || retSkeleton != expectedSkeleton ) {
456         errln("ERROR: Unexpected result from getSkeleton().\n");
457         errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected: ") + expectedSkeleton );
458    }
459    retSkeleton = gen->getBaseSkeleton(pattern, status);
460    if(U_FAILURE(status) || retSkeleton !=  expectedBaseSkeleton) {
461         errln("ERROR: Unexpected result from getBaseSkeleton().\n");
462         errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected:")+ expectedBaseSkeleton);
463    }
464    delete format;
465    delete zone;
466    delete gen;
467
468    {
469        // Trac# 6104
470        status = U_ZERO_ERROR;
471        pattern = UnicodeString("YYYYMMM");
472        UnicodeString expR = CharsToUnicodeString("1999\\u5E741\\u6708"); // fixed expected result per ticket:6626:
473        Locale loc("ja");
474        UDate testDate1= LocaleTest::date(99, 0, 13, 23, 58, 59);
475        DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
476        if(U_FAILURE(status)) {
477            dataerrln("ERROR: Could not create DateTimePatternGenerator");
478            return;
479        }
480        UnicodeString bPattern = patGen->getBestPattern(pattern, status);
481        UnicodeString rDate;
482        SimpleDateFormat sdf(bPattern, loc, status);
483        rDate.remove();
484        rDate = sdf.format(testDate1, rDate);
485
486        logln(UnicodeString(" ja locale with skeleton: YYYYMMM  Best Pattern:") + bPattern);
487        logln(UnicodeString("  Formatted date:") + rDate);
488
489        if ( expR!= rDate ) {
490            errln(UnicodeString("\nERROR: Test Japanese month hack Got: ") + rDate +
491                  UnicodeString(" Expected: ") + expR );
492        }
493
494        delete patGen;
495    }
496    {   // Trac# 6104
497        Locale loc("zh");
498        UnicodeString expR = CharsToUnicodeString("1999\\u5E741\\u6708"); // fixed expected result per ticket:6626:
499        UDate testDate1= LocaleTest::date(99, 0, 13, 23, 58, 59);
500        DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
501        if(U_FAILURE(status)) {
502            dataerrln("ERROR: Could not create DateTimePatternGenerator");
503            return;
504        }
505        UnicodeString bPattern = patGen->getBestPattern(pattern, status);
506        UnicodeString rDate;
507        SimpleDateFormat sdf(bPattern, loc, status);
508        rDate.remove();
509        rDate = sdf.format(testDate1, rDate);
510
511        logln(UnicodeString(" zh locale with skeleton: YYYYMMM  Best Pattern:") + bPattern);
512        logln(UnicodeString("  Formatted date:") + rDate);
513        if ( expR!= rDate ) {
514            errln(UnicodeString("\nERROR: Test Chinese month hack Got: ") + rDate +
515                  UnicodeString(" Expected: ") + expR );
516        }
517        delete patGen;
518    }
519
520    {
521         // Trac# 6172 duplicate time pattern
522         status = U_ZERO_ERROR;
523         pattern = UnicodeString("hmv");
524         UnicodeString expR = UnicodeString("h:mm a v"); // avail formats has hm -> "h:mm a" (fixed expected result per ticket:6626:)
525         Locale loc("en");
526         DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
527         if(U_FAILURE(status)) {
528             dataerrln("ERROR: Could not create DateTimePatternGenerator");
529             return;
530         }
531         UnicodeString bPattern = patGen->getBestPattern(pattern, status);
532         logln(UnicodeString(" en locale with skeleton: hmv  Best Pattern:") + bPattern);
533
534         if ( expR!= bPattern ) {
535             errln(UnicodeString("\nERROR: Test EN time format Got: ") + bPattern +
536                   UnicodeString(" Expected: ") + expR );
537         }
538
539         delete patGen;
540     }
541
542
543    // ======= Test various skeletons.
544    logln("Testing DateTimePatternGenerator with various skeleton");
545
546    status = U_ZERO_ERROR;
547    int32_t localeIndex=0;
548    int32_t resultIndex=0;
549    UnicodeString resultDate;
550    UDate testDate= LocaleTest::date(99, 0, 13, 23, 58, 59);
551    while (localeIndex < MAX_LOCALE )
552    {
553        int32_t dataIndex=0;
554        UnicodeString bestPattern;
555
556        Locale loc(testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2], testLocale[localeIndex][3]);
557        logln("\n\n Locale: %s_%s_%s@%s", testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2], testLocale[localeIndex][3]);
558        DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
559        if(U_FAILURE(status)) {
560            dataerrln("ERROR: Could not create DateTimePatternGenerator with locale index:%d . - exitting\n", localeIndex);
561            return;
562        }
563        while (patternData[dataIndex].length() > 0) {
564            log(patternData[dataIndex]);
565            bestPattern = patGen->getBestPattern(patternData[dataIndex++], status);
566            logln(UnicodeString(" -> ") + bestPattern);
567
568            SimpleDateFormat sdf(bestPattern, loc, status);
569            resultDate.remove();
570            resultDate = sdf.format(testDate, resultDate);
571            if ( resultDate != patternResults[resultIndex] ) {
572                errln(UnicodeString("\nERROR: Test various skeletons[") + (dataIndex-1) + UnicodeString("], localeIndex ") + localeIndex +
573                      UnicodeString(". Got: \"") + resultDate + UnicodeString("\" Expected: \"") + patternResults[resultIndex] + "\"" );
574            }
575
576            resultIndex++;
577        }
578        delete patGen;
579        localeIndex++;
580    }
581
582    // ======= More tests ticket#6110
583    logln("Testing DateTimePatternGenerator with various skeleton");
584
585    status = U_ZERO_ERROR;
586    localeIndex=0;
587    resultIndex=0;
588    testDate= LocaleTest::date(99, 9, 13, 23, 58, 59);
589    {
590        int32_t dataIndex=0;
591        UnicodeString bestPattern;
592        logln("\n\n Test various skeletons for English locale...");
593        DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(Locale::getEnglish(), status);
594        if(U_FAILURE(status)) {
595            dataerrln("ERROR: Could not create DateTimePatternGenerator with locale English . - exitting\n");
596            return;
597        }
598        TimeZone *enZone = TimeZone::createTimeZone(UnicodeString("ECT/GMT"));
599        if (enZone==NULL) {
600            dataerrln("ERROR: Could not create TimeZone ECT");
601            delete patGen;
602            return;
603        }
604        SimpleDateFormat *enFormat = (SimpleDateFormat *)DateFormat::createDateTimeInstance(DateFormat::kFull,
605                         DateFormat::kFull, Locale::getEnglish());
606        enFormat->setTimeZone(*enZone);
607        while (patternTests2[dataIndex].length() > 0) {
608            logln(patternTests2[dataIndex]);
609            bestPattern = patGen->getBestPattern(patternTests2[dataIndex], status);
610            logln(UnicodeString(" -> ") + bestPattern);
611            enFormat->applyPattern(bestPattern);
612            resultDate.remove();
613            resultDate = enFormat->format(testDate, resultDate);
614            if ( resultDate != patternResults2[resultIndex] ) {
615                errln(UnicodeString("\nERROR: Test various skeletons[") + dataIndex
616                    + UnicodeString("]. Got: ") + resultDate + UnicodeString(" Expected: ") +
617                    patternResults2[resultIndex] );
618            }
619            dataIndex++;
620            resultIndex++;
621        }
622        delete patGen;
623        delete enZone;
624        delete enFormat;
625    }
626
627
628
629    // ======= Test random skeleton
630    DateTimePatternGenerator *randDTGen= DateTimePatternGenerator::createInstance(status);
631    if (U_FAILURE(status)) {
632        dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getFrench()) - exitting");
633        return;
634    }
635    UChar newChar;
636    int32_t i;
637    for (i=0; i<10; ++i) {
638        UnicodeString randomSkeleton;
639        int32_t len = rand() % 20;
640        for (int32_t j=0; j<len; ++j ) {
641            while ((newChar = (UChar)(rand()%0x7f))>=(UChar)0x20) {
642                randomSkeleton += newChar;
643            }
644        }
645        UnicodeString bestPattern = randDTGen->getBestPattern(randomSkeleton, status);
646    }
647    delete randDTGen;
648
649    // UnicodeString randomString=Unicode
650    // ======= Test getStaticClassID()
651
652    logln("Testing getStaticClassID()");
653    status = U_ZERO_ERROR;
654    DateTimePatternGenerator *test= DateTimePatternGenerator::createInstance(status);
655
656    if(test->getDynamicClassID() != DateTimePatternGenerator::getStaticClassID()) {
657        errln("ERROR: getDynamicClassID() didn't return the expected value");
658    }
659    delete test;
660
661    // ====== Test createEmptyInstance()
662
663    logln("Testing createEmptyInstance()");
664    status = U_ZERO_ERROR;
665
666    test = DateTimePatternGenerator::createEmptyInstance(status);
667    if(U_FAILURE(status)) {
668         errln("ERROR: Fail to create an empty instance ! - exitting.\n");
669         delete test;
670         return;
671    }
672
673    conflictingStatus = test->addPattern(UnicodeString("MMMMd"), true, conflictingPattern, status);
674    status = U_ZERO_ERROR;
675    testPattern=test->getBestPattern(UnicodeString("MMMMdd"), status);
676    conflictingStatus = test->addPattern(UnicodeString("HH:mm"), true, conflictingPattern, status);
677    conflictingStatus = test->addPattern(UnicodeString("MMMMMd"), true, conflictingPattern, status); //duplicate pattern
678    StringEnumeration *output=NULL;
679    output = test->getRedundants(status);
680    expectedResult=UnicodeString("MMMMd");
681    if (output != NULL) {
682        output->reset(status);
683        const UnicodeString *dupPattern=output->snext(status);
684        if ( (dupPattern==NULL) || (*dupPattern != expectedResult) ) {
685            errln("ERROR: Fail in getRedundants !\n");
686        }
687    }
688
689    // ======== Test getSkeletons and getBaseSkeletons
690    StringEnumeration* ptrSkeletonEnum = test->getSkeletons(status);
691    if(U_FAILURE(status)) {
692        errln("ERROR: Fail to get skeletons !\n");
693    }
694    UnicodeString returnPattern, *ptrSkeleton;
695    ptrSkeletonEnum->reset(status);
696    int32_t count=ptrSkeletonEnum->count(status);
697    for (i=0; i<count; ++i) {
698        ptrSkeleton = (UnicodeString *)ptrSkeletonEnum->snext(status);
699        returnPattern = test->getPatternForSkeleton(*ptrSkeleton);
700        if ( returnPattern != testSkeletonsResults[i] ) {
701            errln(UnicodeString("ERROR: Unexpected result from getSkeletons and getPatternForSkeleton\nGot: ") + returnPattern
702               + UnicodeString("\nExpected: ") + testSkeletonsResults[i]
703               + UnicodeString("\n"));
704        }
705    }
706    StringEnumeration* ptrBaseSkeletonEnum = test->getBaseSkeletons(status);
707    if(U_FAILURE(status)) {
708        errln("ERROR: Fail to get base skeletons !\n");
709    }
710    count=ptrBaseSkeletonEnum->count(status);
711    for (i=0; i<count; ++i) {
712        ptrSkeleton = (UnicodeString *)ptrBaseSkeletonEnum->snext(status);
713        if ( *ptrSkeleton != testBaseSkeletonsResults[i] ) {
714            errln("ERROR: Unexpected result from getBaseSkeletons() !\n");
715        }
716    }
717
718    // ========= DateTimePatternGenerator sample code in Userguide
719    // set up the generator
720    Locale locale = Locale::getFrench();
721    status = U_ZERO_ERROR;
722    DateTimePatternGenerator *generator = DateTimePatternGenerator::createInstance( locale, status);
723
724    // get a pattern for an abbreviated month and day
725    pattern = generator->getBestPattern(UnicodeString("MMMd"), status);
726    SimpleDateFormat formatter(pattern, locale, status);
727
728    zone = TimeZone::createTimeZone(UnicodeString("GMT"));
729    formatter.setTimeZone(*zone);
730    // use it to format (or parse)
731    UnicodeString formatted;
732    formatted = formatter.format(Calendar::getNow(), formatted, status);
733    // for French, the result is "13 sept."
734    formatted.remove();
735    // cannot use the result from getNow() because the value change evreyday.
736    testDate= LocaleTest::date(99, 0, 13, 23, 58, 59);
737    formatted = formatter.format(testDate, formatted, status);
738    expectedResult=UnicodeString("14 janv.");
739    if ( formatted != expectedResult ) {
740        errln("ERROR: Userguide sample code result!");
741        errln(UnicodeString(" Got: ")+ formatted + UnicodeString(" Expected: ") + expectedResult);
742    }
743
744    delete zone;
745    delete output;
746    delete ptrSkeletonEnum;
747    delete ptrBaseSkeletonEnum;
748    delete test;
749    delete generator;
750}
751
752/**
753 * Test handling of options
754 *
755 * For reference, as of ICU 4.3.3,
756 *  root/gregorian has
757 *      Hm{"H:mm"}
758 *      Hms{"H:mm:ss"}
759 *      hm{"h:mm a"}
760 *      hms{"h:mm:ss a"}
761 *  en/gregorian has
762 *      Hm{"H:mm"}
763 *      Hms{"H:mm:ss"}
764 *      hm{"h:mm a"}
765 *  be/gregorian has
766 *      HHmmss{"HH.mm.ss"}
767 *      Hm{"HH.mm"}
768 *      hm{"h.mm a"}
769 *      hms{"h.mm.ss a"}
770 */
771typedef struct DTPtnGenOptionsData {
772    const char *locale;
773    const char *skel;
774    const char *expectedPattern;
775    UDateTimePatternMatchOptions    options;
776} DTPtnGenOptionsData;
777void IntlTestDateTimePatternGeneratorAPI::testOptions(/*char *par*/)
778{
779    DTPtnGenOptionsData testData[] = {
780    //   locale  skel   expectedPattern     options
781        { "en", "Hmm",  "HH:mm",   UDATPG_MATCH_NO_OPTIONS        },
782        { "en", "HHmm", "HH:mm",   UDATPG_MATCH_NO_OPTIONS        },
783        { "en", "hhmm", "h:mm a",  UDATPG_MATCH_NO_OPTIONS        },
784        { "en", "Hmm",  "HH:mm",   UDATPG_MATCH_HOUR_FIELD_LENGTH },
785        { "en", "HHmm", "HH:mm",   UDATPG_MATCH_HOUR_FIELD_LENGTH },
786        { "en", "hhmm", "hh:mm a", UDATPG_MATCH_HOUR_FIELD_LENGTH },
787        { "be", "Hmm",  "HH.mm",   UDATPG_MATCH_NO_OPTIONS        },
788        { "be", "HHmm", "HH.mm",   UDATPG_MATCH_NO_OPTIONS        },
789        { "be", "hhmm", "h.mm a",  UDATPG_MATCH_NO_OPTIONS        },
790        { "be", "Hmm",  "H.mm",    UDATPG_MATCH_HOUR_FIELD_LENGTH },
791        { "be", "HHmm", "HH.mm",   UDATPG_MATCH_HOUR_FIELD_LENGTH },
792        { "be", "hhmm", "hh.mm a", UDATPG_MATCH_HOUR_FIELD_LENGTH },
793    };
794
795    int count = sizeof(testData) / sizeof(testData[0]);
796    const DTPtnGenOptionsData * testDataPtr = testData;
797
798    for (; count-- > 0; ++testDataPtr) {
799        UErrorCode status = U_ZERO_ERROR;
800
801        Locale locale(testDataPtr->locale);
802        UnicodeString skel(testDataPtr->skel);
803        UnicodeString expectedPattern(testDataPtr->expectedPattern);
804        UDateTimePatternMatchOptions options = testDataPtr->options;
805
806        DateTimePatternGenerator * dtpgen = DateTimePatternGenerator::createInstance(locale, status);
807        if (U_FAILURE(status)) {
808            dataerrln("Unable to create DateTimePatternGenerator instance for locale(%s): %s", locale.getName(), u_errorName(status));
809            delete dtpgen;
810            continue;
811        }
812        UnicodeString pattern = dtpgen->getBestPattern(skel, options, status);
813        if (pattern.compare(expectedPattern) != 0) {
814            errln( UnicodeString("ERROR in getBestPattern, locale ") + UnicodeString(testDataPtr->locale) +
815                   UnicodeString(", skeleton ") + skel +
816                   ((options)?UnicodeString(", options!=0"):UnicodeString(", options==0")) +
817                   UnicodeString(", expected pattern ") + expectedPattern +
818                   UnicodeString(", got ") + pattern );
819        }
820        delete dtpgen;
821    }
822}
823
824#endif /* #if !UCONFIG_NO_FORMATTING */
825