1// Copyright (C) 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
45void 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 */
65void 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 */
405void 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
1050void 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 */
1097void 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
1151void 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
1181void 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
1251void 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
1303void 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
1370void 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
1502void 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
1523void 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
1538static const DateIntervalFormat *gIntervalFormatter = NULL;      // The Formatter to be used concurrently by test threads.
1539static const DateInterval *gInterval = NULL;                     // The date interval to be formatted concurrently.
1540static const UnicodeString *gExpectedResult = NULL;
1541
1542void 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
1560void 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 ==.
1599void DateIntervalFormatTest::testTicket12065() {
1600    UErrorCode status = U_ZERO_ERROR;
1601    LocalPointer<DateIntervalFormat> formatter(DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getEnglish(), status), status);
1602    LocalPointer<DateIntervalFormat> clone(dynamic_cast<DateIntervalFormat *>(formatter->clone()));
1603    if (*formatter != *clone) {
1604        errln("%s:%d DateIntervalFormat and clone are not equal.", __FILE__, __LINE__);
1605        return;
1606    }
1607    DateInterval interval((UDate) 1232364615000.0, (UDate) 1328787015000.0);
1608    UnicodeString appendTo;
1609    FieldPosition fpos(FieldPosition::DONT_CARE);
1610    formatter->format(&interval, appendTo, fpos, status);
1611    if (*formatter != *clone) {
1612        errln("%s:%d DateIntervalFormat and clone are not equal after formatting.", __FILE__, __LINE__);
1613        return;
1614    }
1615    if (U_FAILURE(status)) {
1616        errln("%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1617    }
1618}
1619
1620
1621#endif /* #if !UCONFIG_NO_FORMATTING */
1622