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 "japancal.h"
29 #include "unicode/gregocal.h"
30 #include "unicode/dtintrv.h"
31 #include "unicode/dtitvinf.h"
32 #include "unicode/dtitvfmt.h"
33 #include "unicode/localpointer.h"
34 #include "unicode/timezone.h"
35
36
37
38 #ifdef DTIFMTTS_DEBUG
39 //#define PRINTMESG(msg) { std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; }
40 #define PRINTMESG(msg) { std::cout << msg; }
41 #endif
42
43 #include <stdio.h>
44
45
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)46 void DateIntervalFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) {
47 if (exec) logln("TestSuite DateIntervalFormat");
48 switch (index) {
49 TESTCASE(0, testAPI);
50 TESTCASE(1, testFormat);
51 TESTCASE(2, testFormatUserDII);
52 TESTCASE(3, testSetIntervalPatternNoSideEffect);
53 TESTCASE(4, testYearFormats);
54 TESTCASE(5, testStress);
55 TESTCASE(6, testTicket11583_2);
56 TESTCASE(7, testTicket11985);
57 TESTCASE(8, testTicket11669);
58 TESTCASE(9, testTicket12065);
59 TESTCASE(10, testFormattedDateInterval);
60 TESTCASE(11, testCreateInstanceForAllLocales);
61 TESTCASE(12, testTicket20707);
62 TESTCASE(13, testFormatMillisecond);
63 default: name = ""; break;
64 }
65 }
66
67 /**
68 * Test various generic API methods of DateIntervalFormat for API coverage.
69 */
testAPI()70 void DateIntervalFormatTest::testAPI() {
71
72 /* ====== Test create interval instance with default locale and skeleton
73 */
74 UErrorCode status = U_ZERO_ERROR;
75 logln("Testing DateIntervalFormat create instance with default locale and skeleton");
76
77 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, status);
78 if(U_FAILURE(status)) {
79 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + default locale) - exitting");
80 return;
81 } else {
82 delete dtitvfmt;
83 }
84
85
86 /* ====== Test create interval instance with given locale and skeleton
87 */
88 status = U_ZERO_ERROR;
89 logln("Testing DateIntervalFormat create instance with given locale and skeleton");
90
91 dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getJapanese(), status);
92 if(U_FAILURE(status)) {
93 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + locale) - exitting");
94 return;
95 } else {
96 delete dtitvfmt;
97 }
98
99
100 /* ====== Test create interval instance with dateIntervalInfo and skeleton
101 */
102 status = U_ZERO_ERROR;
103 logln("Testing DateIntervalFormat create instance with dateIntervalInfo and skeleton");
104
105 DateIntervalInfo* dtitvinf = new DateIntervalInfo(Locale::getSimplifiedChinese(), status);
106
107 dtitvfmt = DateIntervalFormat::createInstance("EEEdMMMyhms", *dtitvinf, status);
108 delete dtitvinf;
109
110 if(U_FAILURE(status)) {
111 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + DateIntervalInfo + default locale) - exitting");
112 return;
113 } else {
114 delete dtitvfmt;
115 }
116
117
118 /* ====== Test create interval instance with dateIntervalInfo and skeleton
119 */
120 status = U_ZERO_ERROR;
121 logln("Testing DateIntervalFormat create instance with dateIntervalInfo and skeleton");
122
123 dtitvinf = new DateIntervalInfo(Locale::getSimplifiedChinese(), status);
124
125 dtitvfmt = DateIntervalFormat::createInstance("EEEdMMMyhms", Locale::getSimplifiedChinese(), *dtitvinf, status);
126 delete dtitvinf;
127 if(U_FAILURE(status)) {
128 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + DateIntervalInfo + locale) - exitting");
129 return;
130 }
131 // not deleted, test clone
132
133
134 // ====== Test clone()
135 status = U_ZERO_ERROR;
136 logln("Testing DateIntervalFormat clone");
137
138 DateIntervalFormat* another = dtitvfmt->clone();
139 if ( (*another) != (*dtitvfmt) ) {
140 dataerrln("%s:%d ERROR: clone failed", __FILE__, __LINE__);
141 }
142
143
144 // ====== Test getDateIntervalInfo, setDateIntervalInfo, adoptDateIntervalInfo
145 status = U_ZERO_ERROR;
146 logln("Testing DateIntervalFormat getDateIntervalInfo");
147 const DateIntervalInfo* inf = another->getDateIntervalInfo();
148 dtitvfmt->setDateIntervalInfo(*inf, status);
149 const DateIntervalInfo* anotherInf = dtitvfmt->getDateIntervalInfo();
150 if ( (*inf) != (*anotherInf) || U_FAILURE(status) ) {
151 dataerrln("ERROR: getDateIntervalInfo/setDateIntervalInfo failed");
152 }
153
154 {
155 // We make sure that setDateIntervalInfo does not corrupt the cache. See ticket 9919.
156 status = U_ZERO_ERROR;
157 logln("Testing DateIntervalFormat setDateIntervalInfo");
158 const Locale &enLocale = Locale::getEnglish();
159 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yMd", enLocale, status));
160 if (U_FAILURE(status)) {
161 errln("Failure encountered: %s", u_errorName(status));
162 return;
163 }
164 UnicodeString expected;
165 LocalPointer<Calendar> fromTime(Calendar::createInstance(enLocale, status));
166 LocalPointer<Calendar> toTime(Calendar::createInstance(enLocale, status));
167 if (U_FAILURE(status)) {
168 errln("Failure encountered: %s", u_errorName(status));
169 return;
170 }
171 FieldPosition pos(FieldPosition::DONT_CARE);
172 fromTime->set(2013, 3, 26);
173 toTime->set(2013, 3, 28);
174 dif->format(*fromTime, *toTime, expected, pos, status);
175 if (U_FAILURE(status)) {
176 errln("Failure encountered: %s", u_errorName(status));
177 return;
178 }
179 LocalPointer<DateIntervalInfo> dii(new DateIntervalInfo(Locale::getEnglish(), status), status);
180 if (U_FAILURE(status)) {
181 errln("Failure encountered: %s", u_errorName(status));
182 return;
183 }
184 dii->setIntervalPattern(ctou("yMd"), UCAL_DATE, ctou("M/d/y \\u2013 d"), status);
185 dif->setDateIntervalInfo(*dii, status);
186 if (U_FAILURE(status)) {
187 errln("Failure encountered: %s", u_errorName(status));
188 return;
189 }
190 dif.adoptInstead(DateIntervalFormat::createInstance("yMd", enLocale, status));
191 if (U_FAILURE(status)) {
192 errln("Failure encountered: %s", u_errorName(status));
193 return;
194 }
195 UnicodeString actual;
196 pos = 0;
197 dif->format(*fromTime, *toTime, actual, pos, status);
198 if (U_FAILURE(status)) {
199 errln("Failure encountered: %s", u_errorName(status));
200 return;
201 }
202 if (expected != actual) {
203 errln("DateIntervalFormat.setIntervalInfo should have no side effects.");
204 }
205 }
206
207 /*
208 status = U_ZERO_ERROR;
209 DateIntervalInfo* nonConstInf = inf->clone();
210 dtitvfmt->adoptDateIntervalInfo(nonConstInf, status);
211 anotherInf = dtitvfmt->getDateIntervalInfo();
212 if ( (*inf) != (*anotherInf) || U_FAILURE(status) ) {
213 dataerrln("ERROR: adoptDateIntervalInfo failed");
214 }
215 */
216
217 // ====== Test getDateFormat, setDateFormat, adoptDateFormat
218
219 status = U_ZERO_ERROR;
220 logln("Testing DateIntervalFormat getDateFormat");
221 /*
222 const DateFormat* fmt = another->getDateFormat();
223 dtitvfmt->setDateFormat(*fmt, status);
224 const DateFormat* anotherFmt = dtitvfmt->getDateFormat();
225 if ( (*fmt) != (*anotherFmt) || U_FAILURE(status) ) {
226 dataerrln("ERROR: getDateFormat/setDateFormat failed");
227 }
228
229 status = U_ZERO_ERROR;
230 DateFormat* nonConstFmt = fmt->clone();
231 dtitvfmt->adoptDateFormat(nonConstFmt, status);
232 anotherFmt = dtitvfmt->getDateFormat();
233 if ( (*fmt) != (*anotherFmt) || U_FAILURE(status) ) {
234 dataerrln("ERROR: adoptDateFormat failed");
235 }
236 delete fmt;
237 */
238
239
240 // ======= Test getStaticClassID()
241
242 logln("Testing getStaticClassID()");
243
244
245 if(dtitvfmt->getDynamicClassID() != DateIntervalFormat::getStaticClassID()) {
246 errln("ERROR: getDynamicClassID() didn't return the expected value");
247 }
248
249 delete another;
250
251 // ====== test constructor/copy constructor and assignment
252 /* they are protected, no test
253 logln("Testing DateIntervalFormat constructor and assigment operator");
254 status = U_ZERO_ERROR;
255
256 DateFormat* constFmt = dtitvfmt->getDateFormat()->clone();
257 inf = dtitvfmt->getDateIntervalInfo()->clone();
258
259
260 DateIntervalFormat* dtifmt = new DateIntervalFormat(fmt, inf, status);
261 if(U_FAILURE(status)) {
262 dataerrln("ERROR: Could not create DateIntervalFormat (default) - exitting");
263 return;
264 }
265
266 DateIntervalFormat* dtifmt2 = new(dtifmt);
267 if ( (*dtifmt) != (*dtifmt2) ) {
268 dataerrln("ERROR: Could not create DateIntervalFormat (default) - exitting");
269 return;
270 }
271
272 DateIntervalFormat dtifmt3 = (*dtifmt);
273 if ( (*dtifmt) != dtifmt3 ) {
274 dataerrln("ERROR: Could not create DateIntervalFormat (default) - exitting");
275 return;
276 }
277
278 delete dtifmt2;
279 delete dtifmt3;
280 delete dtifmt;
281 */
282
283
284 //===== test format and parse ==================
285 Formattable formattable;
286 formattable.setInt64(10);
287 UnicodeString res;
288 FieldPosition pos(FieldPosition::DONT_CARE);
289 status = U_ZERO_ERROR;
290 dtitvfmt->format(formattable, res, pos, status);
291 if ( status != U_ILLEGAL_ARGUMENT_ERROR ) {
292 dataerrln("ERROR: format non-date-interval object should set U_ILLEGAL_ARGUMENT_ERROR - exitting");
293 return;
294 }
295
296 DateInterval* dtitv = new DateInterval(3600*24*365, 3600*24*366);
297 formattable.adoptObject(dtitv);
298 res.remove();
299 pos = 0;
300 status = U_ZERO_ERROR;
301 dtitvfmt->format(formattable, res, pos, status);
302 if ( U_FAILURE(status) ) {
303 dataerrln("ERROR: format date interval failed - exitting");
304 return;
305 }
306
307 const DateFormat* dfmt = dtitvfmt->getDateFormat();
308 Calendar* fromCal = dfmt->getCalendar()->clone();
309 Calendar* toCal = dfmt->getCalendar()->clone();
310 res.remove();
311 pos = 0;
312 status = U_ZERO_ERROR;
313 dtitvfmt->format(*fromCal, *toCal, res, pos, status);
314 if ( U_FAILURE(status) ) {
315 dataerrln("ERROR: format date interval failed - exitting");
316 return;
317 }
318 delete fromCal;
319 delete toCal;
320
321
322 Formattable fmttable;
323 status = U_ZERO_ERROR;
324 // TODO: why do I need cast?
325 ((Format*)dtitvfmt)->parseObject(res, fmttable, status);
326 if ( status != U_INVALID_FORMAT_ERROR ) {
327 dataerrln("ERROR: parse should set U_INVALID_FORMAT_ERROR - exitting");
328 return;
329 }
330
331 delete dtitvfmt;
332
333 //====== test setting time zone
334 logln("Testing DateIntervalFormat set & format with different time zones, get time zone");
335 status = U_ZERO_ERROR;
336 dtitvfmt = DateIntervalFormat::createInstance("MMMdHHmm", Locale::getEnglish(), status);
337 if ( U_SUCCESS(status) ) {
338 UDate date1 = 1299090600000.0; // 2011-Mar-02 1030 in US/Pacific, 2011-Mar-03 0330 in Asia/Tokyo
339 UDate date2 = 1299115800000.0; // 2011-Mar-02 1730 in US/Pacific, 2011-Mar-03 1030 in Asia/Tokyo
340
341 DateInterval * dtitv12 = new DateInterval(date1, date2);
342 TimeZone * tzCalif = TimeZone::createTimeZone("US/Pacific");
343 TimeZone * tzTokyo = TimeZone::createTimeZone("Asia/Tokyo");
344 UnicodeString fmtCalif = UnicodeString(ctou("Mar 2, 10:30 \\u2013 17:30"));
345 UnicodeString fmtTokyo = UnicodeString(ctou("Mar 3, 03:30 \\u2013 10:30"));
346
347 dtitvfmt->adoptTimeZone(tzCalif);
348 res.remove();
349 pos = 0;
350 status = U_ZERO_ERROR;
351 dtitvfmt->format(dtitv12, res, pos, status);
352 if ( U_SUCCESS(status) ) {
353 if ( res.compare(fmtCalif) != 0 ) {
354 errln("ERROR: DateIntervalFormat::format for tzCalif, expect " + fmtCalif + ", get " + res);
355 }
356 } else {
357 errln("ERROR: DateIntervalFormat::format for tzCalif, status %s", u_errorName(status));
358 }
359
360 dtitvfmt->setTimeZone(*tzTokyo);
361 res.remove();
362 pos = 0;
363 status = U_ZERO_ERROR;
364 dtitvfmt->format(dtitv12, res, pos, status);
365 if ( U_SUCCESS(status) ) {
366 if ( res.compare(fmtTokyo) != 0 ) {
367 errln("ERROR: DateIntervalFormat::format for fmtTokyo, expect " + fmtTokyo + ", get " + res);
368 }
369 } else {
370 errln("ERROR: DateIntervalFormat::format for tzTokyo, status %s", u_errorName(status));
371 }
372
373 if ( dtitvfmt->getTimeZone() != *tzTokyo ) {
374 errln("ERROR: DateIntervalFormat::getTimeZone returns mismatch.");
375 }
376
377 delete tzTokyo; // tzCalif was owned by dtitvfmt which should have deleted it
378 delete dtitv12;
379 delete dtitvfmt;
380 } else {
381 errln("ERROR: DateIntervalFormat::createInstance(\"MdHH\", Locale::getEnglish(), ...), status %s", u_errorName(status));
382 }
383 //====== test format in testFormat()
384
385 //====== test DateInterval class (better coverage)
386 DateInterval dtitv1(3600*24*365, 3600*24*366);
387 DateInterval dtitv2(dtitv1);
388
389 if (!(dtitv1 == dtitv2)) {
390 errln("ERROR: Copy constructor failed for DateInterval.");
391 }
392
393 DateInterval dtitv3(3600*365, 3600*366);
394 dtitv3 = dtitv1;
395 if (!(dtitv3 == dtitv1)) {
396 errln("ERROR: Equal operator failed for DateInterval.");
397 }
398
399 DateInterval *dtitv4 = dtitv1.clone();
400 if (*dtitv4 != dtitv1) {
401 errln("ERROR: Equal operator failed for DateInterval.");
402 }
403 delete dtitv4;
404 }
405
406
407 /**
408 * Test format
409 */
testFormat()410 void DateIntervalFormatTest::testFormat() {
411 // first item is date pattern
412 // followed by a group of locale/from_data/to_data/skeleton/interval_data
413 // Note that from_data/to_data are specified using era names from root, for the calendar specified by locale.
414 const char* DATA[] = {
415 "GGGGG y MM dd HH:mm:ss", // pattern for from_data/to_data
416 // test root
417 "root", "CE 2007 11 10 10:10:10", "CE 2007 12 10 10:10:10", "yM", "2007-11 \\u2013 2007-12",
418
419 // test 'H' and 'h', using availableFormat in fallback
420 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 15:10:10", "Hms", "10:10:10 \\u2013 15:10:10",
421 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 15:10:10", "hms", "10:10:10 AM \\u2013 3:10:10 PM",
422
423 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMM", "October 2007 \\u2013 October 2008",
424 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMM", "Oct 2007 \\u2013 Oct 2008",
425 // test skeleton with both date and time
426 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 AM \\u2013 Nov 20, 2007, 10:10 AM",
427
428 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "dMMMyhm", "Nov 10, 2007, 10:10 \\u2013 11:10 AM",
429
430 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "hms", "10:10:10 AM \\u2013 11:10:10 AM",
431 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "Hms", "10:10:10 \\u2013 11:10:10",
432 "en", "CE 2007 11 10 20:10:10", "CE 2007 11 10 21:10:10", "Hms", "20:10:10 \\u2013 21:10:10",
433
434 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
435
436 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMMy", "October 10, 2007 \\u2013 October 10, 2008",
437
438 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMM", "October 10, 2007 \\u2013 October 10, 2008",
439
440 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMMy", "October 2007 \\u2013 October 2008",
441
442 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10, 2007 \\u2013 Friday, October 10, 2008",
443
444 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMMMy", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
445
446 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMy", "Oct 10, 2007 \\u2013 Oct 10, 2008",
447
448 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMM", "Oct 10, 2007 \\u2013 Oct 10, 2008",
449
450 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMy", "Oct 2007 \\u2013 Oct 2008",
451
452 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMMM", "Wed, Oct 10, 2007 \\u2013 Fri, Oct 10, 2008",
453
454 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
455
456 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMy", "10/10/2007 \\u2013 10/10/2008",
457
458 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dM", "10/10/2007 \\u2013 10/10/2008",
459
460 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "My", "10/2007 \\u2013 10/2008",
461
462 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdM", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
463
464 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "d", "10/10/2007 \\u2013 10/10/2008",
465
466 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "Ed", "10 Wed \\u2013 10 Fri",
467
468 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "y", "2007 \\u2013 2008",
469
470 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "M", "10/2007 \\u2013 10/2008",
471
472
473
474 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
475 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "Hm", "10/10/2007, 10:10 \\u2013 10/10/2008, 10:10",
476 "en", "CE 2007 10 10 20:10:10", "CE 2008 10 10 20:10:10", "Hm", "10/10/2007, 20:10 \\u2013 10/10/2008, 20:10",
477
478 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 10/10/2008, 10:10 AM PT",
479
480 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
481
482 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 10/10/2008, 10 AM",
483
484 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 10/10/2008, 10 AM PT",
485
486 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 10/10/2008, 10 AM PDT",
487
488 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
489
490 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Fri, 10/10/2008",
491
492 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10 AM \\u2013 10/10/2008, 10:10 AM",
493
494 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 10/10/2008, 10:10 AM PDT",
495
496 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 10/10/2008, 10:10:10 AM",
497
498 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMMMy", "O 10, 2007 \\u2013 O 10, 2008",
499
500 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEEdM", "W, 10/10/2007 \\u2013 F, 10/10/2008",
501
502 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10 \\u2013 Saturday, November 10, 2007",
503
504 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMy", "October 10 \\u2013 November 10, 2007",
505
506 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMM", "October 10 \\u2013 November 10",
507
508 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMMy", "October \\u2013 November 2007",
509
510 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10 \\u2013 Saturday, November 10",
511
512 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMMMy", "Wed, Oct 10 \\u2013 Sat, Nov 10, 2007",
513
514 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMy", "Oct 10 \\u2013 Nov 10, 2007",
515
516 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMM", "Oct 10 \\u2013 Nov 10",
517
518 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMy", "Oct \\u2013 Nov 2007",
519
520 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMMM", "Wed, Oct 10 \\u2013 Sat, Nov 10",
521
522 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
523
524 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMy", "10/10/2007 \\u2013 11/10/2007",
525
526
527 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "My", "10/2007 \\u2013 11/2007",
528
529 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdM", "Wed, 10/10 \\u2013 Sat, 11/10",
530
531 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "d", "10/10 \\u2013 11/10",
532
533 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "Ed", "10 Wed \\u2013 10 Sat",
534
535 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "y", "2007",
536
537 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "M", "10 \\u2013 11",
538
539 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMM", "Oct \\u2013 Nov",
540
541 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMM", "October \\u2013 November",
542
543 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hm", "10/10/2007, 10:10 AM \\u2013 11/10/2007, 10:10 AM",
544 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "Hm", "10/10/2007, 10:10 \\u2013 11/10/2007, 10:10",
545 "en", "CE 2007 10 10 20:10:10", "CE 2007 11 10 20:10:10", "Hm", "10/10/2007, 20:10 \\u2013 11/10/2007, 20:10",
546
547 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmv", "10/10/2007, 10:10 AM PT \\u2013 11/10/2007, 10:10 AM PT",
548
549 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
550
551 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "h", "10/10/2007, 10 AM \\u2013 11/10/2007, 10 AM",
552
553 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hv", "10/10/2007, 10 AM PT \\u2013 11/10/2007, 10 AM PT",
554
555 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hz", "10/10/2007, 10 AM PDT \\u2013 11/10/2007, 10 AM PST",
556
557 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
558
559 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EddMMy", "Wed, 10/10/2007 \\u2013 Sat, 11/10/2007",
560
561
562 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hhmmzz", "10/10/2007, 10:10 AM PDT \\u2013 11/10/2007, 10:10 AM PST",
563
564 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hms", "10/10/2007, 10:10:10 AM \\u2013 11/10/2007, 10:10:10 AM",
565
566 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMMy", "O 10 \\u2013 N 10, 2007",
567
568 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEEdM", "W, 10/10 \\u2013 S, 11/10",
569
570 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMMy", "Saturday, November 10 \\u2013 Tuesday, November 20, 2007",
571
572 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMMy", "November 10 \\u2013 20, 2007",
573
574 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMM", "November 10 \\u2013 20",
575
576
577 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMM", "Saturday, November 10 \\u2013 Tuesday, November 20",
578
579 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMMMy", "Sat, Nov 10 \\u2013 Tue, Nov 20, 2007",
580
581 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMy", "Nov 10 \\u2013 20, 2007",
582
583 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMM", "Nov 10 \\u2013 20",
584
585 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMy", "Nov 2007",
586
587 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMMM", "Sat, Nov 10 \\u2013 Tue, Nov 20",
588
589 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
590
591 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMy", "11/10/2007 \\u2013 11/20/2007",
592
593 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
594
595 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "11/2007",
596
597 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdM", "Sat, 11/10 \\u2013 Tue, 11/20",
598
599 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "d", "10 \\u2013 20",
600
601 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "Ed", "10 Sat \\u2013 20 Tue",
602
603 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007",
604
605 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "M", "11",
606
607 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMM", "Nov",
608
609 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMM", "November",
610
611 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
612 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "Hm", "11/10/2007, 10:10 \\u2013 11/20/2007, 10:10",
613 "en", "CE 2007 11 10 20:10:10", "CE 2007 11 20 20:10:10", "Hm", "11/10/2007, 20:10 \\u2013 11/20/2007, 20:10",
614
615 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmv", "11/10/2007, 10:10 AM PT \\u2013 11/20/2007, 10:10 AM PT",
616
617 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmz", "11/10/2007, 10:10 AM PST \\u2013 11/20/2007, 10:10 AM PST",
618
619 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "h", "11/10/2007, 10 AM \\u2013 11/20/2007, 10 AM",
620
621 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hv", "11/10/2007, 10 AM PT \\u2013 11/20/2007, 10 AM PT",
622
623 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hz", "11/10/2007, 10 AM PST \\u2013 11/20/2007, 10 AM PST",
624
625 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEddMMyyyy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
626
627 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EddMMy", "Sat, 11/10/2007 \\u2013 Tue, 11/20/2007",
628
629 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10 AM \\u2013 11/20/2007, 10:10 AM",
630
631 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmmzz", "11/10/2007, 10:10 AM PST \\u2013 11/20/2007, 10:10 AM PST",
632
633 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hms", "11/10/2007, 10:10:10 AM \\u2013 11/20/2007, 10:10:10 AM",
634 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "Hms", "11/10/2007, 10:10:10 \\u2013 11/20/2007, 10:10:10",
635 "en", "CE 2007 11 10 20:10:10", "CE 2007 11 20 20:10:10", "Hms", "11/10/2007, 20:10:10 \\u2013 11/20/2007, 20:10:10",
636
637 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMMMy", "N 10 \\u2013 20, 2007",
638
639 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEEdM", "S, 11/10 \\u2013 T, 11/20",
640
641 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMMy", "Wednesday, January 10, 2007",
642
643 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMMy", "January 10, 2007",
644
645 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMM", "January 10",
646
647 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMMy", "January 2007",
648
649 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMM", "Wednesday, January 10",
650
651 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdMMMy", "Wed, Jan 10, 2007",
652
653 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMy", "Jan 10, 2007",
654
655 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMM", "Jan 10",
656
657 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMy", "Jan 2007",
658
659 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdMMM", "Wed, Jan 10",
660
661
662 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMy", "1/10/2007",
663
664 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dM", "1/10",
665
666 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "My", "1/2007",
667
668 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdM", "Wed, 1/10",
669
670 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "d", "10",
671
672 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "Ed", "10 Wed",
673
674 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "y", "2007",
675
676 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "M", "1",
677
678 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMM", "Jan",
679
680 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMM", "January",
681
682 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hm", "10:00 AM \\u2013 2:10 PM",
683 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "Hm", "10:00 \\u2013 14:10",
684
685 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmv", "10:00 AM \\u2013 2:10 PM PT",
686
687 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmz", "10:00 AM \\u2013 2:10 PM PST",
688
689 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "10 AM \\u2013 2 PM",
690 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "H", "10 \\u2013 14",
691
692
693 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hz", "10 AM \\u2013 2 PM PST",
694
695 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEddMMyyyy", "Wed, 01/10/2007",
696
697 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EddMMy", "Wed, 01/10/2007",
698
699 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hhmm", "10:00 AM \\u2013 2:10 PM",
700 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "HHmm", "10:00 \\u2013 14:10",
701
702 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hhmmzz", "10:00 AM \\u2013 2:10 PM PST",
703
704 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hms", "10:00:10 AM \\u2013 2:10:10 PM",
705 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "Hms", "10:00:10 \\u2013 14:10:10",
706
707 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMMMy", "J 10, 2007",
708
709 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEEdM", "W, 1/10",
710 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMMy", "January 10, 2007",
711
712 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMM", "January 10",
713
714 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "MMMMy", "January 2007",
715
716 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EEEEdMMMM", "Wednesday, January 10",
717
718 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMMMy", "Wed, Jan 10, 2007",
719
720 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMy", "Jan 10, 2007",
721
722 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMM", "Jan 10",
723
724
725 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMMM", "Wed, Jan 10",
726
727 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMy", "Wed, 1/10/2007",
728
729 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMy", "1/10/2007",
730
731
732 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "My", "1/2007",
733
734 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdM", "Wed, 1/10",
735
736 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "d", "10",
737
738
739 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "y", "2007",
740
741 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "M", "1",
742
743
744
745 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hm", "10:00 \\u2013 10:20 AM",
746 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "Hm", "10:00 \\u2013 10:20",
747
748
749 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmz", "10:00 \\u2013 10:20 AM PST",
750
751
752 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hv", "10 AM PT",
753
754
755
756 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EddMMy", "Wed, 01/10/2007",
757
758 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hhmm", "10:00 \\u2013 10:20 AM",
759 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "HHmm", "10:00 \\u2013 10:20",
760
761 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hhmmzz", "10:00 \\u2013 10:20 AM PST",
762
763
764 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMMMy", "J 10, 2007",
765
766
767 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMMy", "Wednesday, January 10, 2007",
768
769 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMMMy", "January 10, 2007",
770
771
772 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "MMMMy", "January 2007",
773
774 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMM", "Wednesday, January 10",
775
776
777 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMMy", "Jan 10, 2007",
778
779 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMM", "Jan 10",
780
781
782 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdMMM", "Wed, Jan 10",
783
784 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdMy", "Wed, 1/10/2007",
785
786 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMy", "1/10/2007",
787
788
789 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "My", "1/2007",
790
791 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdM", "Wed, 1/10",
792
793 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "d", "10",
794
795
796 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "y", "2007",
797
798 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "M", "1",
799
800
801 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "MMMM", "January",
802
803 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hm", "10:10 AM",
804 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "Hm", "10:10",
805
806
807 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmz", "10:10 AM PST",
808
809 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "h", "10 AM",
810
811 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hv", "10 AM PT",
812
813
814 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEddMMyyyy", "Wed, 01/10/2007",
815
816
817 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmm", "10:10 AM",
818 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "HHmm", "10:10",
819
820 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmmzz", "10:10 AM PST",
821
822
823 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMMMMy", "J 10, 2007",
824
825 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEEdM", "W, 1/10",
826
827 "zh", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e09\\u81f32008\\u5e7410\\u670810\\u65e5\\u661f\\u671f\\u4e94",
828
829
830 "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u81f311\\u670810\\u65e5",
831
832
833 "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMMy", "2007\\u5e7410\\u6708\\u81f311\\u6708",
834
835
836 "zh", "CE 2007 10 10 10:10:10", "CE 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",
837
838 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMMy", "2007\\u5e7411\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
839
840
841 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMM", "11\\u670810\\u65e5\\u81f320\\u65e5",
842
843 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMMy", "2007\\u5E7411\\u6708", // (fixed expected result per ticket:6626:)
844
845 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMM", "11\\u670810\\u65e5\\u661f\\u671f\\u516d\\u81f320\\u65e5\\u661f\\u671f\\u4e8c",
846
847
848 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "2007/11/10\\u5468\\u516d\\u81f32007/11/20\\u5468\\u4e8c",
849
850
851 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
852
853 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "2007\\u5E7411\\u6708",
854
855 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdM", "11/10\\u5468\\u516d\\u81f311/20\\u5468\\u4e8c",
856
857
858 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007\\u5E74", // (fixed expected result per ticket:6626:)
859
860 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "M", "11\\u6708",
861
862 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMM", "11\\u6708", // (fixed expected result per ticket:6626: and others)
863
864
865 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmz", "2007/11/10 GMT-8 \\u4e0a\\u534810:10 \\u2013 2007/11/20 GMT-8 \\u4e0a\\u534810:10",
866
867 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "h", "2007/11/10 \\u4e0a\\u534810\\u65f6 \\u2013 2007/11/20 \\u4e0a\\u534810\\u65f6",
868
869 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMMy", "2007\\u5e741\\u670810\\u65e5\\u661f\\u671f\\u4e09", // (fixed expected result per ticket:6626:)
870
871 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hm", "\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
872
873
874 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmz", "GMT-8\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
875
876 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "\\u4e0a\\u534810\\u65F6\\u81f3\\u4e0b\\u53482\\u65f6",
877
878 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810\\u65F6\\u81F3\\u4E0B\\u53482\\u65F6",
879
880 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hm", "\\u4e0a\\u534810:00\\u81f310:20",
881
882 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmv", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4\\u4E0A\\u534810:00\\u81F310:20",
883
884 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hz", "GMT-8\\u4e0a\\u534810\\u65f6",
885
886 "zh", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hm", "\\u4e0a\\u534810:10",
887
888 "zh", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "h", "\\u4e0a\\u534810\\u65f6",
889
890 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. 2007 \\u2013 Freitag, 10. Okt. 2008",
891
892
893 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMM", "10. Okt. 2007 \\u2013 10. Okt. 2008",
894
895 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMy", "Okt. 2007 \\u2013 Okt. 2008",
896
897
898 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMy", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
899
900 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMy", "10.10.2007 \\u2013 10.10.2008",
901
902
903 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "My", "10.2007 \\u2013 10.2008",
904
905 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdM", "Mi., 10.10.2007 \\u2013 Fr., 10.10.2008",
906
907
908 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "y", "2007\\u20132008",
909
910 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "M", "10.2007 \\u2013 10.2008",
911
912
913 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hm", "10.10.2007, 10:10 AM \\u2013 10.10.2008, 10:10 AM",
914 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "Hm", "10.10.2007, 10:10 \\u2013 10.10.2008, 10:10",
915
916 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov. 2007",
917
918
919 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMM", "10. Okt. \\u2013 10. Nov.",
920
921 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMy", "Okt.\\u2013Nov. 2007",
922
923 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMM", "Mittwoch, 10. Okt. \\u2013 Samstag, 10. Nov.",
924
925
926 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dM", "10.10. \\u2013 10.11.",
927
928 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "My", "10.2007 \\u2013 11.2007",
929
930
931 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "d", "10.10. \\u2013 10.11.",
932
933 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "y", "2007",
934
935
936 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMM", "Okt.\\u2013Nov.",
937
938
939 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hms", "10.10.2007, 10:10:10 AM \\u2013 10.11.2007, 10:10:10 AM",
940 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "Hms", "10.10.2007, 10:10:10 \\u2013 10.11.2007, 10:10:10",
941
942 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMy", "Samstag, 10. \\u2013 Dienstag, 20. Nov. 2007",
943
944 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMy", "10.\\u201320. Nov. 2007",
945
946
947 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMy", "Nov. 2007",
948
949 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMM", "Samstag, 10. \\u2013 Dienstag, 20. Nov.",
950
951 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "Sa., 10. \\u2013 Di., 20.11.2007",
952
953
954 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "10.\\u201320.11.",
955
956 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "11.2007",
957
958
959 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "d", "10.\\u201320.",
960
961 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007",
962
963
964 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmv", "10.11.2007, 10:10 AM Los Angeles Zeit \\u2013 20.11.2007, 10:10 AM Los Angeles Zeit",
965
966 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
967
968
969 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMM", "10. Jan.",
970
971 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMy", "Jan. 2007",
972
973 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
974
975 /* Following is an important test, because the 'h' in 'Uhr' is interpreted as a pattern
976 if not escaped properly. */
977 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "10 Uhr AM \\u2013 2 Uhr PM",
978 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "H", "10\\u201314 Uhr",
979
980 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
981
982
983 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmv", "10:00\\u201310:20 AM Los Angeles Zeit",
984
985 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmz", "10:00\\u201310:20 AM GMT-8",
986
987 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "h", "10 Uhr AM",
988 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "H", "10 Uhr",
989
990
991 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hz", "10 Uhr AM GMT-8",
992
993 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
994
995
996 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmv", "10:10 AM Los Angeles Zeit",
997
998 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmz", "10:10 AM GMT-8",
999
1000
1001 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hv", "10 Uhr AM Los Angeles Zeit",
1002
1003 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hz", "10 Uhr AM GMT-8",
1004
1005 // Thai (default calendar buddhist)
1006
1007 "th", "BE 2550 10 10 10:10:10", "BE 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",
1008
1009
1010 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. 2550 \\u2013 10 \\u0E15.\\u0E04. 2551",
1011
1012 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "MMMy", "\\u0E15.\\u0E04. 2550 \\u2013 \\u0E15.\\u0E04. 2551",
1013
1014
1015 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "EdMy", "\\u0E1E. 10/10/2550 \\u2013 \\u0E28. 10/10/2551",
1016
1017 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "dMy", "10/10/2550 \\u2013 10/10/2551",
1018
1019
1020 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "My", "10/2550 \\u2013 10/2551",
1021
1022 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "EdM", "\\u0E1E. 10/10/2550 \\u2013 \\u0E28. 10/10/2551",
1023
1024
1025 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "y", "2550\\u20132551",
1026
1027 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "M", "10/2550 \\u2013 10/2551",
1028
1029
1030 "th", "BE 2550 10 10 10:10:10", "BE 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",
1031
1032
1033 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. \\u2013 10 \\u0E1E.\\u0E22.",
1034
1035 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "MMMy", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22. 2550",
1036
1037 "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "dM", "10/10 \\u2013 10/11",
1038
1039 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "My", "10/2550 \\u2013 11/2550",
1040
1041
1042 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "d", "10/10 \\u2013 10/11",
1043
1044 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "y", "\\u0E1E.\\u0E28. 2550",
1045
1046
1047 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "MMM", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22.",
1048
1049 // Tests for Japanese calendar with eras, including new era in 2019 (Heisei 31 through April 30, then new era)
1050
1051 "en-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GyMMMd", "Mar 15 \\u2013 Apr 15, 31 Heisei",
1052
1053 "en-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GGGGGyMd", "3/15/31 \\u2013 4/15/31 H",
1054
1055 "en-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GyMMMd", "Jan 5, 64 Sh\\u014Dwa \\u2013 Jan 15, 1 Heisei",
1056
1057 "en-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GGGGGyMd", "1/5/64 S \\u2013 1/15/1 H",
1058
1059 "en-u-ca-japanese", "H 31 04 15 09:00:00", JP_ERA_2019_NARROW " 1 05 15 09:00:00", "GyMMMd", "Apr 15, 31 Heisei \\u2013 May 15, 1 " JP_ERA_2019_ROOT,
1060
1061 "en-u-ca-japanese", "H 31 04 15 09:00:00", JP_ERA_2019_NARROW " 1 05 15 09:00:00", "GGGGGyMd", "4/15/31 H \\u2013 5/15/1 " JP_ERA_2019_NARROW,
1062
1063
1064 "ja-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GyMMMd", "\\u5E73\\u621031\\u5E743\\u670815\\u65E5\\uFF5E4\\u670815\\u65E5",
1065
1066 "ja-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GGGGGyMd", "H31/03/15\\uFF5E31/04/15",
1067
1068 "ja-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GyMMMd", "\\u662D\\u548C64\\u5E741\\u67085\\u65E5\\uFF5E\\u5E73\\u6210\\u5143\\u5E741\\u670815\\u65E5",
1069
1070 "ja-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GGGGGyMd", "S64/01/05\\uFF5EH1/01/15",
1071
1072 "ja-u-ca-japanese", "H 31 04 15 09:00:00", JP_ERA_2019_NARROW " 1 05 15 09:00:00", "GGGGGyMd", "H31/04/15\\uFF5E" JP_ERA_2019_NARROW "1/05/15",
1073
1074 };
1075 expect(DATA, UPRV_LENGTHOF(DATA));
1076 }
1077
1078
expect(const char ** data,int32_t data_length)1079 void DateIntervalFormatTest::expect(const char** data, int32_t data_length) {
1080 int32_t i = 0;
1081 UErrorCode ec = U_ZERO_ERROR;
1082 UnicodeString str, str2;
1083 const char* pattern = data[i++];
1084
1085 while (i<data_length) {
1086 const char* locName = data[i++];
1087 const char* datestr = data[i++];
1088 const char* datestr_2 = data[i++];
1089
1090 Locale loc(locName);
1091 LocalPointer<Calendar> defCal(Calendar::createInstance(loc, ec));
1092 if (U_FAILURE(ec)) {
1093 dataerrln("Calendar::createInstance fails for loc %s with: %s", locName, u_errorName(ec));
1094 return;
1095 }
1096 const char* calType = defCal->getType();
1097
1098 Locale refLoc("root");
1099 if (calType) {
1100 refLoc.setKeywordValue("calendar", calType, ec);
1101 }
1102 SimpleDateFormat ref(pattern, refLoc, ec);
1103 logln( "case %d, locale: %s\n", (i-1)/5, locName);
1104 if (U_FAILURE(ec)) {
1105 dataerrln("contruct SimpleDateFormat in expect failed: %s", u_errorName(ec));
1106 return;
1107 }
1108
1109 // 'f'
1110 logln("original date: %s - %s\n", datestr, datestr_2);
1111 UDate date = ref.parse(ctou(datestr), ec);
1112 if (!assertSuccess("parse 1st data in expect", ec)) return;
1113 UDate date_2 = ref.parse(ctou(datestr_2), ec);
1114 if (!assertSuccess("parse 2nd data in expect", ec)) return;
1115 DateInterval dtitv(date, date_2);
1116
1117 const UnicodeString& oneSkeleton(ctou(data[i++]));
1118
1119 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(oneSkeleton, loc, ec);
1120 if (!assertSuccess("createInstance(skeleton) in expect", ec)) return;
1121 FieldPosition pos(FieldPosition::DONT_CARE);
1122 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1123 if (!assertSuccess("format in expect", ec)) return;
1124 assertEquals((UnicodeString)"\"" + locName + "\\" + oneSkeleton + "\\" + ctou(datestr) + "\\" + ctou(datestr_2) + "\"", ctou(data[i++]), str);
1125
1126 logln("interval date:" + str + "\"" + locName + "\", "
1127 + "\"" + datestr + "\", "
1128 + "\"" + datestr_2 + "\", " + oneSkeleton);
1129 delete dtitvfmt;
1130 }
1131 }
1132
1133
1134 /*
1135 * Test format using user defined DateIntervalInfo
1136 */
testFormatUserDII()1137 void DateIntervalFormatTest::testFormatUserDII() {
1138 // first item is date pattern
1139 const char* DATA[] = {
1140 "yyyy MM dd HH:mm:ss",
1141 "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "Oct 10, 2007 --- Oct 10, 2008",
1142
1143 "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 Oct 10 - Nov 2007",
1144
1145 "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "Nov 10, 2007 --- Nov 20, 2007",
1146
1147 "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "Jan 10, 2007",
1148
1149 "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "Jan 10, 2007",
1150
1151 "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "Jan 10, 2007",
1152
1153 "zh", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "2007\\u5e7410\\u670810\\u65e5 --- 2008\\u5e7410\\u670810\\u65e5",
1154
1155 "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 10\\u6708 10 - 11\\u6708 2007",
1156
1157 "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "2007\\u5e7411\\u670810\\u65e5 --- 2007\\u5e7411\\u670820\\u65e5",
1158
1159 "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1160
1161 "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1162
1163 "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1164
1165 "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "10. Okt. 2007 --- 10. Okt. 2008",
1166
1167
1168 "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "10. Nov. 2007 --- 20. Nov. 2007",
1169
1170 "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "10. Jan. 2007",
1171
1172 "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "10. Jan. 2007",
1173
1174
1175 "es", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "10 oct. 2007 --- 10 oct. 2008",
1176
1177 "es", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 oct. 10 - nov. 2007",
1178
1179 "es", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "10 nov. 2007 --- 20 nov. 2007",
1180
1181 "es", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "10 ene. 2007",
1182
1183 "es", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "10 ene. 2007",
1184
1185 "es", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "10 ene. 2007",
1186 };
1187 expectUserDII(DATA, UPRV_LENGTHOF(DATA));
1188 }
1189
1190
testSetIntervalPatternNoSideEffect()1191 void DateIntervalFormatTest::testSetIntervalPatternNoSideEffect() {
1192 UErrorCode ec = U_ZERO_ERROR;
1193 LocalPointer<DateIntervalInfo> dtitvinf(new DateIntervalInfo(ec), ec);
1194 if (U_FAILURE(ec)) {
1195 errln("Failure encountered: %s", u_errorName(ec));
1196 return;
1197 }
1198 UnicodeString expected;
1199 dtitvinf->getIntervalPattern(ctou("yMd"), UCAL_DATE, expected, ec);
1200 dtitvinf->setIntervalPattern(ctou("yMd"), UCAL_DATE, ctou("M/d/y \\u2013 d"), ec);
1201 if (U_FAILURE(ec)) {
1202 errln("Failure encountered: %s", u_errorName(ec));
1203 return;
1204 }
1205 dtitvinf.adoptInsteadAndCheckErrorCode(new DateIntervalInfo(ec), ec);
1206 if (U_FAILURE(ec)) {
1207 errln("Failure encountered: %s", u_errorName(ec));
1208 return;
1209 }
1210 UnicodeString actual;
1211 dtitvinf->getIntervalPattern(ctou("yMd"), UCAL_DATE, actual, ec);
1212 if (U_FAILURE(ec)) {
1213 errln("Failure encountered: %s", u_errorName(ec));
1214 return;
1215 }
1216 if (expected != actual) {
1217 errln("DateIntervalInfo.setIntervalPattern should have no side effects.");
1218 }
1219 }
1220
testYearFormats()1221 void DateIntervalFormatTest::testYearFormats() {
1222 const Locale &enLocale = Locale::getEnglish();
1223 UErrorCode status = U_ZERO_ERROR;
1224 LocalPointer<Calendar> fromTime(Calendar::createInstance(enLocale, status));
1225 LocalPointer<Calendar> toTime(Calendar::createInstance(enLocale, status));
1226 if (U_FAILURE(status)) {
1227 errln("Failure encountered: %s", u_errorName(status));
1228 return;
1229 }
1230 // April 26, 113. Three digit year so that we can test 2 digit years;
1231 // 4 digit years with padded 0's and full years.
1232 fromTime->set(113, 3, 26);
1233 // April 28, 113.
1234 toTime->set(113, 3, 28);
1235 {
1236 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yyyyMd", enLocale, status));
1237 if (U_FAILURE(status)) {
1238 dataerrln("Failure encountered: %s", u_errorName(status));
1239 return;
1240 }
1241 UnicodeString actual;
1242 UnicodeString expected(ctou("4/26/0113 \\u2013 4/28/0113"));
1243 FieldPosition pos;
1244 dif->format(*fromTime, *toTime, actual, pos, status);
1245 if (U_FAILURE(status)) {
1246 errln("Failure encountered: %s", u_errorName(status));
1247 return;
1248 }
1249 if (actual != expected) {
1250 errln("Expected " + expected + ", got: " + actual);
1251 }
1252 }
1253 {
1254 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yyMd", enLocale, status));
1255 if (U_FAILURE(status)) {
1256 errln("Failure encountered: %s", u_errorName(status));
1257 return;
1258 }
1259 UnicodeString actual;
1260 UnicodeString expected(ctou("4/26/13 \\u2013 4/28/13"));
1261 FieldPosition pos(FieldPosition::DONT_CARE);
1262 dif->format(*fromTime, *toTime, actual, pos, status);
1263 if (U_FAILURE(status)) {
1264 errln("Failure encountered: %s", u_errorName(status));
1265 return;
1266 }
1267 if (actual != expected) {
1268 errln("Expected " + expected + ", got: " + actual);
1269 }
1270 }
1271 {
1272 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yMd", enLocale, status));
1273 if (U_FAILURE(status)) {
1274 errln("Failure encountered: %s", u_errorName(status));
1275 return;
1276 }
1277 UnicodeString actual;
1278 UnicodeString expected(ctou("4/26/113 \\u2013 4/28/113"));
1279 FieldPosition pos(FieldPosition::DONT_CARE);
1280 dif->format(*fromTime, *toTime, actual, pos, status);
1281 if (U_FAILURE(status)) {
1282 errln("Failure encountered: %s", u_errorName(status));
1283 return;
1284 }
1285 if (actual != expected) {
1286 errln("Expected " + expected + ", got: " + actual);
1287 }
1288 }
1289 }
1290
expectUserDII(const char ** data,int32_t data_length)1291 void DateIntervalFormatTest::expectUserDII(const char** data,
1292 int32_t data_length) {
1293 int32_t i = 0;
1294 UnicodeString str;
1295 UErrorCode ec = U_ZERO_ERROR;
1296 const char* pattern = data[0];
1297 i++;
1298
1299 while ( i < data_length ) {
1300 const char* locName = data[i++];
1301 Locale loc(locName);
1302 SimpleDateFormat ref(pattern, loc, ec);
1303 if (U_FAILURE(ec)) {
1304 dataerrln("contruct SimpleDateFormat in expectUserDII failed: %s", u_errorName(ec));
1305 return;
1306 }
1307 const char* datestr = data[i++];
1308 const char* datestr_2 = data[i++];
1309 UDate date = ref.parse(ctou(datestr), ec);
1310 if (!assertSuccess("parse in expectUserDII", ec)) return;
1311 UDate date_2 = ref.parse(ctou(datestr_2), ec);
1312 if (!assertSuccess("parse in expectUserDII", ec)) return;
1313 DateInterval dtitv(date, date_2);
1314
1315 ec = U_ZERO_ERROR;
1316 // test user created DateIntervalInfo
1317 DateIntervalInfo* dtitvinf = new DateIntervalInfo(ec);
1318 dtitvinf->setFallbackIntervalPattern("{0} --- {1}", ec);
1319 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_MONTH, "yyyy MMM d - MMM y",ec);
1320 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1321 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_HOUR_OF_DAY, "yyyy MMM d HH:mm - HH:mm", ec);
1322 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1323 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_ABBR_MONTH_DAY, loc, *dtitvinf, ec);
1324 delete dtitvinf;
1325 if (!assertSuccess("createInstance(skeleton,dtitvinf) in expectUserDII", ec)) return;
1326 FieldPosition pos(FieldPosition::DONT_CARE);
1327 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1328 if (!assertSuccess("format in expectUserDII", ec)) return;
1329 assertEquals((UnicodeString)"\"" + locName + "\\" + datestr + "\\" + datestr_2 + "\"", ctou(data[i++]), str);
1330 #ifdef DTIFMTTS_DEBUG
1331 char result[1000];
1332 char mesg[1000];
1333 PRINTMESG("interval format using user defined DateIntervalInfo\n");
1334 str.extract(0, str.length(), result, "UTF-8");
1335 sprintf(mesg, "interval date: %s\n", result);
1336 PRINTMESG(mesg);
1337 #endif
1338 delete dtitvfmt;
1339 }
1340 }
1341
1342
testStress()1343 void DateIntervalFormatTest::testStress() {
1344 if(quick){
1345 logln("Quick mode: Skipping test");
1346 return;
1347 }
1348 const char* DATA[] = {
1349 "yyyy MM dd HH:mm:ss",
1350 "2007 10 10 10:10:10", "2008 10 10 10:10:10",
1351 "2007 10 10 10:10:10", "2007 11 10 10:10:10",
1352 "2007 11 10 10:10:10", "2007 11 20 10:10:10",
1353 "2007 01 10 10:00:10", "2007 01 10 14:10:10",
1354 "2007 01 10 10:00:10", "2007 01 10 10:20:10",
1355 "2007 01 10 10:10:10", "2007 01 10 10:10:20",
1356 };
1357
1358 const char* testLocale[][3] = {
1359 //{"th", "", ""},
1360 {"en", "", ""},
1361 {"zh", "", ""},
1362 {"de", "", ""},
1363 {"ar", "", ""},
1364 {"en", "GB", ""},
1365 {"fr", "", ""},
1366 {"it", "", ""},
1367 {"nl", "", ""},
1368 {"zh", "TW", ""},
1369 {"ja", "", ""},
1370 {"pt", "BR", ""},
1371 {"ru", "", ""},
1372 {"pl", "", ""},
1373 {"tr", "", ""},
1374 {"es", "", ""},
1375 {"ko", "", ""},
1376 {"sv", "", ""},
1377 {"fi", "", ""},
1378 {"da", "", ""},
1379 {"pt", "PT", ""},
1380 {"ro", "", ""},
1381 {"hu", "", ""},
1382 {"he", "", ""},
1383 {"in", "", ""},
1384 {"cs", "", ""},
1385 {"el", "", ""},
1386 {"no", "", ""},
1387 {"vi", "", ""},
1388 {"bg", "", ""},
1389 {"hr", "", ""},
1390 {"lt", "", ""},
1391 {"sk", "", ""},
1392 {"sl", "", ""},
1393 {"sr", "", ""},
1394 {"ca", "", ""},
1395 {"lv", "", ""},
1396 {"uk", "", ""},
1397 {"hi", "", ""},
1398 };
1399
1400 uint32_t localeIndex;
1401 for ( localeIndex = 0; localeIndex < UPRV_LENGTHOF(testLocale); ++localeIndex ) {
1402 char locName[32];
1403 uprv_strcpy(locName, testLocale[localeIndex][0]);
1404 uprv_strcat(locName, testLocale[localeIndex][1]);
1405 stress(DATA, UPRV_LENGTHOF(DATA), Locale(testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2]), locName);
1406 }
1407 }
1408
1409
stress(const char ** data,int32_t data_length,const Locale & loc,const char * locName)1410 void DateIntervalFormatTest::stress(const char** data, int32_t data_length,
1411 const Locale& loc, const char* locName) {
1412 UnicodeString skeleton[] = {
1413 "EEEEdMMMMy",
1414 "dMMMMy",
1415 "dMMMM",
1416 "MMMMy",
1417 "EEEEdMMMM",
1418 "EdMMMy",
1419 "dMMMy",
1420 "dMMM",
1421 "MMMy",
1422 "EdMMM",
1423 "EdMy",
1424 "dMy",
1425 "dM",
1426 "My",
1427 "EdM",
1428 "d",
1429 "Ed",
1430 "y",
1431 "M",
1432 "MMM",
1433 "MMMM",
1434 "hm",
1435 "hmv",
1436 "hmz",
1437 "h",
1438 "hv",
1439 "hz",
1440 "EEddMMyyyy", // following could be normalized
1441 "EddMMy",
1442 "hhmm",
1443 "hhmmzz",
1444 "hms", // following could not be normalized
1445 "dMMMMMy",
1446 "EEEEEdM",
1447 };
1448
1449 int32_t i = 0;
1450 UErrorCode ec = U_ZERO_ERROR;
1451 UnicodeString str, str2;
1452 SimpleDateFormat ref(data[i++], loc, ec);
1453 if (!assertSuccess("construct SimpleDateFormat", ec)) return;
1454
1455 #ifdef DTIFMTTS_DEBUG
1456 char result[1000];
1457 char mesg[1000];
1458 sprintf(mesg, "locale: %s\n", locName);
1459 PRINTMESG(mesg);
1460 #endif
1461
1462 while (i<data_length) {
1463
1464 // 'f'
1465 const char* datestr = data[i++];
1466 const char* datestr_2 = data[i++];
1467 #ifdef DTIFMTTS_DEBUG
1468 sprintf(mesg, "original date: %s - %s\n", datestr, datestr_2);
1469 PRINTMESG(mesg)
1470 #endif
1471 UDate date = ref.parse(ctou(datestr), ec);
1472 if (!assertSuccess("parse", ec)) return;
1473 UDate date_2 = ref.parse(ctou(datestr_2), ec);
1474 if (!assertSuccess("parse", ec)) return;
1475 DateInterval dtitv(date, date_2);
1476
1477 for ( uint32_t skeletonIndex = 0;
1478 skeletonIndex < UPRV_LENGTHOF(skeleton);
1479 ++skeletonIndex ) {
1480 const UnicodeString& oneSkeleton = skeleton[skeletonIndex];
1481 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(oneSkeleton, loc, ec);
1482 if (!assertSuccess("createInstance(skeleton)", ec)) return;
1483 /*
1484 // reset the calendar to be Gregorian calendar for "th"
1485 if ( uprv_strcmp(locName, "th") == 0 ) {
1486 GregorianCalendar* gregCal = new GregorianCalendar(loc, ec);
1487 if (!assertSuccess("GregorianCalendar()", ec)) return;
1488 const DateFormat* dformat = dtitvfmt->getDateFormat();
1489 DateFormat* newOne = dformat->clone();
1490 newOne->adoptCalendar(gregCal);
1491 //dtitvfmt->adoptDateFormat(newOne, ec);
1492 dtitvfmt->setDateFormat(*newOne, ec);
1493 delete newOne;
1494 if (!assertSuccess("adoptDateFormat()", ec)) return;
1495 }
1496 */
1497 FieldPosition pos(FieldPosition::DONT_CARE);
1498 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1499 if (!assertSuccess("format", ec)) return;
1500 #ifdef DTIFMTTS_DEBUG
1501 oneSkeleton.extract(0, oneSkeleton.length(), result, "UTF-8");
1502 sprintf(mesg, "interval by skeleton: %s\n", result);
1503 PRINTMESG(mesg)
1504 str.extract(0, str.length(), result, "UTF-8");
1505 sprintf(mesg, "interval date: %s\n", result);
1506 PRINTMESG(mesg)
1507 #endif
1508 delete dtitvfmt;
1509 }
1510
1511 // test user created DateIntervalInfo
1512 ec = U_ZERO_ERROR;
1513 DateIntervalInfo* dtitvinf = new DateIntervalInfo(ec);
1514 dtitvinf->setFallbackIntervalPattern("{0} --- {1}", ec);
1515 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_MONTH, "yyyy MMM d - MMM y",ec);
1516 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1517 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_HOUR_OF_DAY, "yyyy MMM d HH:mm - HH:mm", ec);
1518 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1519 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_ABBR_MONTH_DAY, loc, *dtitvinf, ec);
1520 delete dtitvinf;
1521 if (!assertSuccess("createInstance(skeleton,dtitvinf)", ec)) return;
1522 FieldPosition pos(FieldPosition::DONT_CARE);
1523 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1524 if ( uprv_strcmp(locName, "th") ) {
1525 if (!assertSuccess("format", ec)) return;
1526 #ifdef DTIFMTTS_DEBUG
1527 PRINTMESG("interval format using user defined DateIntervalInfo\n");
1528 str.extract(0, str.length(), result, "UTF-8");
1529 sprintf(mesg, "interval date: %s\n", result);
1530 PRINTMESG(mesg)
1531 #endif
1532 } else {
1533 // for "th", the default calendar is Budhist,
1534 // not Gregorian.
1535 assertTrue("Default calendar for \"th\" is Budhist", ec == U_ILLEGAL_ARGUMENT_ERROR);
1536 ec = U_ZERO_ERROR;
1537 }
1538 delete dtitvfmt;
1539 }
1540 }
1541
testTicket11583_2()1542 void DateIntervalFormatTest::testTicket11583_2() {
1543 UErrorCode status = U_ZERO_ERROR;
1544 LocalPointer<DateIntervalFormat> fmt(
1545 DateIntervalFormat::createInstance("yMMM", "es-US", status));
1546 if (!assertSuccess("Error create format object", status)) {
1547 return;
1548 }
1549 DateInterval interval((UDate) 1232364615000.0, (UDate) 1328787015000.0);
1550 UnicodeString appendTo;
1551 FieldPosition fpos(FieldPosition::DONT_CARE);
1552 UnicodeString expected("ene. de 2009 \\u2013 feb. de 2012");
1553 assertEquals(
1554 "",
1555 expected.unescape(),
1556 fmt->format(&interval, appendTo, fpos, status));
1557 if (!assertSuccess("Error formatting", status)) {
1558 return;
1559 }
1560 }
1561
1562
testTicket11985()1563 void DateIntervalFormatTest::testTicket11985() {
1564 UErrorCode status = U_ZERO_ERROR;
1565 LocalPointer<DateIntervalFormat> fmt(
1566 DateIntervalFormat::createInstance(UDAT_HOUR_MINUTE, Locale::getEnglish(), status));
1567 if (!assertSuccess("createInstance", status)) {
1568 return;
1569 }
1570 UnicodeString pattern;
1571 static_cast<const SimpleDateFormat*>(fmt->getDateFormat())->toPattern(pattern);
1572 assertEquals("Format pattern", "h:mm a", pattern);
1573 }
1574
1575 // Ticket 11669 - thread safety of DateIntervalFormat::format(). This test failed before
1576 // the implementation was fixed.
1577
1578 static const DateIntervalFormat *gIntervalFormatter = NULL; // The Formatter to be used concurrently by test threads.
1579 static const DateInterval *gInterval = NULL; // The date interval to be formatted concurrently.
1580 static const UnicodeString *gExpectedResult = NULL;
1581
threadFunc11669(int32_t threadNum)1582 void DateIntervalFormatTest::threadFunc11669(int32_t threadNum) {
1583 (void)threadNum;
1584 for (int loop=0; loop<1000; ++loop) {
1585 UErrorCode status = U_ZERO_ERROR;
1586 FieldPosition pos(FieldPosition::DONT_CARE);
1587 UnicodeString result;
1588 gIntervalFormatter->format(gInterval, result, pos, status);
1589 if (U_FAILURE(status)) {
1590 errln("%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1591 return;
1592 }
1593 if (result != *gExpectedResult) {
1594 errln("%s:%d Expected \"%s\", got \"%s\"", __FILE__, __LINE__, CStr(*gExpectedResult)(), CStr(result)());
1595 return;
1596 }
1597 }
1598 }
1599
testTicket11669()1600 void DateIntervalFormatTest::testTicket11669() {
1601 UErrorCode status = U_ZERO_ERROR;
1602 LocalPointer<DateIntervalFormat> formatter(DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getEnglish(), status), status);
1603 LocalPointer<TimeZone> tz(TimeZone::createTimeZone("America/Los_Angleles"), status);
1604 LocalPointer<Calendar> intervalStart(Calendar::createInstance(*tz, Locale::getEnglish(), status), status);
1605 LocalPointer<Calendar> intervalEnd(Calendar::createInstance(*tz, Locale::getEnglish(), status), status);
1606 if (U_FAILURE(status)) {
1607 errcheckln(status, "%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1608 return;
1609 }
1610
1611 intervalStart->set(2009, 6, 1, 14, 0);
1612 intervalEnd->set(2009, 6, 2, 14, 0);
1613 DateInterval interval(intervalStart->getTime(status), intervalEnd->getTime(status));
1614 FieldPosition pos(FieldPosition::DONT_CARE);
1615 UnicodeString expectedResult;
1616 formatter->format(&interval, expectedResult, pos, status);
1617 if (U_FAILURE(status)) {
1618 errln("%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1619 return;
1620 }
1621
1622 gInterval = &interval;
1623 gIntervalFormatter = formatter.getAlias();
1624 gExpectedResult = &expectedResult;
1625
1626 ThreadPool<DateIntervalFormatTest> threads(this, 4, &DateIntervalFormatTest::threadFunc11669);
1627 threads.start();
1628 threads.join();
1629
1630 gInterval = NULL; // Don't leave dangling pointers lying around. Not strictly necessary.
1631 gIntervalFormatter = NULL;
1632 gExpectedResult = NULL;
1633 }
1634
1635
1636 // testTicket12065
1637 // Using a DateIntervalFormat to format shouldn't change its state in any way
1638 // that changes how the behavior of operator ==.
testTicket12065()1639 void DateIntervalFormatTest::testTicket12065() {
1640 UErrorCode status = U_ZERO_ERROR;
1641 LocalPointer<DateIntervalFormat> formatter(DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getEnglish(), status), status);
1642 if (formatter.isNull()) {
1643 dataerrln("FAIL: DateIntervalFormat::createInstance failed for Locale::getEnglish()");
1644 return;
1645 }
1646 LocalPointer<DateIntervalFormat> clone(formatter->clone());
1647 if (*formatter != *clone) {
1648 errln("%s:%d DateIntervalFormat and clone are not equal.", __FILE__, __LINE__);
1649 return;
1650 }
1651 DateInterval interval((UDate) 1232364615000.0, (UDate) 1328787015000.0);
1652 UnicodeString appendTo;
1653 FieldPosition fpos(FieldPosition::DONT_CARE);
1654 formatter->format(&interval, appendTo, fpos, status);
1655 if (*formatter != *clone) {
1656 errln("%s:%d DateIntervalFormat and clone are not equal after formatting.", __FILE__, __LINE__);
1657 return;
1658 }
1659 if (U_FAILURE(status)) {
1660 errln("%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1661 }
1662 }
1663
1664
testFormattedDateInterval()1665 void DateIntervalFormatTest::testFormattedDateInterval() {
1666 IcuTestErrorCode status(*this, "testFormattedDateInterval");
1667 LocalPointer<DateIntervalFormat> fmt(DateIntervalFormat::createInstance(u"dMMMMy", "en-US", status), status);
1668
1669 {
1670 const char16_t* message = u"FormattedDateInterval test 1";
1671 const char16_t* expectedString = u"July 20 \u2013 25, 2018";
1672 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1673 if (status.errIfFailureAndReset()) { return; }
1674 LocalPointer<Calendar> input2(Calendar::createInstance("en-GB", status));
1675 if (status.errIfFailureAndReset()) { return; }
1676 input1->set(2018, 6, 20);
1677 input2->set(2018, 6, 25);
1678 FormattedDateInterval result = fmt->formatToValue(*input1, *input2, status);
1679 static const UFieldPositionWithCategory expectedFieldPositions[] = {
1680 // field, begin index, end index
1681 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 0, 4},
1682 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 5, 7},
1683 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 5, 7},
1684 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 10, 12},
1685 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 10, 12},
1686 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 14, 18}};
1687 checkMixedFormattedValue(
1688 message,
1689 result,
1690 expectedString,
1691 expectedFieldPositions,
1692 UPRV_LENGTHOF(expectedFieldPositions));
1693 }
1694
1695 {
1696 const char16_t* message = u"FormattedDateInterval identical dates test: no span field";
1697 const char16_t* expectedString = u"July 20, 2018";
1698 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1699 input1->set(2018, 6, 20);
1700 FormattedDateInterval result = fmt->formatToValue(*input1, *input1, status);
1701 static const UFieldPositionWithCategory expectedFieldPositions[] = {
1702 // field, begin index, end index
1703 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 0, 4},
1704 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 5, 7},
1705 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 9, 13}};
1706 checkMixedFormattedValue(
1707 message,
1708 result,
1709 expectedString,
1710 expectedFieldPositions,
1711 UPRV_LENGTHOF(expectedFieldPositions));
1712 }
1713
1714 // Test sample code
1715 {
1716 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1717 LocalPointer<Calendar> input2(Calendar::createInstance("en-GB", status));
1718 input1->set(2018, 6, 20);
1719 input2->set(2018, 7, 3);
1720
1721 // Let fmt be a DateIntervalFormat for locale en-US and skeleton dMMMMy
1722 // Let input1 be July 20, 2018 and input2 be August 3, 2018:
1723 FormattedDateInterval result = fmt->formatToValue(*input1, *input2, status);
1724 assertEquals("Expected output from format",
1725 u"July 20 \u2013 August 3, 2018", result.toString(status));
1726 ConstrainedFieldPosition cfpos;
1727 cfpos.constrainField(UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0);
1728 if (result.nextPosition(cfpos, status)) {
1729 assertEquals("Expect start index", 0, cfpos.getStart());
1730 assertEquals("Expect end index", 7, cfpos.getLimit());
1731 } else {
1732 // No such span: can happen if input dates are equal.
1733 }
1734 assertFalse("No more than one occurrence of the field",
1735 result.nextPosition(cfpos, status));
1736 }
1737
1738 // To test the fallback pattern behavior, make a custom DateIntervalInfo.
1739 DateIntervalInfo dtitvinf(status);
1740 dtitvinf.setFallbackIntervalPattern("<< {1} --- {0} >>", status);
1741 fmt.adoptInsteadAndCheckErrorCode(
1742 DateIntervalFormat::createInstance(u"dMMMMy", "en-US", dtitvinf, status),
1743 status);
1744
1745 {
1746 const char16_t* message = u"FormattedDateInterval with fallback format test 1";
1747 const char16_t* expectedString = u"<< July 25, 2018 --- July 20, 2018 >>";
1748 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1749 if (status.errIfFailureAndReset()) { return; }
1750 LocalPointer<Calendar> input2(Calendar::createInstance("en-GB", status));
1751 if (status.errIfFailureAndReset()) { return; }
1752 input1->set(2018, 6, 20);
1753 input2->set(2018, 6, 25);
1754 FormattedDateInterval result = fmt->formatToValue(*input1, *input2, status);
1755 static const UFieldPositionWithCategory expectedFieldPositions[] = {
1756 // field, begin index, end index
1757 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 3, 16},
1758 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 3, 7},
1759 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 8, 10},
1760 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 12, 16},
1761 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 21, 34},
1762 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 21, 25},
1763 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 26, 28},
1764 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 30, 34}};
1765 checkMixedFormattedValue(
1766 message,
1767 result,
1768 expectedString,
1769 expectedFieldPositions,
1770 UPRV_LENGTHOF(expectedFieldPositions));
1771 }
1772 }
1773
testCreateInstanceForAllLocales()1774 void DateIntervalFormatTest::testCreateInstanceForAllLocales() {
1775 IcuTestErrorCode status(*this, "testCreateInstanceForAllLocales");
1776 int32_t locale_count = 0;
1777 const Locale* locales = icu::Locale::getAvailableLocales(locale_count);
1778 // Iterate through all locales
1779 for (int32_t i = 0; i < locale_count; i++) {
1780 std::unique_ptr<icu::StringEnumeration> calendars(
1781 icu::Calendar::getKeywordValuesForLocale(
1782 "calendar", locales[i], FALSE, status));
1783 int32_t calendar_count = calendars->count(status);
1784 if (status.errIfFailureAndReset()) { break; }
1785 // In quick mode, only run 1/5 of locale combination
1786 // to make the test run faster.
1787 if (quick && (i % 5 != 0)) continue;
1788 LocalPointer<DateIntervalFormat> fmt(
1789 DateIntervalFormat::createInstance(u"dMMMMy", locales[i], status),
1790 status);
1791 if (status.errIfFailureAndReset(locales[i].getName())) {
1792 continue;
1793 }
1794 // Iterate through all calendars in this locale
1795 for (int32_t j = 0; j < calendar_count; j++) {
1796 // In quick mode, only run 1/7 of locale/calendar combination
1797 // to make the test run faster.
1798 if (quick && ((i * j) % 7 != 0)) continue;
1799 const char* calendar = calendars->next(nullptr, status);
1800 Locale locale(locales[i]);
1801 locale.setKeywordValue("calendar", calendar, status);
1802 fmt.adoptInsteadAndCheckErrorCode(
1803 DateIntervalFormat::createInstance(u"dMMMMy", locale, status),
1804 status);
1805 status.errIfFailureAndReset(locales[i].getName());
1806 }
1807 }
1808 }
1809
testFormatMillisecond()1810 void DateIntervalFormatTest::testFormatMillisecond() {
1811 struct
1812 {
1813 int year;
1814 int month;
1815 int day;
1816 int from_hour;
1817 int from_miniute;
1818 int from_second;
1819 int from_millisecond;
1820 int to_hour;
1821 int to_miniute;
1822 int to_second;
1823 int to_millisecond;
1824 const char* skeleton;
1825 const char16_t* expected;
1826 }
1827 kTestCases [] =
1828 {
1829 // From To
1830 // y m d h m s ms h m s ms skeleton expected
1831 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "ms", u"23:45"},
1832 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "msS", u"23:45.3"},
1833 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "msSS", u"23:45.32"},
1834 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "msSSS", u"23:45.321"},
1835 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "ms", u"23:45"},
1836 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "msS", u"23:45.3 \u2013 23:45.9"},
1837 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "msSS", u"23:45.32 \u2013 23:45.98"},
1838 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "msSSS", u"23:45.321 \u2013 23:45.987"},
1839 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "ms", u"23:45 \u2013 23:46"},
1840 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "msS", u"23:45.3 \u2013 23:46.9"},
1841 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "msSS", u"23:45.32 \u2013 23:46.98"},
1842 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "msSSS", u"23:45.321 \u2013 23:46.987"},
1843 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "ms", u"23:45 \u2013 24:45"},
1844 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "msS", u"23:45.3 \u2013 24:45.9"},
1845 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "msSS", u"23:45.32 \u2013 24:45.98"},
1846 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "msSSS", u"23:45.321 \u2013 24:45.987"},
1847 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "s", u"45"},
1848 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "sS", u"45.3"},
1849 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "sSS", u"45.32"},
1850 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "sSSS", u"45.321"},
1851 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "s", u"45"},
1852 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "sS", u"45.3 \u2013 45.9"},
1853 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "sSS", u"45.32 \u2013 45.98"},
1854 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "sSSS", u"45.321 \u2013 45.987"},
1855 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "s", u"45 \u2013 46"},
1856 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "sS", u"45.3 \u2013 46.9"},
1857 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "sSS", u"45.32 \u2013 46.98"},
1858 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "sSSS", u"45.321 \u2013 46.987"},
1859 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "s", u"45 \u2013 45"},
1860 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "sS", u"45.3 \u2013 45.9"},
1861 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "sSS", u"45.32 \u2013 45.98"},
1862 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "sSSS", u"45.321 \u2013 45.987"},
1863 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "S", u"3"},
1864 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "SS", u"32"},
1865 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "SSS", u"321"},
1866
1867 // Same millisecond but in different second.
1868 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 321, "S", u"3 \u2013 3"},
1869 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 321, "SS", u"32 \u2013 32"},
1870 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 321, "SSS", u"321 \u2013 321"},
1871
1872 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "S", u"3 \u2013 9"},
1873 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "SS", u"32 \u2013 98"},
1874 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "SSS", u"321 \u2013 987"},
1875 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "S", u"3 \u2013 9"},
1876 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "SS", u"32 \u2013 98"},
1877 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "SSS", u"321 \u2013 987"},
1878 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "S", u"3 \u2013 9"},
1879 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "SS", u"32 \u2013 98"},
1880 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "SSS", u"321 \u2013 987"},
1881 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr},
1882 };
1883
1884 const Locale &enLocale = Locale::getEnglish();
1885 IcuTestErrorCode status(*this, "testFormatMillisecond");
1886 LocalPointer<Calendar> calendar(Calendar::createInstance(enLocale, status));
1887 if (status.errIfFailureAndReset()) { return; }
1888
1889 for (int32_t i = 0; kTestCases[i].year > 0; i++) {
1890 LocalPointer<DateIntervalFormat> fmt(DateIntervalFormat::createInstance(
1891 kTestCases[i].skeleton, enLocale, status));
1892 if (status.errIfFailureAndReset()) { continue; }
1893
1894 calendar->clear();
1895 calendar->set(kTestCases[i].year, kTestCases[i].month, kTestCases[i].day,
1896 kTestCases[i].from_hour, kTestCases[i].from_miniute, kTestCases[i].from_second);
1897 UDate from = calendar->getTime(status) + kTestCases[i].from_millisecond;
1898 if (status.errIfFailureAndReset()) { continue; }
1899
1900 calendar->clear();
1901 calendar->set(kTestCases[i].year, kTestCases[i].month, kTestCases[i].day,
1902 kTestCases[i].to_hour, kTestCases[i].to_miniute, kTestCases[i].to_second);
1903 UDate to = calendar->getTime(status) + kTestCases[i].to_millisecond;
1904 FormattedDateInterval res = fmt->formatToValue(DateInterval(from, to), status);
1905 if (status.errIfFailureAndReset()) { continue; }
1906
1907 UnicodeString formatted = res.toString(status);
1908 if (status.errIfFailureAndReset()) { continue; }
1909 if (formatted != kTestCases[i].expected) {
1910 std::string tmp1;
1911 std::string tmp2;
1912 errln("Case %d for skeleton %s : Got %s but expect %s",
1913 i, kTestCases[i].skeleton, formatted.toUTF8String<std::string>(tmp1).c_str(),
1914 UnicodeString(kTestCases[i].expected).toUTF8String<std::string>(tmp2).c_str());
1915 }
1916 }
1917 }
1918
testTicket20707()1919 void DateIntervalFormatTest::testTicket20707() {
1920 IcuTestErrorCode status(*this, "testTicket20707");
1921
1922 const char16_t timeZone[] = u"UTC";
1923 Locale locales[] = {"en-u-hc-h24", "en-u-hc-h23", "en-u-hc-h12", "en-u-hc-h11", "en", "en-u-hc-h25", "hi-IN-u-hc-h11"};
1924
1925 // Clomuns: hh, HH, kk, KK, jj, JJs, CC
1926 UnicodeString expected[][7] = {
1927 // Hour-cycle: k
1928 {u"12 AM", u"24", u"24", u"12 AM", u"24", u"0 (hour: 24)", u"12 AM"},
1929 // Hour-cycle: H
1930 {u"12 AM", u"00", u"00", u"12 AM", u"00", u"0 (hour: 00)", u"12 AM"},
1931 // Hour-cycle: h
1932 {u"12 AM", u"00", u"00", u"12 AM", u"12 AM", u"0 (hour: 12)", u"12 AM"},
1933 // Hour-cycle: K
1934 {u"0 AM", u"00", u"00", u"0 AM", u"0 AM", u"0 (hour: 00)", u"0 AM"},
1935 {u"12 AM", u"00", u"00", u"12 AM", u"12 AM", u"0 (hour: 12)", u"12 AM"},
1936 {u"12 AM", u"00", u"00", u"12 AM", u"12 AM", u"0 (hour: 12)", u"12 AM"},
1937 // Hour-cycle: K
1938 {u"0 am", u"00", u"00", u"0 am", u"0 am", u"0 (\u0918\u0902\u091F\u093E: 00)", u"\u0930\u093E\u0924 0"}
1939 };
1940
1941 int32_t i = 0;
1942 for (Locale locale : locales) {
1943 int32_t j = 0;
1944 for (const UnicodeString skeleton : {u"hh", u"HH", u"kk", u"KK", u"jj", u"JJs", u"CC"}) {
1945 LocalPointer<DateIntervalFormat> dtifmt(DateIntervalFormat::createInstance(skeleton, locale, status));
1946 if (status.errDataIfFailureAndReset()) {
1947 continue;
1948 }
1949 FieldPosition fposition;
1950 UnicodeString result;
1951 LocalPointer<Calendar> calendar(Calendar::createInstance(TimeZone::createTimeZone(timeZone), status));
1952 calendar->setTime(UDate(1563235200000), status);
1953 dtifmt->format(*calendar, *calendar, result, fposition, status);
1954
1955 assertEquals("Formatted result", expected[i][j++], result);
1956 }
1957 i++;
1958 }
1959 }
1960
1961 #endif /* #if !UCONFIG_NO_FORMATTING */
1962