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