1 
2 /********************************************************************
3  * COPYRIGHT:
4  * Copyright (c) 1997-2015, International Business Machines Corporation and
5  * others. All Rights Reserved.
6  ********************************************************************/
7 
8 #include "unicode/utypes.h"
9 
10 #if !UCONFIG_NO_FORMATTING
11 
12 
13 //TODO: define it in compiler flag
14 //#define DTIFMTTS_DEBUG 1
15 
16 
17 #ifdef DTIFMTTS_DEBUG
18 #include <iostream>
19 #endif
20 
21 
22 #include "cstring.h"
23 #include "dtifmtts.h"
24 #include "unicode/gregocal.h"
25 #include "unicode/dtintrv.h"
26 #include "unicode/dtitvinf.h"
27 #include "unicode/dtitvfmt.h"
28 #include "unicode/localpointer.h"
29 #include "unicode/timezone.h"
30 
31 
32 
33 #ifdef DTIFMTTS_DEBUG
34 //#define PRINTMESG(msg) { std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; }
35 #define PRINTMESG(msg) { std::cout << msg; }
36 #endif
37 
38 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
39 
40 #include <stdio.h>
41 
42 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)43 void DateIntervalFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) {
44     if (exec) logln("TestSuite DateIntervalFormat");
45     switch (index) {
46         TESTCASE(0, testAPI);
47         TESTCASE(1, testFormat);
48         TESTCASE(2, testFormatUserDII);
49         TESTCASE(3, testSetIntervalPatternNoSideEffect);
50         TESTCASE(4, testYearFormats);
51         TESTCASE(5, testStress);
52         TESTCASE(6, testTicket11583_2);
53         default: name = ""; break;
54     }
55 }
56 
57 /**
58  * Test various generic API methods of DateIntervalFormat for API coverage.
59  */
testAPI()60 void DateIntervalFormatTest::testAPI() {
61 
62     /* ====== Test create interval instance with default locale and skeleton
63      */
64     UErrorCode status = U_ZERO_ERROR;
65     logln("Testing DateIntervalFormat create instance with default locale and skeleton");
66 
67     DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, status);
68     if(U_FAILURE(status)) {
69         dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + default locale) - exitting");
70         return;
71     } else {
72         delete dtitvfmt;
73     }
74 
75 
76     /* ====== Test create interval instance with given locale and skeleton
77      */
78     status = U_ZERO_ERROR;
79     logln("Testing DateIntervalFormat create instance with given locale and skeleton");
80 
81     dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getJapanese(), status);
82     if(U_FAILURE(status)) {
83         dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + locale) - exitting");
84         return;
85     } else {
86         delete dtitvfmt;
87     }
88 
89 
90     /* ====== Test create interval instance with dateIntervalInfo and skeleton
91      */
92     status = U_ZERO_ERROR;
93     logln("Testing DateIntervalFormat create instance with dateIntervalInfo  and skeleton");
94 
95     DateIntervalInfo* dtitvinf = new DateIntervalInfo(Locale::getSimplifiedChinese(), status);
96 
97     dtitvfmt = DateIntervalFormat::createInstance("EEEdMMMyhms", *dtitvinf, status);
98     delete dtitvinf;
99 
100     if(U_FAILURE(status)) {
101         dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + DateIntervalInfo + default locale) - exitting");
102         return;
103     } else {
104         delete dtitvfmt;
105     }
106 
107 
108     /* ====== Test create interval instance with dateIntervalInfo and skeleton
109      */
110     status = U_ZERO_ERROR;
111     logln("Testing DateIntervalFormat create instance with dateIntervalInfo  and skeleton");
112 
113     dtitvinf = new DateIntervalInfo(Locale::getSimplifiedChinese(), status);
114 
115     dtitvfmt = DateIntervalFormat::createInstance("EEEdMMMyhms", Locale::getSimplifiedChinese(), *dtitvinf, status);
116     delete dtitvinf;
117     if(U_FAILURE(status)) {
118         dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + DateIntervalInfo + locale) - exitting");
119         return;
120     }
121     // not deleted, test clone
122 
123 
124     // ====== Test clone()
125     status = U_ZERO_ERROR;
126     logln("Testing DateIntervalFormat clone");
127 
128     DateIntervalFormat* another = (DateIntervalFormat*)dtitvfmt->clone();
129     if ( (*another) != (*dtitvfmt) ) {
130         dataerrln("ERROR: clone failed");
131     }
132 
133 
134     // ====== Test getDateIntervalInfo, setDateIntervalInfo, adoptDateIntervalInfo
135     status = U_ZERO_ERROR;
136     logln("Testing DateIntervalFormat getDateIntervalInfo");
137     const DateIntervalInfo* inf = another->getDateIntervalInfo();
138     dtitvfmt->setDateIntervalInfo(*inf, status);
139     const DateIntervalInfo* anotherInf = dtitvfmt->getDateIntervalInfo();
140     if ( (*inf) != (*anotherInf) || U_FAILURE(status) ) {
141         dataerrln("ERROR: getDateIntervalInfo/setDateIntervalInfo failed");
142     }
143 
144     {
145         // We make sure that setDateIntervalInfo does not corrupt the cache. See ticket 9919.
146         status = U_ZERO_ERROR;
147         logln("Testing DateIntervalFormat setDateIntervalInfo");
148         const Locale &enLocale = Locale::getEnglish();
149         LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yMd", enLocale, status));
150         if (U_FAILURE(status)) {
151             errln("Failure encountered: %s", u_errorName(status));
152             return;
153         }
154         UnicodeString expected;
155         LocalPointer<Calendar> fromTime(Calendar::createInstance(enLocale, status));
156         LocalPointer<Calendar> toTime(Calendar::createInstance(enLocale, status));
157         if (U_FAILURE(status)) {
158             errln("Failure encountered: %s", u_errorName(status));
159             return;
160         }
161         FieldPosition pos = 0;
162         fromTime->set(2013, 3, 26);
163         toTime->set(2013, 3, 28);
164         dif->format(*fromTime, *toTime, expected, pos, status);
165         if (U_FAILURE(status)) {
166             errln("Failure encountered: %s", u_errorName(status));
167             return;
168         }
169         LocalPointer<DateIntervalInfo> dii(new DateIntervalInfo(Locale::getEnglish(), status), status);
170         if (U_FAILURE(status)) {
171             errln("Failure encountered: %s", u_errorName(status));
172             return;
173         }
174         dii->setIntervalPattern(ctou("yMd"), UCAL_DATE, ctou("M/d/y \\u2013 d"), status);
175         dif->setDateIntervalInfo(*dii, status);
176         if (U_FAILURE(status)) {
177             errln("Failure encountered: %s", u_errorName(status));
178             return;
179         }
180         dif.adoptInstead(DateIntervalFormat::createInstance("yMd", enLocale, status));
181         if (U_FAILURE(status)) {
182             errln("Failure encountered: %s", u_errorName(status));
183             return;
184         }
185         UnicodeString actual;
186         pos = 0;
187         dif->format(*fromTime, *toTime, actual, pos, status);
188         if (U_FAILURE(status)) {
189             errln("Failure encountered: %s", u_errorName(status));
190             return;
191         }
192         if (expected != actual) {
193             errln("DateIntervalFormat.setIntervalInfo should have no side effects.");
194         }
195     }
196 
197     /*
198     status = U_ZERO_ERROR;
199     DateIntervalInfo* nonConstInf = inf->clone();
200     dtitvfmt->adoptDateIntervalInfo(nonConstInf, status);
201     anotherInf = dtitvfmt->getDateIntervalInfo();
202     if ( (*inf) != (*anotherInf) || U_FAILURE(status) ) {
203         dataerrln("ERROR: adoptDateIntervalInfo failed");
204     }
205     */
206 
207     // ====== Test getDateFormat, setDateFormat, adoptDateFormat
208 
209     status = U_ZERO_ERROR;
210     logln("Testing DateIntervalFormat getDateFormat");
211     /*
212     const DateFormat* fmt = another->getDateFormat();
213     dtitvfmt->setDateFormat(*fmt, status);
214     const DateFormat* anotherFmt = dtitvfmt->getDateFormat();
215     if ( (*fmt) != (*anotherFmt) || U_FAILURE(status) ) {
216         dataerrln("ERROR: getDateFormat/setDateFormat failed");
217     }
218 
219     status = U_ZERO_ERROR;
220     DateFormat* nonConstFmt = (DateFormat*)fmt->clone();
221     dtitvfmt->adoptDateFormat(nonConstFmt, status);
222     anotherFmt = dtitvfmt->getDateFormat();
223     if ( (*fmt) != (*anotherFmt) || U_FAILURE(status) ) {
224         dataerrln("ERROR: adoptDateFormat failed");
225     }
226     delete fmt;
227     */
228 
229 
230     // ======= Test getStaticClassID()
231 
232     logln("Testing getStaticClassID()");
233 
234 
235     if(dtitvfmt->getDynamicClassID() != DateIntervalFormat::getStaticClassID()) {
236         errln("ERROR: getDynamicClassID() didn't return the expected value");
237     }
238 
239     delete another;
240 
241     // ====== test constructor/copy constructor and assignment
242     /* they are protected, no test
243     logln("Testing DateIntervalFormat constructor and assigment operator");
244     status = U_ZERO_ERROR;
245 
246     DateFormat* constFmt = (constFmt*)dtitvfmt->getDateFormat()->clone();
247     inf = dtitvfmt->getDateIntervalInfo()->clone();
248 
249 
250     DateIntervalFormat* dtifmt = new DateIntervalFormat(fmt, inf, status);
251     if(U_FAILURE(status)) {
252         dataerrln("ERROR: Could not create DateIntervalFormat (default) - exitting");
253         return;
254     }
255 
256     DateIntervalFormat* dtifmt2 = new(dtifmt);
257     if ( (*dtifmt) != (*dtifmt2) ) {
258         dataerrln("ERROR: Could not create DateIntervalFormat (default) - exitting");
259         return;
260     }
261 
262     DateIntervalFormat dtifmt3 = (*dtifmt);
263     if ( (*dtifmt) != dtifmt3 ) {
264         dataerrln("ERROR: Could not create DateIntervalFormat (default) - exitting");
265         return;
266     }
267 
268     delete dtifmt2;
269     delete dtifmt3;
270     delete dtifmt;
271     */
272 
273 
274     //===== test format and parse ==================
275     Formattable formattable;
276     formattable.setInt64(10);
277     UnicodeString res;
278     FieldPosition pos = 0;
279     status = U_ZERO_ERROR;
280     dtitvfmt->format(formattable, res, pos, status);
281     if ( status != U_ILLEGAL_ARGUMENT_ERROR ) {
282         dataerrln("ERROR: format non-date-interval object should set U_ILLEGAL_ARGUMENT_ERROR - exitting");
283         return;
284     }
285 
286     DateInterval* dtitv = new DateInterval(3600*24*365, 3600*24*366);
287     formattable.adoptObject(dtitv);
288     res.remove();
289     pos = 0;
290     status = U_ZERO_ERROR;
291     dtitvfmt->format(formattable, res, pos, status);
292     if ( U_FAILURE(status) ) {
293         dataerrln("ERROR: format date interval failed - exitting");
294         return;
295     }
296 
297     const DateFormat* dfmt = dtitvfmt->getDateFormat();
298     Calendar* fromCal = dfmt->getCalendar()->clone();
299     Calendar* toCal = dfmt->getCalendar()->clone();
300     res.remove();
301     pos = 0;
302     status = U_ZERO_ERROR;
303     dtitvfmt->format(*fromCal, *toCal, res, pos, status);
304     if ( U_FAILURE(status) ) {
305         dataerrln("ERROR: format date interval failed - exitting");
306         return;
307     }
308     delete fromCal;
309     delete toCal;
310 
311 
312     Formattable fmttable;
313     status = U_ZERO_ERROR;
314     // TODO: why do I need cast?
315     ((Format*)dtitvfmt)->parseObject(res, fmttable, status);
316     if ( status != U_INVALID_FORMAT_ERROR ) {
317         dataerrln("ERROR: parse should set U_INVALID_FORMAT_ERROR - exitting");
318         return;
319     }
320 
321     delete dtitvfmt;
322 
323     //====== test setting time zone
324     logln("Testing DateIntervalFormat set & format with different time zones, get time zone");
325     status = U_ZERO_ERROR;
326     dtitvfmt = DateIntervalFormat::createInstance("MMMdHHmm", Locale::getEnglish(), status);
327     if ( U_SUCCESS(status) ) {
328         UDate date1 = 1299090600000.0; // 2011-Mar-02 1030 in US/Pacific, 2011-Mar-03 0330 in Asia/Tokyo
329         UDate date2 = 1299115800000.0; // 2011-Mar-02 1730 in US/Pacific, 2011-Mar-03 1030 in Asia/Tokyo
330 
331         DateInterval * dtitv12 = new DateInterval(date1, date2);
332         TimeZone * tzCalif = TimeZone::createTimeZone("US/Pacific");
333         TimeZone * tzTokyo = TimeZone::createTimeZone("Asia/Tokyo");
334         UnicodeString fmtCalif = UnicodeString(ctou("Mar 2, 10:30 \\u2013 17:30"));
335         UnicodeString fmtTokyo = UnicodeString(ctou("Mar 3, 03:30 \\u2013 10:30"));
336 
337         dtitvfmt->adoptTimeZone(tzCalif);
338         res.remove();
339         pos = 0;
340         status = U_ZERO_ERROR;
341         dtitvfmt->format(dtitv12, res, pos, status);
342         if ( U_SUCCESS(status) ) {
343             if ( res.compare(fmtCalif) != 0 ) {
344                 errln("ERROR: DateIntervalFormat::format for tzCalif, expect " + fmtCalif + ", get " + res);
345             }
346         } else {
347             errln("ERROR: DateIntervalFormat::format for tzCalif, status %s", u_errorName(status));
348         }
349 
350         dtitvfmt->setTimeZone(*tzTokyo);
351         res.remove();
352         pos = 0;
353         status = U_ZERO_ERROR;
354         dtitvfmt->format(dtitv12, res, pos, status);
355         if ( U_SUCCESS(status) ) {
356             if ( res.compare(fmtTokyo) != 0 ) {
357                 errln("ERROR: DateIntervalFormat::format for fmtTokyo, expect " + fmtTokyo + ", get " + res);
358             }
359         } else {
360             errln("ERROR: DateIntervalFormat::format for tzTokyo, status %s", u_errorName(status));
361         }
362 
363         if ( dtitvfmt->getTimeZone() != *tzTokyo ) {
364             errln("ERROR: DateIntervalFormat::getTimeZone returns mismatch.");
365         }
366 
367         delete tzTokyo; // tzCalif was owned by dtitvfmt which should have deleted it
368         delete dtitv12;
369         delete dtitvfmt;
370     } else {
371         errln("ERROR: DateIntervalFormat::createInstance(\"MdHH\", Locale::getEnglish(), ...), status %s", u_errorName(status));
372     }
373     //====== test format  in testFormat()
374 
375     //====== test DateInterval class (better coverage)
376     DateInterval dtitv1(3600*24*365, 3600*24*366);
377     DateInterval dtitv2(dtitv1);
378 
379     if (!(dtitv1 == dtitv2)) {
380         errln("ERROR: Copy constructor failed for DateInterval.");
381     }
382 
383     DateInterval dtitv3(3600*365, 3600*366);
384     dtitv3 = dtitv1;
385     if (!(dtitv3 == dtitv1)) {
386         errln("ERROR: Equal operator failed for DateInterval.");
387     }
388 
389     DateInterval *dtitv4 = dtitv1.clone();
390     if (*dtitv4 != dtitv1) {
391         errln("ERROR: Equal operator failed for DateInterval.");
392     }
393     delete dtitv4;
394 }
395 
396 
397 /**
398  * Test format
399  */
testFormat()400 void DateIntervalFormatTest::testFormat() {
401     // first item is date pattern
402     // followed by a group of locale/from_data/to_data/skeleton/interval_data
403     const char* DATA[] = {
404         "yyyy MM dd HH:mm:ss",
405         // test root
406         "root", "2007 11 10 10:10:10", "2007 12 10 10:10:10", "yM", "2007-11 \\u2013 2007-12",
407 
408         // test 'H' and 'h', using availableFormat in fallback
409         "en", "2007 11 10 10:10:10", "2007 11 10 15:10:10", "Hms", "10:10:10 \\u2013 15:10:10",
410         "en", "2007 11 10 10:10:10", "2007 11 10 15:10:10", "hms", "10:10:10 AM \\u2013 3:10:10 PM",
411 
412         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMM", "October 2007 \\u2013 October 2008",
413         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMM", "Oct 2007 \\u2013 Oct 2008",
414         // test skeleton with both date and time
415         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 AM \\u2013 Nov 20, 2007, 10:10 AM",
416 
417         "en", "2007 11 10 10:10:10", "2007 11 10 11:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 \\u2013 11:10 AM",
418 
419         "en", "2007 11 10 10:10:10", "2007 11 10 11:10:10", "hms", "10:10:10 AM \\u2013 11:10:10 AM",
420         "en", "2007 11 10 10:10:10", "2007 11 10 11:10:10", "Hms", "10:10:10 \\u2013 11:10:10",
421         "en", "2007 11 10 20:10:10", "2007 11 10 21:10:10", "Hms", "20:10:10 \\u2013 21:10:10",
422 
423         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
424 
425         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMMy", "October 10, 2007 \\u2013 October 10, 2008",
426 
427         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMM", "October 10, 2007 \\u2013 October 10, 2008",
428 
429         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMMy", "October 2007 \\u2013 October 2008",
430 
431         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
432 
433         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMMMy", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
434 
435         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMy", "Oct 10, 2007 \\u2013 Oct 10, 2008",
436 
437         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMM", "Oct 10, 2007 \\u2013 Oct 10, 2008",
438 
439         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMy", "Oct 2007 \\u2013 Oct 2008",
440 
441         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMMM", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
442 
443         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
444 
445         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMy", "10/10/2007 \\u2013 10/10/2008",
446 
447         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dM", "10/10/2007 \\u2013 10/10/2008",
448 
449         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "My", "10/2007 \\u2013 10/2008",
450 
451         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdM", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
452 
453         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "d", "10/10/2007 \\u2013 10/10/2008",
454 
455         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "Ed", "10 Wed \\u2013 10 Fri",
456 
457         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "y", "2007 \\u2013 2008",
458 
459         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "M", "10/2007 \\u2013 10/2008",
460 
461 
462 
463         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
464         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "Hm", "10/10/2007, 10:10 \\u2013 10/10/2008, 10:10",
465         "en", "2007 10 10 20:10:10", "2008 10 10 20:10:10", "Hm", "10/10/2007, 20:10 \\u2013 10/10/2008, 20:10",
466 
467         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 10/10/2008, 10:10 AM PT",
468 
469         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
470 
471         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 10/10/2008, 10 AM",
472 
473         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 10/10/2008, 10 AM PT",
474 
475         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 10/10/2008, 10 AM PDT",
476 
477         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
478 
479         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
480 
481         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
482 
483         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
484 
485         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 10/10/2008, 10:10:10 AM",
486 
487         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMMMMy", "O 10, 2007 \\u2013 O 10, 2008",
488 
489         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEEdM", "W, 10/10/2007 \\u2013 F, 10/10/2008",
490 
491         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10 \\u2013 Saturday, November 10, 2007",
492 
493         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMMy", "October 10 \\u2013 November 10, 2007",
494 
495         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMM", "October 10 \\u2013 November 10",
496 
497         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMMy", "October \\u2013 November 2007",
498 
499         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10 \\u2013 Saturday, November 10",
500 
501         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdMMMy", "Wed, Oct 10 \\u2013 Sat, Nov 10, 2007",
502 
503         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMy", "Oct 10 \\u2013 Nov 10, 2007",
504 
505         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMM", "Oct 10 \\u2013 Nov 10",
506 
507         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMy", "Oct \\u2013 Nov 2007",
508 
509         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdMMM", "Wed, Oct 10 \\u2013 Sat, Nov 10",
510 
511         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
512 
513         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMy", "10/10/2007 \\u2013 11/10/2007",
514 
515 
516         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "My", "10/2007 \\u2013 11/2007",
517 
518         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EdM", "Wed, 10/10 \\u2013 Sat, 11/10",
519 
520         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "d", "10/10 \\u2013 11/10",
521 
522         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "Ed", "10 Wed \\u2013 10 Sat",
523 
524         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "y", "2007",
525 
526         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "M", "10 \\u2013 11",
527 
528         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMM", "Oct \\u2013 Nov",
529 
530         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMM", "October \\u2013 November",
531 
532         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 11/10/2007, 10:10 AM",
533         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "Hm", "10/10/2007, 10:10 \\u2013 11/10/2007, 10:10",
534         "en", "2007 10 10 20:10:10", "2007 11 10 20:10:10", "Hm", "10/10/2007, 20:10 \\u2013 11/10/2007, 20:10",
535 
536         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 11/10/2007, 10:10 AM PT",
537 
538         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
539 
540         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 11/10/2007, 10 AM",
541 
542         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 11/10/2007, 10 AM PT",
543 
544         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 11/10/2007, 10 AM PST",
545 
546         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
547 
548         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
549 
550 
551         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
552 
553         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 11/10/2007, 10:10:10 AM",
554 
555         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMMMy", "O 10 \\u2013 N 10, 2007",
556 
557         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEEdM", "W, 10/10 \\u2013 S, 11/10",
558 
559         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMMy", "Saturday, November 10 \\u2013 Tuesday, November 20, 2007",
560 
561         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMMy", "November 10 \\u2013 20, 2007",
562 
563         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMM", "November 10 \\u2013 20",
564 
565 
566         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMM", "Saturday, November 10 \\u2013 Tuesday, November 20",
567 
568         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMMMy", "Sat, Nov 10 \\u2013 Tue, Nov 20, 2007",
569 
570         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMy", "Nov 10 \\u2013 20, 2007",
571 
572         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMM", "Nov 10 \\u2013 20",
573 
574         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMy", "Nov 2007",
575 
576         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMMM", "Sat, Nov 10 \\u2013 Tue, Nov 20",
577 
578         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
579 
580         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMy", "11/10/2007 \\u2013 11/20/2007",
581 
582         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
583 
584         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "My", "11/2007",
585 
586         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdM", "Sat, 11/10 \\u2013 Tue, 11/20",
587 
588         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "d", "10 \\u2013 20",
589 
590         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "Ed", "10 Sat \\u2013 20 Tue",
591 
592         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "y", "2007",
593 
594         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "M", "11",
595 
596         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMM", "Nov",
597 
598         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMM", "November",
599 
600         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
601         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "Hm", "11/10/2007, 10:10 \\u2013 11/20/2007, 10:10",
602         "en", "2007 11 10 20:10:10", "2007 11 20 20:10:10", "Hm", "11/10/2007, 20:10 \\u2013 11/20/2007, 20:10",
603 
604         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmv", "11/10/2007, 10:10 AM PT \\u2013 11/20/2007, 10:10 AM PT",
605 
606         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmz", "11/10/2007, 10:10 AM PST \\u2013 11/20/2007, 10:10 AM PST",
607 
608         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "h", "11/10/2007, 10 AM \\u2013 11/20/2007, 10 AM",
609 
610         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hv", "11/10/2007, 10 AM PT \\u2013 11/20/2007, 10 AM PT",
611 
612         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hz", "11/10/2007, 10 AM PST \\u2013 11/20/2007, 10 AM PST",
613 
614         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEddMMyyyy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
615 
616         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EddMMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
617 
618         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
619 
620         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hhmmzz", "11/10/2007, 10:10 AM PST \\u2013 11/20/2007, 10:10 AM PST",
621 
622         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hms", "11/10/2007, 10:10:10 AM \\u2013 11/20/2007, 10:10:10 AM",
623         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "Hms", "11/10/2007, 10:10:10 \\u2013 11/20/2007, 10:10:10",
624         "en", "2007 11 10 20:10:10", "2007 11 20 20:10:10", "Hms", "11/10/2007, 20:10:10 \\u2013 11/20/2007, 20:10:10",
625 
626         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMMMy", "N 10 \\u2013 20, 2007",
627 
628         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEEdM", "S, 11/10 \\u2013 T, 11/20",
629 
630         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMMy", "Wednesday, January 10, 2007",
631 
632         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMMy", "January 10, 2007",
633 
634         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMM", "January 10",
635 
636         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMMy", "January 2007",
637 
638         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMM", "Wednesday, January 10",
639 
640         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EdMMMy", "Wed, Jan 10, 2007",
641 
642         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMy", "Jan 10, 2007",
643 
644         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMM", "Jan 10",
645 
646         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMy", "Jan 2007",
647 
648         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EdMMM", "Wed, Jan 10",
649 
650 
651         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMy", "1/10/2007",
652 
653         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dM", "1/10",
654 
655         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "My", "1/2007",
656 
657         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EdM", "Wed, 1/10",
658 
659         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "d", "10",
660 
661         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "Ed", "10 Wed",
662 
663         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "y", "2007",
664 
665         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "M", "1",
666 
667         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMM", "Jan",
668 
669         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMM", "January",
670 
671         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hm", "10:00 AM \\u2013 2:10 PM",
672         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "Hm", "10:00 \\u2013 14:10",
673 
674         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hmv", "10:00 AM \\u2013 2:10 PM PT",
675 
676         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hmz", "10:00 AM \\u2013 2:10 PM PST",
677 
678         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "h", "10 AM \\u2013 2 PM",
679         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "H", "10 \\u2013 14",
680 
681 
682         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hz", "10 AM \\u2013 2 PM PST",
683 
684         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEddMMyyyy", "Wed, 01/10/2007",
685 
686         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EddMMy", "Wed, 01/10/2007",
687 
688         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hhmm", "10:00 AM \\u2013 2:10 PM",
689         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "HHmm", "10:00 \\u2013 14:10",
690 
691         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hhmmzz", "10:00 AM \\u2013 2:10 PM PST",
692 
693         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hms", "10:00:10 AM \\u2013 2:10:10 PM",
694         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "Hms", "10:00:10 \\u2013 14:10:10",
695 
696         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMMMMy", "J 10, 2007",
697 
698         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEEdM", "W, 1/10",
699         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMMMy", "January 10, 2007",
700 
701         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMMM", "January 10",
702 
703         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "MMMMy", "January 2007",
704 
705         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EEEEdMMMM", "Wednesday, January 10",
706 
707         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdMMMy", "Wed, Jan 10, 2007",
708 
709         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMMy", "Jan 10, 2007",
710 
711         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMM", "Jan 10",
712 
713 
714         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdMMM", "Wed, Jan 10",
715 
716         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdMy", "Wed, 1/10/2007",
717 
718         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMy", "1/10/2007",
719 
720 
721         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "My", "1/2007",
722 
723         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EdM", "Wed, 1/10",
724 
725         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "d", "10",
726 
727 
728         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "y", "2007",
729 
730         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "M", "1",
731 
732 
733 
734         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hm", "10:00 \\u2013 10:20 AM",
735         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "Hm", "10:00 \\u2013 10:20",
736 
737 
738         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmz", "10:00 \\u2013 10:20 AM PST",
739 
740 
741         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hv", "10 AM PT",
742 
743 
744 
745         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EddMMy", "Wed, 01/10/2007",
746 
747         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hhmm", "10:00 \\u2013 10:20 AM",
748         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "HHmm", "10:00 \\u2013 10:20",
749 
750         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hhmmzz", "10:00 \\u2013 10:20 AM PST",
751 
752 
753         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "dMMMMMy", "J 10, 2007",
754 
755 
756         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEEEdMMMMy", "Wednesday, January 10, 2007",
757 
758         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dMMMMy", "January 10, 2007",
759 
760 
761         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "MMMMy", "January 2007",
762 
763         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEEEdMMMM", "Wednesday, January 10",
764 
765 
766         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dMMMy", "Jan 10, 2007",
767 
768         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dMMM", "Jan 10",
769 
770 
771         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EdMMM", "Wed, Jan 10",
772 
773         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EdMy", "Wed, 1/10/2007",
774 
775         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dMy", "1/10/2007",
776 
777 
778         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "My", "1/2007",
779 
780         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EdM", "Wed, 1/10",
781 
782         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "d", "10",
783 
784 
785         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "y", "2007",
786 
787         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "M", "1",
788 
789 
790         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "MMMM", "January",
791 
792         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hm", "10:10 AM",
793         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "Hm", "10:10",
794 
795 
796         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hmz", "10:10 AM PST",
797 
798         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "h", "10 AM",
799 
800         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hv", "10 AM PT",
801 
802 
803         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEddMMyyyy", "Wed, 01/10/2007",
804 
805 
806         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hhmm", "10:10 AM",
807         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "HHmm", "10:10",
808 
809         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hhmmzz", "10:10 AM PST",
810 
811 
812         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "dMMMMMy", "J 10, 2007",
813 
814         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEEEEdM", "W, 1/10",
815 
816         "zh", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e09\\u81f32008\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e94",
817 
818 
819         "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u81f311\\u670810\\u65e5",
820 
821 
822         "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMMy", "2007\\u5e7410\\u6708\\u81f311\\u6708",
823 
824 
825         "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hmv", "2007/10/10 \\u6D1B\\u6749\\u77F6\\u65F6\\u95F4 \\u4E0A\\u534810:10 \\u2013 2007/11/10 \\u6D1B\\u6749\\u77F6\\u65F6\\u95F4 \\u4E0A\\u534810:10",
826 
827         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMMy", "2007\\u5e7411\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
828 
829 
830         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMM", "11\\u670810\\u65e5\\u81f320\\u65e5",
831 
832         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMMy", "2007\\u5E7411\\u6708", // (fixed expected result per ticket:6626:)
833 
834         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMM", "11\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
835 
836 
837         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMy", "2007/11/10\\u5468\\u516d\\u81f32007/11/20\\u5468\\u4e8c",
838 
839 
840         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
841 
842         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "My", "2007\\u5E7411\\u6708",
843 
844         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdM", "11/10\\u5468\\u516d\\u81f311/20\\u5468\\u4e8c",
845 
846 
847         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "y", "2007\\u5E74", // (fixed expected result per ticket:6626:)
848 
849         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "M", "11\\u6708",
850 
851         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMM", "11\\u6708", // (fixed expected result per ticket:6626: and others)
852 
853 
854         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmz", "2007/11/10 GMT-8 \\u4e0a\\u534810:10 \\u2013 2007/11/20 GMT-8 \\u4e0a\\u534810:10",
855 
856         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "h", "2007/11/10 \\u4e0a\\u534810\\u65f6 \\u2013 2007/11/20 \\u4e0a\\u534810\\u65f6",
857 
858         "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMMy", "2007\\u5e741\\u670810\\u65e5\\u661f\\u671f\\u4e09", // (fixed expected result per ticket:6626:)
859 
860         "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hm", "\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
861 
862 
863         "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hmz", "GMT-8\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
864 
865         "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "h", "\\u4e0a\\u534810\\u65F6\\u81f3\\u4e0b\\u53482\\u65f6",
866 
867         "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "hv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810\\u65F6\\u81F3\\u4E0B\\u53482\\u65F6",
868 
869         "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hm", "\\u4e0a\\u534810:00\\u81f310:20",
870 
871         "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810:00\\u81F310:20",
872 
873         "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hz", "GMT-8\\u4e0a\\u534810\\u65f6",
874 
875         "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hm", "\\u4e0a\\u534810:10",
876 
877         "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "h", "\\u4e0a\\u534810\\u65f6",
878 
879         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. 2007 \\u2013 Freitag, 10. Okt. 2008",
880 
881 
882         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMMM", "10. Okt. 2007 \\u2013 10. Okt. 2008",
883 
884         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "MMMy", "Okt. 2007 \\u2013 Okt. 2008",
885 
886 
887         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdMy", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
888 
889         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "dMy", "10.10.2007 \\u2013 10.10.2008",
890 
891 
892         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "My", "10.2007 \\u2013 10.2008",
893 
894         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "EdM", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
895 
896 
897         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "y", "2007\\u20132008",
898 
899         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "M", "10.2007 \\u2013 10.2008",
900 
901 
902         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "hm", "10.10.2007, 10:10 vorm. \\u2013 10.10.2008, 10:10 vorm.",
903         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "Hm", "10.10.2007, 10:10 \\u2013 10.10.2008, 10:10",
904 
905         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov. 2007",
906 
907 
908         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dMMM", "10. Okt. \\u2013 10. Nov.",
909 
910         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMMy", "Okt.\\u2013Nov. 2007",
911 
912         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "EEEEdMMM", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov.",
913 
914 
915         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "dM", "10.10. \\u2013 10.11.",
916 
917         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "My", "10.2007 \\u2013 11.2007",
918 
919 
920         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "d", "10.10. \\u2013 10.11.",
921 
922         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "y", "2007",
923 
924 
925         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "MMM", "Okt.\\u2013Nov.",
926 
927 
928         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "hms", "10.10.2007, 10:10:10 vorm. \\u2013 10.11.2007, 10:10:10 vorm.",
929         "de", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "Hms", "10.10.2007, 10:10:10 \\u2013 10.11.2007, 10:10:10",
930 
931         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMMy", "Samstag, 10. \\u2013 Dienstag, 20. Nov. 2007",
932 
933         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dMMMy", "10.\\u201320. Nov. 2007",
934 
935 
936         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "MMMy", "Nov. 2007",
937 
938         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EEEEdMMM", "Samstag, 10. \\u2013 Dienstag, 20. Nov.",
939 
940         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "EdMy", "Sa., 10.11.2007 \\u2013 Di., 20.11.2007",
941 
942 
943         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "dM", "10.11. \\u2013 20.11.",
944 
945         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "My", "11.2007",
946 
947 
948         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "d", "10.\\u201320.",
949 
950         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "y", "2007",
951 
952 
953         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "hmv", "10.11.2007, 10:10 vorm. Los Angeles Zeit \\u2013 20.11.2007, 10:10 vorm. Los Angeles Zeit",
954 
955         "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
956 
957 
958         "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "dMMM", "10. Jan.",
959 
960         "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "MMMy", "Jan. 2007",
961 
962         "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
963 
964 
965         "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "h", "10 vorm. \\u2013 2 nachm.",
966         "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "H", "10\\u201314 Uhr",
967 
968         "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
969 
970 
971         "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmv", "10:00\\u201310:20 vorm. Los Angeles Zeit",
972 
973         "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hmz", "10:00\\u201310:20 vorm. GMT-8",
974 
975         "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "h", "10 vorm.",
976         "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "H", "10 Uhr",
977 
978 
979         "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "hz", "10 vorm. GMT-8",
980 
981         "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
982 
983 
984         "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hmv", "10:10 vorm. Los Angeles Zeit",
985 
986         "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hmz", "10:10 vorm. GMT-8",
987 
988 
989         "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hv", "10 vorm. Los Angeles Zeit",
990 
991         "de", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "hz", "10 vorm. GMT-8",
992 
993         // Thai (default calendar buddhist)
994 
995         // BEGIN ANDROID-changed.  Default calendar in Android is Gregorian for th locale.
996         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "EEEEdMMMy", "\\u0E27\\u0E31\\u0E19\\u0E1E\\u0E38\\u0E18\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. 2550 \\u2013 \\u0E27\\u0E31\\u0E19\\u0E28\\u0E38\\u0E01\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. 2551",
997 
998 
999         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. 2550 \\u2013 10 \\u0E15.\\u0E04. 2551",
1000 
1001         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "MMMy", "\\u0E15.\\u0E04. 2550 \\u2013 \\u0E15.\\u0E04. 2551",
1002 
1003 
1004         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "EdMy", "\\u0E1E. 10/10/2550 \\u2013 \\u0E28. 10/10/2551",
1005 
1006         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "dMy", "10/10/2550 \\u2013 10/10/2551",
1007 
1008 
1009         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "My", "10/2550 \\u2013 10/2551",
1010 
1011         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "EdM", "\\u0E1E. 10/10/2550 \\u2013 \\u0E28. 10/10/2551",
1012 
1013 
1014         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "y", "2550\\u20132551",
1015 
1016         // "th", "2550 10 10 10:10:10", "2551 10 10 10:10:10", "M", "10/2550 \\u2013 10/2551",
1017 
1018 
1019         // "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "EEEEdMMMy", "\\u0E27\\u0E31\\u0E19\\u0E1E\\u0E38\\u0E18\\u0E17\\u0E35\\u0E48 10 \\u0E15.\\u0E04. \\u2013 \\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48 10 \\u0E1E.\\u0E22. 2550",
1020 
1021 
1022         "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. \\u2013 10 \\u0E1E.\\u0E22.",
1023 
1024         // "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "MMMy", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22. 2550",
1025 
1026        "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "dM", "10/10 \\u2013 10/11",
1027 
1028         // "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "My", "10/2550 \\u2013 11/2550",
1029 
1030 
1031         "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "d", "10/10 \\u2013 10/11",
1032 
1033         // "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "y", "\\u0E1E.\\u0E28. 2550",
1034 
1035 
1036         "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "MMM", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22.",
1037 
1038         // END ANDROID-changed
1039     };
1040     expect(DATA, ARRAY_SIZE(DATA));
1041 }
1042 
1043 
expect(const char ** data,int32_t data_length)1044 void DateIntervalFormatTest::expect(const char** data, int32_t data_length) {
1045     int32_t i = 0;
1046     UErrorCode ec = U_ZERO_ERROR;
1047     UnicodeString str, str2;
1048     const char* pattern = data[0];
1049     i++;
1050 
1051 #ifdef DTIFMTTS_DEBUG
1052     char result[1000];
1053     char mesg[1000];
1054     sprintf(mesg, "locale: %s\n", locName);
1055     PRINTMESG(mesg);
1056 #endif
1057 
1058     while (i<data_length) {
1059         const char* locName = data[i++];
1060         Locale loc(locName);
1061         SimpleDateFormat ref(pattern, loc, ec);
1062         if (U_FAILURE(ec)) {
1063             dataerrln("contruct SimpleDateFormat in expect failed: %s", u_errorName(ec));
1064             return;
1065         }
1066         // 'f'
1067         const char* datestr = data[i++];
1068         const char* datestr_2 = data[i++];
1069 #ifdef DTIFMTTS_DEBUG
1070         sprintf(mesg, "original date: %s - %s\n", datestr, datestr_2);
1071         PRINTMESG(mesg)
1072 #endif
1073         UDate date = ref.parse(ctou(datestr), ec);
1074         if (!assertSuccess("parse 1st data in expect", ec)) return;
1075         UDate date_2 = ref.parse(ctou(datestr_2), ec);
1076         if (!assertSuccess("parse 2nd data in expect", ec)) return;
1077         DateInterval dtitv(date, date_2);
1078 
1079         const UnicodeString& oneSkeleton = data[i++];
1080 
1081         DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(oneSkeleton, loc, ec);
1082         if (!assertSuccess("createInstance(skeleton) in expect", ec)) return;
1083         FieldPosition pos=0;
1084         dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1085         if (!assertSuccess("format in expect", ec)) return;
1086         assertEquals((UnicodeString)"\"" + locName + "\\" + oneSkeleton + "\\" + datestr + "\\" + datestr_2 + "\"", ctou(data[i++]), str);
1087 
1088 
1089 
1090 #ifdef DTIFMTTS_DEBUG
1091         str.extract(0,  str.length(), result, "UTF-8");
1092         sprintf(mesg, "interval date: %s\n", result);
1093         std::cout << "//";
1094         PRINTMESG(mesg)
1095         std::cout << "\"" << locName << "\", "
1096                  << "\"" << datestr << "\", "
1097                  << "\"" << datestr_2 << "\", ";
1098         printUnicodeString(oneSkeleton);
1099         printUnicodeString(str);
1100         std::cout << "\n\n";
1101 #endif
1102         delete dtitvfmt;
1103     }
1104 }
1105 
1106 
1107 /*
1108  * Test format using user defined DateIntervalInfo
1109  */
testFormatUserDII()1110 void DateIntervalFormatTest::testFormatUserDII() {
1111     // first item is date pattern
1112     const char* DATA[] = {
1113         "yyyy MM dd HH:mm:ss",
1114         "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "Oct 10, 2007 --- Oct 10, 2008",
1115 
1116         "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 Oct 10 - Nov 2007",
1117 
1118         "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "Nov 10, 2007 --- Nov 20, 2007",
1119 
1120         "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "Jan 10, 2007",
1121 
1122         "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "Jan 10, 2007",
1123 
1124         "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "Jan 10, 2007",
1125 
1126         "zh", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "2007\\u5e7410\\u670810\\u65e5 --- 2008\\u5e7410\\u670810\\u65e5",
1127 
1128         "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 10\\u6708 10 - 11\\u6708 2007",
1129 
1130         "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "2007\\u5e7411\\u670810\\u65e5 --- 2007\\u5e7411\\u670820\\u65e5",
1131 
1132         "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1133 
1134         "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1135 
1136         "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1137 
1138         "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "10. Okt. 2007 --- 10. Okt. 2008",
1139 
1140 
1141         "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "10. Nov. 2007 --- 20. Nov. 2007",
1142 
1143         "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "10. Jan. 2007",
1144 
1145         "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "10. Jan. 2007",
1146 
1147 
1148         "es", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "10 oct. 2007 --- 10 oct. 2008",
1149 
1150         "es", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 oct. 10 - nov. 2007",
1151 
1152         "es", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "10 nov. 2007 --- 20 nov. 2007",
1153 
1154         "es", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "10 ene. 2007",
1155 
1156         "es", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "10 ene. 2007",
1157 
1158         "es", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "10 ene. 2007",
1159     };
1160     expectUserDII(DATA, ARRAY_SIZE(DATA));
1161 }
1162 
1163 
testSetIntervalPatternNoSideEffect()1164 void DateIntervalFormatTest::testSetIntervalPatternNoSideEffect() {
1165     UErrorCode ec = U_ZERO_ERROR;
1166     LocalPointer<DateIntervalInfo> dtitvinf(new DateIntervalInfo(ec), ec);
1167     if (U_FAILURE(ec)) {
1168         errln("Failure encountered: %s", u_errorName(ec));
1169         return;
1170     }
1171     UnicodeString expected;
1172     dtitvinf->getIntervalPattern(ctou("yMd"), UCAL_DATE, expected, ec);
1173     dtitvinf->setIntervalPattern(ctou("yMd"), UCAL_DATE, ctou("M/d/y \\u2013 d"), ec);
1174     if (U_FAILURE(ec)) {
1175         errln("Failure encountered: %s", u_errorName(ec));
1176         return;
1177     }
1178     dtitvinf.adoptInsteadAndCheckErrorCode(new DateIntervalInfo(ec), ec);
1179     if (U_FAILURE(ec)) {
1180         errln("Failure encountered: %s", u_errorName(ec));
1181         return;
1182     }
1183     UnicodeString actual;
1184     dtitvinf->getIntervalPattern(ctou("yMd"), UCAL_DATE, actual, ec);
1185     if (U_FAILURE(ec)) {
1186         errln("Failure encountered: %s", u_errorName(ec));
1187         return;
1188     }
1189     if (expected != actual) {
1190         errln("DateIntervalInfo.setIntervalPattern should have no side effects.");
1191     }
1192 }
1193 
testYearFormats()1194 void DateIntervalFormatTest::testYearFormats() {
1195     const Locale &enLocale = Locale::getEnglish();
1196     UErrorCode status = U_ZERO_ERROR;
1197     LocalPointer<Calendar> fromTime(Calendar::createInstance(enLocale, status));
1198     LocalPointer<Calendar> toTime(Calendar::createInstance(enLocale, status));
1199     if (U_FAILURE(status)) {
1200         errln("Failure encountered: %s", u_errorName(status));
1201         return;
1202     }
1203     // April 26, 113. Three digit year so that we can test 2 digit years;
1204     // 4 digit years with padded 0's and full years.
1205     fromTime->set(113, 3, 26);
1206     // April 28, 113.
1207     toTime->set(113, 3, 28);
1208     {
1209         LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yyyyMd", enLocale, status));
1210         if (U_FAILURE(status)) {
1211             dataerrln("Failure encountered: %s", u_errorName(status));
1212             return;
1213         }
1214         UnicodeString actual;
1215         UnicodeString expected(ctou("4/26/0113 \\u2013 4/28/0113"));
1216         FieldPosition pos = 0;
1217         dif->format(*fromTime, *toTime, actual, pos, status);
1218         if (U_FAILURE(status)) {
1219             errln("Failure encountered: %s", u_errorName(status));
1220             return;
1221         }
1222         if (actual != expected) {
1223             errln("Expected " + expected + ", got: " + actual);
1224         }
1225     }
1226     {
1227         LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yyMd", enLocale, status));
1228         if (U_FAILURE(status)) {
1229             errln("Failure encountered: %s", u_errorName(status));
1230             return;
1231         }
1232         UnicodeString actual;
1233         UnicodeString expected(ctou("4/26/13 \\u2013 4/28/13"));
1234         FieldPosition pos = 0;
1235         dif->format(*fromTime, *toTime, actual, pos, status);
1236         if (U_FAILURE(status)) {
1237             errln("Failure encountered: %s", u_errorName(status));
1238             return;
1239         }
1240         if (actual != expected) {
1241             errln("Expected " + expected + ", got: " + actual);
1242         }
1243     }
1244     {
1245         LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yMd", enLocale, status));
1246         if (U_FAILURE(status)) {
1247             errln("Failure encountered: %s", u_errorName(status));
1248             return;
1249         }
1250         UnicodeString actual;
1251         UnicodeString expected(ctou("4/26/113 \\u2013 4/28/113"));
1252         FieldPosition pos = 0;
1253         dif->format(*fromTime, *toTime, actual, pos, status);
1254         if (U_FAILURE(status)) {
1255             errln("Failure encountered: %s", u_errorName(status));
1256             return;
1257         }
1258         if (actual != expected) {
1259             errln("Expected " + expected + ", got: " + actual);
1260         }
1261     }
1262 }
1263 
expectUserDII(const char ** data,int32_t data_length)1264 void DateIntervalFormatTest::expectUserDII(const char** data,
1265                                            int32_t data_length) {
1266     int32_t i = 0;
1267     UnicodeString str;
1268     UErrorCode ec = U_ZERO_ERROR;
1269     const char* pattern = data[0];
1270     i++;
1271 
1272     while ( i < data_length ) {
1273         const char* locName = data[i++];
1274         Locale loc(locName);
1275         SimpleDateFormat ref(pattern, loc, ec);
1276         if (U_FAILURE(ec)) {
1277             dataerrln("contruct SimpleDateFormat in expectUserDII failed: %s", u_errorName(ec));
1278             return;
1279         }
1280         const char* datestr = data[i++];
1281         const char* datestr_2 = data[i++];
1282         UDate date = ref.parse(ctou(datestr), ec);
1283         if (!assertSuccess("parse in expectUserDII", ec)) return;
1284         UDate date_2 = ref.parse(ctou(datestr_2), ec);
1285         if (!assertSuccess("parse in expectUserDII", ec)) return;
1286         DateInterval dtitv(date, date_2);
1287 
1288         ec = U_ZERO_ERROR;
1289         // test user created DateIntervalInfo
1290         DateIntervalInfo* dtitvinf = new DateIntervalInfo(ec);
1291         dtitvinf->setFallbackIntervalPattern("{0} --- {1}", ec);
1292         dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_MONTH, "yyyy MMM d - MMM y",ec);
1293         if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1294         dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_HOUR_OF_DAY, "yyyy MMM d HH:mm - HH:mm", ec);
1295         if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1296         DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_ABBR_MONTH_DAY, loc, *dtitvinf, ec);
1297         delete dtitvinf;
1298         if (!assertSuccess("createInstance(skeleton,dtitvinf) in expectUserDII", ec)) return;
1299         FieldPosition pos=0;
1300         dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1301         if (!assertSuccess("format in expectUserDII", ec)) return;
1302         assertEquals((UnicodeString)"\"" + locName + "\\" + datestr + "\\" + datestr_2 + "\"", ctou(data[i++]), str);
1303 #ifdef DTIFMTTS_DEBUG
1304         char result[1000];
1305         char mesg[1000];
1306         PRINTMESG("interval format using user defined DateIntervalInfo\n");
1307         str.extract(0,  str.length(), result, "UTF-8");
1308         sprintf(mesg, "interval date: %s\n", result);
1309         PRINTMESG(mesg);
1310 #endif
1311         delete dtitvfmt;
1312     }
1313 }
1314 
1315 
testStress()1316 void DateIntervalFormatTest::testStress() {
1317     if(quick){
1318     	logln("Quick mode: Skipping test");
1319     	return;
1320     }
1321 	const char* DATA[] = {
1322         "yyyy MM dd HH:mm:ss",
1323         "2007 10 10 10:10:10", "2008 10 10 10:10:10",
1324         "2007 10 10 10:10:10", "2007 11 10 10:10:10",
1325         "2007 11 10 10:10:10", "2007 11 20 10:10:10",
1326         "2007 01 10 10:00:10", "2007 01 10 14:10:10",
1327         "2007 01 10 10:00:10", "2007 01 10 10:20:10",
1328         "2007 01 10 10:10:10", "2007 01 10 10:10:20",
1329     };
1330 
1331     const char* testLocale[][3] = {
1332         //{"th", "", ""},
1333         {"en", "", ""},
1334         {"zh", "", ""},
1335         {"de", "", ""},
1336         {"ar", "", ""},
1337         {"en", "GB",  ""},
1338         {"fr", "", ""},
1339         {"it", "", ""},
1340         {"nl", "", ""},
1341         {"zh", "TW",  ""},
1342         {"ja", "", ""},
1343         {"pt", "BR", ""},
1344         {"ru", "", ""},
1345         {"pl", "", ""},
1346         {"tr", "", ""},
1347         {"es", "", ""},
1348         {"ko", "", ""},
1349         {"sv", "", ""},
1350         {"fi", "", ""},
1351         {"da", "", ""},
1352         {"pt", "PT", ""},
1353         {"ro", "", ""},
1354         {"hu", "", ""},
1355         {"he", "", ""},
1356         {"in", "", ""},
1357         {"cs", "", ""},
1358         {"el", "", ""},
1359         {"no", "", ""},
1360         {"vi", "", ""},
1361         {"bg", "", ""},
1362         {"hr", "", ""},
1363         {"lt", "", ""},
1364         {"sk", "", ""},
1365         {"sl", "", ""},
1366         {"sr", "", ""},
1367         {"ca", "", ""},
1368         {"lv", "", ""},
1369         {"uk", "", ""},
1370         {"hi", "", ""},
1371     };
1372 
1373     uint32_t localeIndex;
1374     for ( localeIndex = 0; localeIndex < ARRAY_SIZE(testLocale); ++localeIndex ) {
1375         char locName[32];
1376         uprv_strcpy(locName, testLocale[localeIndex][0]);
1377         uprv_strcat(locName, testLocale[localeIndex][1]);
1378         stress(DATA, ARRAY_SIZE(DATA), Locale(testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2]), locName);
1379     }
1380 }
1381 
1382 
stress(const char ** data,int32_t data_length,const Locale & loc,const char * locName)1383 void DateIntervalFormatTest::stress(const char** data, int32_t data_length,
1384                                     const Locale& loc, const char* locName) {
1385     UnicodeString skeleton[] = {
1386         "EEEEdMMMMy",
1387         "dMMMMy",
1388         "dMMMM",
1389         "MMMMy",
1390         "EEEEdMMMM",
1391         "EdMMMy",
1392         "dMMMy",
1393         "dMMM",
1394         "MMMy",
1395         "EdMMM",
1396         "EdMy",
1397         "dMy",
1398         "dM",
1399         "My",
1400         "EdM",
1401         "d",
1402         "Ed",
1403         "y",
1404         "M",
1405         "MMM",
1406         "MMMM",
1407         "hm",
1408         "hmv",
1409         "hmz",
1410         "h",
1411         "hv",
1412         "hz",
1413         "EEddMMyyyy", // following could be normalized
1414         "EddMMy",
1415         "hhmm",
1416         "hhmmzz",
1417         "hms",  // following could not be normalized
1418         "dMMMMMy",
1419         "EEEEEdM",
1420     };
1421 
1422     int32_t i = 0;
1423     UErrorCode ec = U_ZERO_ERROR;
1424     UnicodeString str, str2;
1425     SimpleDateFormat ref(data[i++], loc, ec);
1426     if (!assertSuccess("construct SimpleDateFormat", ec)) return;
1427 
1428 #ifdef DTIFMTTS_DEBUG
1429     char result[1000];
1430     char mesg[1000];
1431     sprintf(mesg, "locale: %s\n", locName);
1432     PRINTMESG(mesg);
1433 #endif
1434 
1435     while (i<data_length) {
1436 
1437         // 'f'
1438         const char* datestr = data[i++];
1439         const char* datestr_2 = data[i++];
1440 #ifdef DTIFMTTS_DEBUG
1441         sprintf(mesg, "original date: %s - %s\n", datestr, datestr_2);
1442         PRINTMESG(mesg)
1443 #endif
1444         UDate date = ref.parse(ctou(datestr), ec);
1445         if (!assertSuccess("parse", ec)) return;
1446         UDate date_2 = ref.parse(ctou(datestr_2), ec);
1447         if (!assertSuccess("parse", ec)) return;
1448         DateInterval dtitv(date, date_2);
1449 
1450         for ( uint32_t skeletonIndex = 0;
1451               skeletonIndex < ARRAY_SIZE(skeleton);
1452               ++skeletonIndex ) {
1453             const UnicodeString& oneSkeleton = skeleton[skeletonIndex];
1454             DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(oneSkeleton, loc, ec);
1455             if (!assertSuccess("createInstance(skeleton)", ec)) return;
1456             /*
1457             // reset the calendar to be Gregorian calendar for "th"
1458             if ( uprv_strcmp(locName, "th") == 0 ) {
1459                 GregorianCalendar* gregCal = new GregorianCalendar(loc, ec);
1460                 if (!assertSuccess("GregorianCalendar()", ec)) return;
1461                 const DateFormat* dformat = dtitvfmt->getDateFormat();
1462                 DateFormat* newOne = (DateFormat*)dformat->clone();
1463                 newOne->adoptCalendar(gregCal);
1464                 //dtitvfmt->adoptDateFormat(newOne, ec);
1465                 dtitvfmt->setDateFormat(*newOne, ec);
1466                 delete newOne;
1467                 if (!assertSuccess("adoptDateFormat()", ec)) return;
1468             }
1469             */
1470             FieldPosition pos=0;
1471             dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1472             if (!assertSuccess("format", ec)) return;
1473 #ifdef DTIFMTTS_DEBUG
1474             oneSkeleton.extract(0,  oneSkeleton.length(), result, "UTF-8");
1475             sprintf(mesg, "interval by skeleton: %s\n", result);
1476             PRINTMESG(mesg)
1477             str.extract(0,  str.length(), result, "UTF-8");
1478             sprintf(mesg, "interval date: %s\n", result);
1479             PRINTMESG(mesg)
1480 #endif
1481             delete dtitvfmt;
1482         }
1483 
1484         // test user created DateIntervalInfo
1485         ec = U_ZERO_ERROR;
1486         DateIntervalInfo* dtitvinf = new DateIntervalInfo(ec);
1487         dtitvinf->setFallbackIntervalPattern("{0} --- {1}", ec);
1488         dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_MONTH, "yyyy MMM d - MMM y",ec);
1489         if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1490         dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_HOUR_OF_DAY, "yyyy MMM d HH:mm - HH:mm", ec);
1491         if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1492         DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_ABBR_MONTH_DAY, loc, *dtitvinf, ec);
1493         delete dtitvinf;
1494         if (!assertSuccess("createInstance(skeleton,dtitvinf)", ec)) return;
1495         FieldPosition pos=0;
1496         dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1497         if ( uprv_strcmp(locName, "th") ) {
1498             if (!assertSuccess("format", ec)) return;
1499 #ifdef DTIFMTTS_DEBUG
1500             PRINTMESG("interval format using user defined DateIntervalInfo\n");
1501             str.extract(0,  str.length(), result, "UTF-8");
1502             sprintf(mesg, "interval date: %s\n", result);
1503             PRINTMESG(mesg)
1504 #endif
1505         } else {
1506             // for "th", the default calendar is Budhist,
1507             // not Gregorian.
1508             assertTrue("Default calendar for \"th\" is Budhist", ec == U_ILLEGAL_ARGUMENT_ERROR);
1509             ec = U_ZERO_ERROR;
1510         }
1511         delete dtitvfmt;
1512     }
1513 }
1514 
testTicket11583_2()1515 void DateIntervalFormatTest::testTicket11583_2() {
1516     UErrorCode status = U_ZERO_ERROR;
1517     LocalPointer<DateIntervalFormat> fmt(
1518             DateIntervalFormat::createInstance("yMMM", "es-US", status));
1519     if (!assertSuccess("Error create format object", status)) {
1520         return;
1521     }
1522     DateInterval interval((UDate) 1232364615000.0, (UDate) 1328787015000.0);
1523     UnicodeString appendTo;
1524     FieldPosition fpos(FieldPosition::DONT_CARE);
1525     UnicodeString expected("ene. de 2009 \\u2013 feb. de 2012");
1526     assertEquals(
1527             "",
1528             expected.unescape(),
1529             fmt->format(&interval, appendTo, fpos, status));
1530     if (!assertSuccess("Error formatting", status)) {
1531         return;
1532     }
1533 }
1534 
1535 #endif /* #if !UCONFIG_NO_FORMATTING */
1536