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