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