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 TESTCASE_AUTO_BEGIN;
49 TESTCASE_AUTO(testAPI);
50 TESTCASE_AUTO(testFormat);
51 TESTCASE_AUTO(testFormatUserDII);
52 TESTCASE_AUTO(testSetIntervalPatternNoSideEffect);
53 TESTCASE_AUTO(testYearFormats);
54 TESTCASE_AUTO(testStress);
55 TESTCASE_AUTO(testTicket11583_2);
56 TESTCASE_AUTO(testTicket11985);
57 TESTCASE_AUTO(testTicket11669);
58 TESTCASE_AUTO(testTicket12065);
59 TESTCASE_AUTO(testFormattedDateInterval);
60 TESTCASE_AUTO(testCreateInstanceForAllLocales);
61 TESTCASE_AUTO(testTicket20707);
62 TESTCASE_AUTO(testFormatMillisecond);
63 TESTCASE_AUTO(testHourMetacharacters);
64 TESTCASE_AUTO(testContext);
65 TESTCASE_AUTO(testTicket21222GregorianEraDiff);
66 TESTCASE_AUTO(testTicket21222ROCEraDiff);
67 TESTCASE_AUTO(testTicket21222JapaneseEraDiff);
68 TESTCASE_AUTO(testTicket21939);
69 TESTCASE_AUTO_END;
70 }
71
72 /**
73 * Test various generic API methods of DateIntervalFormat for API coverage.
74 */
testAPI()75 void DateIntervalFormatTest::testAPI() {
76
77 /* ====== Test create interval instance with default locale and skeleton
78 */
79 UErrorCode status = U_ZERO_ERROR;
80 logln("Testing DateIntervalFormat create instance with default locale and skeleton");
81
82 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, status);
83 if(U_FAILURE(status)) {
84 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + default locale) - exiting");
85 return;
86 } else {
87 delete dtitvfmt;
88 }
89
90
91 /* ====== Test create interval instance with given locale and skeleton
92 */
93 status = U_ZERO_ERROR;
94 logln("Testing DateIntervalFormat create instance with given locale and skeleton");
95
96 dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getJapanese(), status);
97 if(U_FAILURE(status)) {
98 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + locale) - exiting");
99 return;
100 } else {
101 delete dtitvfmt;
102 }
103
104
105 /* ====== Test create interval instance with dateIntervalInfo and skeleton
106 */
107 status = U_ZERO_ERROR;
108 logln("Testing DateIntervalFormat create instance with dateIntervalInfo and skeleton");
109
110 DateIntervalInfo* dtitvinf = new DateIntervalInfo(Locale::getSimplifiedChinese(), status);
111
112 dtitvfmt = DateIntervalFormat::createInstance("EEEdMMMyhms", *dtitvinf, status);
113 delete dtitvinf;
114
115 if(U_FAILURE(status)) {
116 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + DateIntervalInfo + default locale) - exiting");
117 return;
118 } else {
119 delete dtitvfmt;
120 }
121
122
123 /* ====== Test create interval instance with dateIntervalInfo and skeleton
124 */
125 status = U_ZERO_ERROR;
126 logln("Testing DateIntervalFormat create instance with dateIntervalInfo and skeleton");
127
128 dtitvinf = new DateIntervalInfo(Locale::getSimplifiedChinese(), status);
129
130 dtitvfmt = DateIntervalFormat::createInstance("EEEdMMMyhms", Locale::getSimplifiedChinese(), *dtitvinf, status);
131 delete dtitvinf;
132 if(U_FAILURE(status)) {
133 dataerrln("ERROR: Could not create DateIntervalFormat (skeleton + DateIntervalInfo + locale) - exiting");
134 return;
135 }
136 // not deleted, test clone
137
138
139 // ====== Test clone()
140 status = U_ZERO_ERROR;
141 logln("Testing DateIntervalFormat clone");
142
143 DateIntervalFormat* another = dtitvfmt->clone();
144 if ( (*another) != (*dtitvfmt) ) {
145 dataerrln("%s:%d ERROR: clone failed", __FILE__, __LINE__);
146 }
147
148
149 // ====== Test getDateIntervalInfo, setDateIntervalInfo, adoptDateIntervalInfo
150 status = U_ZERO_ERROR;
151 logln("Testing DateIntervalFormat getDateIntervalInfo");
152 const DateIntervalInfo* inf = another->getDateIntervalInfo();
153 dtitvfmt->setDateIntervalInfo(*inf, status);
154 const DateIntervalInfo* anotherInf = dtitvfmt->getDateIntervalInfo();
155 if ( (*inf) != (*anotherInf) || U_FAILURE(status) ) {
156 dataerrln("ERROR: getDateIntervalInfo/setDateIntervalInfo failed");
157 }
158
159 {
160 // We make sure that setDateIntervalInfo does not corrupt the cache. See ticket 9919.
161 status = U_ZERO_ERROR;
162 logln("Testing DateIntervalFormat setDateIntervalInfo");
163 const Locale &enLocale = Locale::getEnglish();
164 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yMd", enLocale, status));
165 if (U_FAILURE(status)) {
166 errln("Failure encountered: %s", u_errorName(status));
167 return;
168 }
169 UnicodeString expected;
170 LocalPointer<Calendar> fromTime(Calendar::createInstance(enLocale, status));
171 LocalPointer<Calendar> toTime(Calendar::createInstance(enLocale, status));
172 if (U_FAILURE(status)) {
173 errln("Failure encountered: %s", u_errorName(status));
174 return;
175 }
176 FieldPosition pos(FieldPosition::DONT_CARE);
177 fromTime->set(2013, 3, 26);
178 toTime->set(2013, 3, 28);
179 dif->format(*fromTime, *toTime, expected, pos, status);
180 if (U_FAILURE(status)) {
181 errln("Failure encountered: %s", u_errorName(status));
182 return;
183 }
184 LocalPointer<DateIntervalInfo> dii(new DateIntervalInfo(Locale::getEnglish(), status), status);
185 if (U_FAILURE(status)) {
186 errln("Failure encountered: %s", u_errorName(status));
187 return;
188 }
189 dii->setIntervalPattern(ctou("yMd"), UCAL_DATE, ctou("M/d/y \\u2013 d"), status);
190 dif->setDateIntervalInfo(*dii, status);
191 if (U_FAILURE(status)) {
192 errln("Failure encountered: %s", u_errorName(status));
193 return;
194 }
195 dif.adoptInstead(DateIntervalFormat::createInstance("yMd", enLocale, status));
196 if (U_FAILURE(status)) {
197 errln("Failure encountered: %s", u_errorName(status));
198 return;
199 }
200 UnicodeString actual;
201 pos = 0;
202 dif->format(*fromTime, *toTime, actual, pos, status);
203 if (U_FAILURE(status)) {
204 errln("Failure encountered: %s", u_errorName(status));
205 return;
206 }
207 if (expected != actual) {
208 errln("DateIntervalFormat.setIntervalInfo should have no side effects.");
209 }
210 }
211
212 /*
213 status = U_ZERO_ERROR;
214 DateIntervalInfo* nonConstInf = inf->clone();
215 dtitvfmt->adoptDateIntervalInfo(nonConstInf, status);
216 anotherInf = dtitvfmt->getDateIntervalInfo();
217 if ( (*inf) != (*anotherInf) || U_FAILURE(status) ) {
218 dataerrln("ERROR: adoptDateIntervalInfo failed");
219 }
220 */
221
222 // ====== Test getDateFormat, setDateFormat, adoptDateFormat
223
224 status = U_ZERO_ERROR;
225 logln("Testing DateIntervalFormat getDateFormat");
226 /*
227 const DateFormat* fmt = another->getDateFormat();
228 dtitvfmt->setDateFormat(*fmt, status);
229 const DateFormat* anotherFmt = dtitvfmt->getDateFormat();
230 if ( (*fmt) != (*anotherFmt) || U_FAILURE(status) ) {
231 dataerrln("ERROR: getDateFormat/setDateFormat failed");
232 }
233
234 status = U_ZERO_ERROR;
235 DateFormat* nonConstFmt = fmt->clone();
236 dtitvfmt->adoptDateFormat(nonConstFmt, status);
237 anotherFmt = dtitvfmt->getDateFormat();
238 if ( (*fmt) != (*anotherFmt) || U_FAILURE(status) ) {
239 dataerrln("ERROR: adoptDateFormat failed");
240 }
241 delete fmt;
242 */
243
244
245 // ======= Test getStaticClassID()
246
247 logln("Testing getStaticClassID()");
248
249
250 if(dtitvfmt->getDynamicClassID() != DateIntervalFormat::getStaticClassID()) {
251 errln("ERROR: getDynamicClassID() didn't return the expected value");
252 }
253
254 delete another;
255
256 // ====== test constructor/copy constructor and assignment
257 /* they are protected, no test
258 logln("Testing DateIntervalFormat constructor and assignment operator");
259 status = U_ZERO_ERROR;
260
261 DateFormat* constFmt = dtitvfmt->getDateFormat()->clone();
262 inf = dtitvfmt->getDateIntervalInfo()->clone();
263
264
265 DateIntervalFormat* dtifmt = new DateIntervalFormat(fmt, inf, status);
266 if(U_FAILURE(status)) {
267 dataerrln("ERROR: Could not create DateIntervalFormat (default) - exiting");
268 return;
269 }
270
271 DateIntervalFormat* dtifmt2 = new(dtifmt);
272 if ( (*dtifmt) != (*dtifmt2) ) {
273 dataerrln("ERROR: Could not create DateIntervalFormat (default) - exiting");
274 return;
275 }
276
277 DateIntervalFormat dtifmt3 = (*dtifmt);
278 if ( (*dtifmt) != dtifmt3 ) {
279 dataerrln("ERROR: Could not create DateIntervalFormat (default) - exiting");
280 return;
281 }
282
283 delete dtifmt2;
284 delete dtifmt3;
285 delete dtifmt;
286 */
287
288
289 //===== test format and parse ==================
290 Formattable formattable;
291 formattable.setInt64(10);
292 UnicodeString res;
293 FieldPosition pos(FieldPosition::DONT_CARE);
294 status = U_ZERO_ERROR;
295 dtitvfmt->format(formattable, res, pos, status);
296 if ( status != U_ILLEGAL_ARGUMENT_ERROR ) {
297 dataerrln("ERROR: format non-date-interval object should set U_ILLEGAL_ARGUMENT_ERROR - exiting");
298 return;
299 }
300
301 DateInterval* dtitv = new DateInterval(3600*24*365, 3600*24*366);
302 formattable.adoptObject(dtitv);
303 res.remove();
304 pos = 0;
305 status = U_ZERO_ERROR;
306 dtitvfmt->format(formattable, res, pos, status);
307 if ( U_FAILURE(status) ) {
308 dataerrln("ERROR: format date interval failed - exiting");
309 return;
310 }
311
312 const DateFormat* dfmt = dtitvfmt->getDateFormat();
313 Calendar* fromCal = dfmt->getCalendar()->clone();
314 Calendar* toCal = dfmt->getCalendar()->clone();
315 res.remove();
316 pos = 0;
317 status = U_ZERO_ERROR;
318 dtitvfmt->format(*fromCal, *toCal, res, pos, status);
319 if ( U_FAILURE(status) ) {
320 dataerrln("ERROR: format date interval failed - exiting");
321 return;
322 }
323 delete fromCal;
324 delete toCal;
325
326
327 Formattable fmttable;
328 status = U_ZERO_ERROR;
329 // TODO: why do I need cast?
330 ((Format*)dtitvfmt)->parseObject(res, fmttable, status);
331 if ( status != U_INVALID_FORMAT_ERROR ) {
332 dataerrln("ERROR: parse should set U_INVALID_FORMAT_ERROR - exiting");
333 return;
334 }
335
336 delete dtitvfmt;
337
338 //====== test setting time zone
339 logln("Testing DateIntervalFormat set & format with different time zones, get time zone");
340 status = U_ZERO_ERROR;
341 dtitvfmt = DateIntervalFormat::createInstance("MMMdHHmm", Locale::getEnglish(), status);
342 if ( U_SUCCESS(status) ) {
343 UDate date1 = 1299090600000.0; // 2011-Mar-02 1030 in US/Pacific, 2011-Mar-03 0330 in Asia/Tokyo
344 UDate date2 = 1299115800000.0; // 2011-Mar-02 1730 in US/Pacific, 2011-Mar-03 1030 in Asia/Tokyo
345
346 DateInterval * dtitv12 = new DateInterval(date1, date2);
347 TimeZone * tzCalif = TimeZone::createTimeZone("US/Pacific");
348 TimeZone * tzTokyo = TimeZone::createTimeZone("Asia/Tokyo");
349 UnicodeString fmtCalif = UnicodeString(u"Mar 2, 10:30\u2009\u2013\u200917:30", -1);
350 UnicodeString fmtTokyo = UnicodeString(u"Mar 3, 03:30\u2009\u2013\u200910:30", -1);
351
352 dtitvfmt->adoptTimeZone(tzCalif);
353 res.remove();
354 pos = 0;
355 status = U_ZERO_ERROR;
356 dtitvfmt->format(dtitv12, res, pos, status);
357 if ( U_SUCCESS(status) ) {
358 if ( res.compare(fmtCalif) != 0 ) {
359 errln("ERROR: DateIntervalFormat::format for tzCalif, expect " + fmtCalif + ", get " + res);
360 }
361 } else {
362 errln("ERROR: DateIntervalFormat::format for tzCalif, status %s", u_errorName(status));
363 }
364
365 dtitvfmt->setTimeZone(*tzTokyo);
366 res.remove();
367 pos = 0;
368 status = U_ZERO_ERROR;
369 dtitvfmt->format(dtitv12, res, pos, status);
370 if ( U_SUCCESS(status) ) {
371 if ( res.compare(fmtTokyo) != 0 ) {
372 errln("ERROR: DateIntervalFormat::format for tzTokyo, expect " + fmtTokyo + ", get " + res);
373 }
374 } else {
375 errln("ERROR: DateIntervalFormat::format for tzTokyo, status %s", u_errorName(status));
376 }
377
378 if ( dtitvfmt->getTimeZone() != *tzTokyo ) {
379 errln("ERROR: DateIntervalFormat::getTimeZone returns mismatch.");
380 }
381
382 delete tzTokyo; // tzCalif was owned by dtitvfmt which should have deleted it
383 delete dtitv12;
384 delete dtitvfmt;
385 } else {
386 errln("ERROR: DateIntervalFormat::createInstance(\"MdHH\", Locale::getEnglish(), ...), status %s", u_errorName(status));
387 }
388 //====== test format in testFormat()
389
390 //====== test DateInterval class (better coverage)
391 DateInterval dtitv1(3600*24*365, 3600*24*366);
392 DateInterval dtitv2(dtitv1);
393
394 if (!(dtitv1 == dtitv2)) {
395 errln("ERROR: Copy constructor failed for DateInterval.");
396 }
397
398 DateInterval dtitv3(3600*365, 3600*366);
399 dtitv3 = dtitv1;
400 if (!(dtitv3 == dtitv1)) {
401 errln("ERROR: Equal operator failed for DateInterval.");
402 }
403
404 DateInterval *dtitv4 = dtitv1.clone();
405 if (*dtitv4 != dtitv1) {
406 errln("ERROR: Equal operator failed for DateInterval.");
407 }
408 delete dtitv4;
409 }
410
411
412 /**
413 * Test format
414 */
testFormat()415 void DateIntervalFormatTest::testFormat() {
416 // first item is date pattern
417 // followed by a group of locale/from_data/to_data/skeleton/interval_data
418 // Note that from_data/to_data are specified using era names from root, for the calendar specified by locale.
419 const char* DATA[] = {
420 "GGGGG y MM dd HH:mm:ss", // pattern for from_data/to_data
421 // test root
422 "root", "CE 2007 11 10 10:10:10", "CE 2007 12 10 10:10:10", "yM", "2007-11 \\u2013 2007-12",
423
424 // test 'H' and 'h', using availableFormat in fallback
425 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 15:10:10", "Hms", "10:10:10\\u2009\\u2013\\u200915:10:10",
426 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 15:10:10", "hms", "10:10:10\\u202FAM\\u2009\\u2013\\u20093:10:10\\u202FPM",
427
428 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMM", "October 2007\\u2009\\u2013\\u2009October 2008",
429 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMM", "Oct 2007\\u2009\\u2013\\u2009Oct 2008",
430 // test skeleton with both date and time
431 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMyhm", "Nov 10, 2007, 10:10\\u202FAM\\u2009\\u2013\\u2009Nov 20, 2007, 10:10\\u202FAM",
432
433 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "dMMMyhm", "Nov 10, 2007, 10:10\\u2009\\u2013\\u200911:10\\u202FAM",
434
435 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "hms", "10:10:10\\u202FAM\\u2009\\u2013\\u200911:10:10\\u202FAM",
436 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 10 11:10:10", "Hms", "10:10:10\\u2009\\u2013\\u200911:10:10",
437 "en", "CE 2007 11 10 20:10:10", "CE 2007 11 10 21:10:10", "Hms", "20:10:10\\u2009\\u2013\\u200921:10:10",
438
439 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10, 2007\\u2009\\u2013\\u2009Friday, October 10, 2008",
440
441 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMMy", "October 10, 2007\\u2009\\u2013\\u2009October 10, 2008",
442
443 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMM", "October 10, 2007\\u2009\\u2013\\u2009October 10, 2008",
444
445 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMMy", "October 2007\\u2009\\u2013\\u2009October 2008",
446
447 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10, 2007\\u2009\\u2013\\u2009Friday, October 10, 2008",
448
449 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMMMy", "Wed, Oct 10, 2007\\u2009\\u2013\\u2009Fri, Oct 10, 2008",
450
451 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMy", "Oct 10, 2007\\u2009\\u2013\\u2009Oct 10, 2008",
452
453 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMM", "Oct 10, 2007\\u2009\\u2013\\u2009Oct 10, 2008",
454
455 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMy", "Oct 2007\\u2009\\u2013\\u2009Oct 2008",
456
457 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMMM", "Wed, Oct 10, 2007\\u2009\\u2013\\u2009Fri, Oct 10, 2008",
458
459 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Fri, 10/10/2008",
460
461 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMy", "10/10/2007\\u2009\\u2013\\u200910/10/2008",
462
463 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dM", "10/10/2007\\u2009\\u2013\\u200910/10/2008",
464
465 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "My", "10/2007\\u2009\\u2013\\u200910/2008",
466
467 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdM", "Wed, 10/10/2007\\u2009\\u2013\\u2009Fri, 10/10/2008",
468
469 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "d", "10/10/2007\\u2009\\u2013\\u200910/10/2008",
470
471 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "Ed", "10 Wed\\u2009\\u2013\\u200910 Fri",
472
473 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "y", "2007\\u2009\\u2013\\u20092008",
474
475 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "M", "10/2007\\u2009\\u2013\\u200910/2008",
476
477
478
479 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hm", "10/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM",
480 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "Hm", "10/10/2007, 10:10\\u2009\\u2013\\u200910/10/2008, 10:10",
481 "en", "CE 2007 10 10 20:10:10", "CE 2008 10 10 20:10:10", "Hm", "10/10/2007, 20:10\\u2009\\u2013\\u200910/10/2008, 20:10",
482
483 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hmv", "10/10/2007, 10:10\\u202FAM PT\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM PT",
484
485 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hmz", "10/10/2007, 10:10\\u202FAM PDT\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM PDT",
486
487 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "h", "10/10/2007, 10\\u202FAM\\u2009\\u2013\\u200910/10/2008, 10\\u202FAM",
488
489 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hv", "10/10/2007, 10\\u202FAM PT\\u2009\\u2013\\u200910/10/2008, 10\\u202FAM PT",
490
491 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hz", "10/10/2007, 10\\u202FAM PDT\\u2009\\u2013\\u200910/10/2008, 10\\u202FAM PDT",
492
493 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Fri, 10/10/2008",
494
495 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EddMMy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Fri, 10/10/2008",
496
497 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmm", "10/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM",
498
499 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hhmmzz", "10/10/2007, 10:10\\u202FAM PDT\\u2009\\u2013\\u200910/10/2008, 10:10\\u202FAM PDT",
500
501 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hms", "10/10/2007, 10:10:10\\u202FAM\\u2009\\u2013\\u200910/10/2008, 10:10:10\\u202FAM",
502
503 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMMMMy", "O 10, 2007\\u2009\\u2013\\u2009O 10, 2008",
504
505 "en", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEEdM", "W, 10/10/2007\\u2009\\u2013\\u2009F, 10/10/2008",
506
507 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMMy", "Wednesday, October 10\\u2009\\u2013\\u2009Saturday, November 10, 2007",
508
509 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMy", "October 10\\u2009\\u2013\\u2009November 10, 2007",
510
511 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMM", "October 10\\u2009\\u2013\\u2009November 10",
512
513 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMMy", "October\\u2009\\u2013\\u2009November 2007",
514
515 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMM", "Wednesday, October 10\\u2009\\u2013\\u2009Saturday, November 10",
516
517 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMMMy", "Wed, Oct 10\\u2009\\u2013\\u2009Sat, Nov 10, 2007",
518
519 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMy", "Oct 10\\u2009\\u2013\\u2009Nov 10, 2007",
520
521 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMM", "Oct 10\\u2009\\u2013\\u2009Nov 10",
522
523 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMy", "Oct\\u2009\\u2013\\u2009Nov 2007",
524
525 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMMM", "Wed, Oct 10\\u2009\\u2013\\u2009Sat, Nov 10",
526
527 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdMy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Sat, 11/10/2007",
528
529 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMy", "10/10/2007\\u2009\\u2013\\u200911/10/2007",
530
531
532 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "My", "10/2007\\u2009\\u2013\\u200911/2007",
533
534 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EdM", "Wed, 10/10\\u2009\\u2013\\u2009Sat, 11/10",
535
536 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "d", "10/10\\u2009\\u2013\\u200911/10",
537
538 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "Ed", "10 Wed\\u2009\\u2013\\u200910 Sat",
539
540 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "y", "2007",
541
542 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "M", "10\\u2009\\u2013\\u200911",
543
544 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMM", "Oct\\u2009\\u2013\\u2009Nov",
545
546 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMM", "October\\u2009\\u2013\\u2009November",
547
548 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hm", "10/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200911/10/2007, 10:10\\u202FAM",
549 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "Hm", "10/10/2007, 10:10\\u2009\\u2013\\u200911/10/2007, 10:10",
550 "en", "CE 2007 10 10 20:10:10", "CE 2007 11 10 20:10:10", "Hm", "10/10/2007, 20:10\\u2009\\u2013\\u200911/10/2007, 20:10",
551
552 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmv", "10/10/2007, 10:10\\u202FAM PT\\u2009\\u2013\\u200911/10/2007, 10:10\\u202FAM PT",
553
554 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hmz", "10/10/2007, 10:10\\u202FAM PDT\\u2009\\u2013\\u200911/10/2007, 10:10\\u202FAM PST",
555
556 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "h", "10/10/2007, 10\\u202FAM\\u2009\\u2013\\u200911/10/2007, 10\\u202FAM",
557
558 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hv", "10/10/2007, 10\\u202FAM PT\\u2009\\u2013\\u200911/10/2007, 10\\u202FAM PT",
559
560 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hz", "10/10/2007, 10\\u202FAM PDT\\u2009\\u2013\\u200911/10/2007, 10\\u202FAM PST",
561
562 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEddMMyyyy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Sat, 11/10/2007",
563
564 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EddMMy", "Wed, 10/10/2007\\u2009\\u2013\\u2009Sat, 11/10/2007",
565
566
567 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hhmmzz", "10/10/2007, 10:10\\u202FAM PDT\\u2009\\u2013\\u200911/10/2007, 10:10\\u202FAM PST",
568
569 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hms", "10/10/2007, 10:10:10\\u202FAM\\u2009\\u2013\\u200911/10/2007, 10:10:10\\u202FAM",
570
571 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMMy", "O 10\\u2009\\u2013\\u2009N 10, 2007",
572
573 "en", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEEdM", "W, 10/10\\u2009\\u2013\\u2009S, 11/10",
574
575 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMMy", "Saturday, November 10\\u2009\\u2013\\u2009Tuesday, November 20, 2007",
576
577 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMMy", "November 10\\u2009\\u2013\\u200920, 2007",
578
579 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMM", "November 10\\u2009\\u2013\\u200920",
580
581
582 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMM", "Saturday, November 10\\u2009\\u2013\\u2009Tuesday, November 20",
583
584 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMMMy", "Sat, Nov 10\\u2009\\u2013\\u2009Tue, Nov 20, 2007",
585
586 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMy", "Nov 10\\u2009\\u2013\\u200920, 2007",
587
588 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMM", "Nov 10\\u2009\\u2013\\u200920",
589
590 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMy", "Nov 2007",
591
592 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMMM", "Sat, Nov 10\\u2009\\u2013\\u2009Tue, Nov 20",
593
594 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "Sat, 11/10/2007\\u2009\\u2013\\u2009Tue, 11/20/2007",
595
596 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMy", "11/10/2007\\u2009\\u2013\\u200911/20/2007",
597
598 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "11/10\\u2009\\u2013\\u200911/20",
599
600 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "11/2007",
601
602 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdM", "Sat, 11/10\\u2009\\u2013\\u2009Tue, 11/20",
603
604 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "d", "10\\u2009\\u2013\\u200920",
605
606 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "Ed", "10 Sat\\u2009\\u2013\\u200920 Tue",
607
608 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007",
609
610 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "M", "11",
611
612 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMM", "Nov",
613
614 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMM", "November",
615
616 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hm", "11/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM",
617 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "Hm", "11/10/2007, 10:10\\u2009\\u2013\\u200911/20/2007, 10:10",
618 "en", "CE 2007 11 10 20:10:10", "CE 2007 11 20 20:10:10", "Hm", "11/10/2007, 20:10\\u2009\\u2013\\u200911/20/2007, 20:10",
619
620 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmv", "11/10/2007, 10:10\\u202FAM PT\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM PT",
621
622 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmz", "11/10/2007, 10:10\\u202FAM PST\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM PST",
623
624 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "h", "11/10/2007, 10\\u202FAM\\u2009\\u2013\\u200911/20/2007, 10\\u202FAM",
625
626 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hv", "11/10/2007, 10\\u202FAM PT\\u2009\\u2013\\u200911/20/2007, 10\\u202FAM PT",
627
628 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hz", "11/10/2007, 10\\u202FAM PST\\u2009\\u2013\\u200911/20/2007, 10\\u202FAM PST",
629
630 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEddMMyyyy", "Sat, 11/10/2007\\u2009\\u2013\\u2009Tue, 11/20/2007",
631
632 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EddMMy", "Sat, 11/10/2007\\u2009\\u2013\\u2009Tue, 11/20/2007",
633
634 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmm", "11/10/2007, 10:10\\u202FAM\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM",
635
636 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hhmmzz", "11/10/2007, 10:10\\u202FAM PST\\u2009\\u2013\\u200911/20/2007, 10:10\\u202FAM PST",
637
638 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hms", "11/10/2007, 10:10:10\\u202FAM\\u2009\\u2013\\u200911/20/2007, 10:10:10\\u202FAM",
639 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "Hms", "11/10/2007, 10:10:10\\u2009\\u2013\\u200911/20/2007, 10:10:10",
640 "en", "CE 2007 11 10 20:10:10", "CE 2007 11 20 20:10:10", "Hms", "11/10/2007, 20:10:10\\u2009\\u2013\\u200911/20/2007, 20:10:10",
641
642 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMMMy", "N 10\\u2009\\u2013\\u200920, 2007",
643
644 "en", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEEdM", "S, 11/10\\u2009\\u2013\\u2009T, 11/20",
645
646 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMMy", "Wednesday, January 10, 2007",
647
648 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMMy", "January 10, 2007",
649
650 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMM", "January 10",
651
652 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMMy", "January 2007",
653
654 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMM", "Wednesday, January 10",
655
656 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdMMMy", "Wed, Jan 10, 2007",
657
658 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMy", "Jan 10, 2007",
659
660 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMM", "Jan 10",
661
662 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMy", "Jan 2007",
663
664 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdMMM", "Wed, Jan 10",
665
666
667 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMy", "1/10/2007",
668
669 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dM", "1/10",
670
671 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "My", "1/2007",
672
673 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EdM", "Wed, 1/10",
674
675 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "d", "10",
676
677 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "Ed", "10 Wed",
678
679 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "y", "2007",
680
681 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "M", "1",
682
683 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMM", "Jan",
684
685 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMM", "January",
686
687 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hm", "10:00\\u202FAM\\u2009\\u2013\\u20092:10\\u202FPM",
688 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "Hm", "10:00\\u2009\\u2013\\u200914:10",
689
690 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmv", "10:00\\u202FAM\\u2009\\u2013\\u20092:10\\u202FPM PT",
691
692 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hmz", "10:00\\u202FAM\\u2009\\u2013\\u20092:10\\u202FPM PST",
693
694 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "10\\u202FAM\\u2009\\u2013\\u20092\\u202FPM",
695 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "H", "10\\u2009\\u2013\\u200914",
696
697
698 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hz", "10\\u202FAM\\u2009\\u2013\\u20092\\u202FPM PST",
699
700 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEddMMyyyy", "Wed, 01/10/2007",
701
702 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EddMMy", "Wed, 01/10/2007",
703
704 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hhmm", "10:00\\u202FAM\\u2009\\u2013\\u20092:10\\u202FPM",
705 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "HHmm", "10:00\\u2009\\u2013\\u200914:10",
706
707 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hhmmzz", "10:00\\u202FAM\\u2009\\u2013\\u20092:10\\u202FPM PST",
708
709 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hms", "10:00:10\\u202FAM\\u2009\\u2013\\u20092:10:10\\u202FPM",
710 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "Hms", "10:00:10\\u2009\\u2013\\u200914:10:10",
711
712 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMMMMy", "J 10, 2007",
713
714 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEEdM", "W, 1/10",
715 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMMy", "January 10, 2007",
716
717 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMM", "January 10",
718
719 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "MMMMy", "January 2007",
720
721 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EEEEdMMMM", "Wednesday, January 10",
722
723 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMMMy", "Wed, Jan 10, 2007",
724
725 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMy", "Jan 10, 2007",
726
727 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMM", "Jan 10",
728
729
730 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMMM", "Wed, Jan 10",
731
732 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdMy", "Wed, 1/10/2007",
733
734 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMy", "1/10/2007",
735
736
737 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "My", "1/2007",
738
739 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EdM", "Wed, 1/10",
740
741 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "d", "10",
742
743
744 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "y", "2007",
745
746 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "M", "1",
747
748
749
750 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hm", "10:00\\u2009\\u2013\\u200910:20\\u202FAM",
751 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "Hm", "10:00\\u2009\\u2013\\u200910:20",
752
753
754 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmz", "10:00\\u2009\\u2013\\u200910:20\\u202FAM PST",
755
756
757 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hv", "10\\u202FAM PT",
758
759
760
761 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EddMMy", "Wed, 01/10/2007",
762
763 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hhmm", "10:00\\u2009\\u2013\\u200910:20\\u202FAM",
764 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "HHmm", "10:00\\u2009\\u2013\\u200910:20",
765
766 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hhmmzz", "10:00\\u2009\\u2013\\u200910:20\\u202FAM PST",
767
768
769 "en", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "dMMMMMy", "J 10, 2007",
770
771
772 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMMy", "Wednesday, January 10, 2007",
773
774 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMMMy", "January 10, 2007",
775
776
777 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "MMMMy", "January 2007",
778
779 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMM", "Wednesday, January 10",
780
781
782 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMMy", "Jan 10, 2007",
783
784 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMM", "Jan 10",
785
786
787 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdMMM", "Wed, Jan 10",
788
789 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdMy", "Wed, 1/10/2007",
790
791 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMy", "1/10/2007",
792
793
794 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "My", "1/2007",
795
796 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EdM", "Wed, 1/10",
797
798 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "d", "10",
799
800
801 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "y", "2007",
802
803 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "M", "1",
804
805
806 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "MMMM", "January",
807
808 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hm", "10:10\\u202FAM",
809 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "Hm", "10:10",
810
811
812 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmz", "10:10\\u202FAM PST",
813
814 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "h", "10\\u202FAM",
815
816 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hv", "10\\u202FAM PT",
817
818
819 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEddMMyyyy", "Wed, 01/10/2007",
820
821
822 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmm", "10:10\\u202FAM",
823 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "HHmm", "10:10",
824
825 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hhmmzz", "10:10\\u202FAM PST",
826
827
828 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "dMMMMMy", "J 10, 2007",
829
830 "en", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEEdM", "W, 1/10",
831
832 "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",
833
834
835 "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMMMy", "2007\\u5e7410\\u670810\\u65e5\\u81f311\\u670810\\u65e5",
836
837
838 "zh", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMMy", "2007\\u5e7410\\u6708\\u81f311\\u6708",
839
840
841 "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",
842
843 "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",
844
845
846 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMM", "11\\u670810\\u65e5\\u81f320\\u65e5",
847
848 "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:)
849
850 "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",
851
852
853 "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",
854
855
856 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "11/10 \\u2013 11/20",
857
858 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "2007\\u5E7411\\u6708",
859
860 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdM", "11/10\\u5468\\u516d\\u81f311/20\\u5468\\u4e8c",
861
862
863 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007\\u5E74", // (fixed expected result per ticket:6626:)
864
865 "zh", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "M", "11\\u6708",
866
867 "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)
868
869
870 "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",
871
872 "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",
873
874 "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:)
875
876 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "hm", "\\u4e0a\\u534810:00\\u81f3\\u4e0b\\u53482:10",
877
878
879 "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",
880
881 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "\\u4e0a\\u534810\\u65F6\\u81f3\\u4e0b\\u53482\\u65f6",
882
883 "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",
884
885 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hm", "\\u4e0a\\u534810:00\\u81f310:20",
886
887 "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",
888
889 "zh", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hz", "GMT-8\\u4e0a\\u534810\\u65f6",
890
891 "zh", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hm", "\\u4e0a\\u534810:10",
892
893 "zh", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "h", "\\u4e0a\\u534810\\u65f6",
894
895 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt. 2007\\u2009\\u2013\\u2009Freitag, 10. Okt. 2008",
896
897
898 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMMM", "10. Okt. 2007\\u2009\\u2013\\u200910. Okt. 2008",
899
900 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "MMMy", "Okt. 2007\\u2009\\u2013\\u2009Okt. 2008",
901
902
903 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdMy", "Mi., 10.10.2007\\u2009\\u2013\\u2009Fr., 10.10.2008",
904
905 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "dMy", "10.10.2007\\u2009\\u2013\\u200910.10.2008",
906
907
908 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "My", "10/2007\\u2009\\u2013\\u200910/2008",
909
910 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "EdM", "Mi., 10.10.2007\\u2009\\u2013\\u2009Fr., 10.10.2008",
911
912
913 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "y", "2007\\u20132008",
914
915 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "M", "10/2007\\u2009\\u2013\\u200910/2008",
916
917
918 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "hm", "10.10.2007, 10:10\\u202FAM\\u2009\\u2013\\u200910.10.2008, 10:10\\u202FAM",
919 "de", "CE 2007 10 10 10:10:10", "CE 2008 10 10 10:10:10", "Hm", "10.10.2007, 10:10\\u2009\\u2013\\u200910.10.2008, 10:10",
920
921 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMMy", "Mittwoch, 10. Okt.\\u2009\\u2013\\u2009Samstag, 10. Nov. 2007",
922
923
924 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dMMM", "10. Okt.\\u2009\\u2013\\u200910. Nov.",
925
926 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMMy", "Okt.\\u2013Nov. 2007",
927
928 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "EEEEdMMM", "Mittwoch, 10. Okt.\\u2009\\u2013\\u2009Samstag, 10. Nov.",
929
930
931 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "dM", "10.10. \\u2013 10.11.",
932
933 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "My", "10/2007\\u2009\\u2013\\u200911/2007",
934
935
936 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "d", "10.10. \\u2013 10.11.",
937
938 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "y", "2007",
939
940
941 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "MMM", "Okt.\\u2013Nov.",
942
943
944 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "hms", "10.10.2007, 10:10:10\\u202FAM\\u2009\\u2013\\u200910.11.2007, 10:10:10\\u202FAM",
945 "de", "CE 2007 10 10 10:10:10", "CE 2007 11 10 10:10:10", "Hms", "10.10.2007, 10:10:10\\u2009\\u2013\\u200910.11.2007, 10:10:10",
946
947 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMMy", "Samstag, 10. \\u2013 Dienstag, 20. Nov. 2007",
948
949 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dMMMy", "10.\\u201320. Nov. 2007",
950
951
952 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "MMMy", "Nov. 2007",
953
954 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EEEEdMMM", "Samstag, 10. \\u2013 Dienstag, 20. Nov.",
955
956 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "EdMy", "Sa., 10. \\u2013 Di., 20.11.2007",
957
958
959 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "dM", "10.\\u201320.11.",
960
961 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "My", "11/2007",
962
963
964 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "d", "10.\\u201320.",
965
966 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "y", "2007",
967
968
969 "de", "CE 2007 11 10 10:10:10", "CE 2007 11 20 10:10:10", "hmv", "10.11.2007, 10:10\\u202FAM Los Angeles (Ortszeit)\\u2009\\u2013\\u200920.11.2007, 10:10\\u202FAM Los Angeles (Ortszeit)",
970
971 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
972
973
974 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "dMMM", "10. Jan.",
975
976 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "MMMy", "Jan. 2007",
977
978 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
979
980 /* Following is an important test, because the 'h' in 'Uhr' is interpreted as a pattern
981 if not escaped properly. */
982 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "h", "10 Uhr AM\\u2009\\u2013\\u20092 Uhr PM",
983 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 14:10:10", "H", "10\\u201314 Uhr",
984
985 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "EEEEdMMM", "Mittwoch, 10. Jan.",
986
987
988 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmv", "10:00\\u201310:20\\u202FAM Los Angeles (Ortszeit)",
989
990 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hmz", "10:00\\u201310:20\\u202FAM GMT-8",
991
992 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "h", "10 Uhr AM",
993 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "H", "10 Uhr",
994
995
996 "de", "CE 2007 01 10 10:00:10", "CE 2007 01 10 10:20:10", "hz", "10 Uhr AM GMT-8",
997
998 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "EEEEdMMMy", "Mittwoch, 10. Jan. 2007",
999
1000
1001 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmv", "10:10\\u202FAM Los Angeles (Ortszeit)",
1002
1003 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hmz", "10:10\\u202FAM GMT-8",
1004
1005
1006 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hv", "10 Uhr AM Los Angeles (Ortszeit)",
1007
1008 "de", "CE 2007 01 10 10:10:10", "CE 2007 01 10 10:10:20", "hz", "10 Uhr AM GMT-8",
1009
1010 // Thai (default calendar buddhist)
1011
1012 "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",
1013
1014
1015 "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",
1016
1017 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "MMMy", "\\u0E15.\\u0E04. 2550 \\u2013 \\u0E15.\\u0E04. 2551",
1018
1019
1020 "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",
1021
1022 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "dMy", "10/10/2550 \\u2013 10/10/2551",
1023
1024
1025 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "My", "10/2550 \\u2013 10/2551",
1026
1027 "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",
1028
1029
1030 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "y", "2550\\u20132551",
1031
1032 "th", "BE 2550 10 10 10:10:10", "BE 2551 10 10 10:10:10", "M", "10/2550 \\u2013 10/2551",
1033
1034
1035 "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",
1036
1037
1038 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "dMMM", "10 \\u0E15.\\u0E04. \\u2013 10 \\u0E1E.\\u0E22.",
1039
1040 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "MMMy", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22. 2550",
1041
1042 "th", "2550 10 10 10:10:10", "2550 11 10 10:10:10", "dM", "10/10 \\u2013 10/11",
1043
1044 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "My", "10/2550 \\u2013 11/2550",
1045
1046
1047 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "d", "10/10 \\u2013 10/11",
1048
1049 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "y", "\\u0E1E.\\u0E28. 2550",
1050
1051
1052 "th", "BE 2550 10 10 10:10:10", "BE 2550 11 10 10:10:10", "MMM", "\\u0E15.\\u0E04.\\u2013\\u0E1E.\\u0E22.",
1053
1054 // Tests for Japanese calendar with eras, including new era in 2019 (Heisei 31 through April 30, then new era)
1055
1056 "en-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GyMMMd", "Mar 15\\u2009\\u2013\\u2009Apr 15, 31 Heisei",
1057
1058 "en-u-ca-japanese", "H 31 03 15 09:00:00", "H 31 04 15 09:00:00", "GGGGGyMd", "3/15/31\\u2009\\u2013\\u20094/15/31 H",
1059
1060 "en-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GyMMMd", "Jan 5, 64 Sh\\u014Dwa\\u2009\\u2013\\u2009Jan 15, 1 Heisei",
1061
1062 "en-u-ca-japanese", "S 64 01 05 09:00:00", "H 1 01 15 09:00:00", "GGGGGyMd", "1/5/64 S\\u2009\\u2013\\u20091/15/1 H",
1063
1064 "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\\u2009\\u2013\\u2009May 15, 1 " JP_ERA_2019_ROOT,
1065
1066 "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\\u2009\\u2013\\u20095/15/1 " JP_ERA_2019_NARROW,
1067
1068
1069 "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",
1070
1071 "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",
1072
1073 "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",
1074
1075 "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",
1076
1077 "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",
1078
1079 };
1080 expect(DATA, UPRV_LENGTHOF(DATA));
1081 }
1082
1083
1084 /**
1085 * Test handling of hour and day period metacharacters
1086 */
testHourMetacharacters()1087 void DateIntervalFormatTest::testHourMetacharacters() {
1088 // first item is date pattern
1089 // followed by a group of locale/from_data/to_data/skeleton/interval_data
1090 // Note that from_data/to_data are specified using era names from root, for the calendar specified by locale.
1091 const char* DATA[] = {
1092 "GGGGG y MM dd HH:mm:ss", // pattern for from_data/to_data
1093
1094 // This test is for tickets ICU-21154, ICU-21155, and ICU-21156 and is intended to verify
1095 // that all of the special skeleton characters for hours and day periods work as expected
1096 // with date intervals:
1097 // - If a, b, or B is included in the skeleton, it correctly sets the length of the day-period field
1098 // - If k or K is included, it behaves the same as H or h, except for the difference in the actual
1099 // number used for the hour.
1100 // - If j is included, it behaves the same as either h or H as appropriate, and multiple j's have the
1101 // intended effect on the length of the day period field (if there is one)
1102 // - If J is included, it correctly suppresses the day period field if j would include it
1103 // - If C is included, it behaves the same as j and brings up the correct day period field
1104 // - In all cases, if the day period of both ends of the range is the same, you only see it once
1105
1106 // baseline (h and H)
1107 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12\\u2009\\u2013\\u20091\\u202FAM",
1108 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "00\\u201301 Uhr",
1109
1110 // k and K (ICU-21154 and ICU-21156)
1111 // (should behave the same as h and H if not overridden in locale ID)
1112 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12\\u2009\\u2013\\u20091\\u202FAM",
1113 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "00\\u201301 Uhr",
1114 // (overriding hour cycle in locale ID should affect both h and K [or both H and k])
1115 "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "0\\u2009\\u2013\\u20091\\u202FAM",
1116 "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "0\\u2009\\u2013\\u20091\\u202FAM",
1117 "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "24\\u201301 Uhr",
1118 "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "24\\u201301 Uhr",
1119 // (overriding hour cycle to h11 should NOT affect H and k; overriding to h24 should NOT affect h and K)
1120 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "00\\u2009\\u2013\\u200901",
1121 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "00\\u2009\\u2013\\u200901",
1122 "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "00\\u2009\\u2013\\u200901",
1123 "en-u-hc-h11", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "00\\u2009\\u2013\\u200901",
1124 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12\\u2009\\u2013\\u20091 Uhr AM",
1125 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12\\u2009\\u2013\\u20091 Uhr AM",
1126 "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12\\u2009\\u2013\\u20091 Uhr AM",
1127 "de-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12\\u2009\\u2013\\u20091 Uhr AM",
1128
1129 // different lengths of the 'a' field
1130 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "ha", "10\\u202FAM\\u2009\\u2013\\u20091\\u202FPM",
1131 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "ha", "12\\u2009\\u2013\\u20091\\u202FAM",
1132 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 12:00:00", "haaaaa", "10\\u202Fa\\u2009\\u2013\\u200912\\u202Fp",
1133 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "haaaaa", "12\\u2009\\u2013\\u20091\\u202Fa",
1134
1135 // j (ICU-21155)
1136 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jj", "10\\u202FAM\\u2009\\u2013\\u20091\\u202FPM",
1137 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "12\\u2009\\u2013\\u20091\\u202FAM",
1138 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jjjjj", "10\\u202Fa\\u2009\\u2013\\u20091\\u202Fp",
1139 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jjjjj", "12\\u2009\\u2013\\u20091\\u202Fa",
1140 "de", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jj", "10\\u201313 Uhr",
1141 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "00\\u201301 Uhr",
1142 "de", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jjjjj", "10\\u201313 Uhr",
1143 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jjjjj", "00\\u201301 Uhr",
1144
1145 // b and B
1146 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 12:00:00", "hb", "10\\u202FAM\\u2009\\u2013\\u200912\\u202Fnoon",
1147 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 12:00:00", "hbbbbb", "10\\u202Fa\\u2009\\u2013\\u200912\\u202Fn",
1148 "en", "CE 2010 09 27 13:00:00", "CE 2010 09 27 14:00:00", "hb", "1\\u2009\\u2013\\u20092\\u202FPM",
1149 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "hB", "10 in the morning\\u2009\\u2013\\u20091 in the afternoon",
1150 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hB", "12\\u2009\\u2013\\u20091 at night",
1151
1152 // J
1153 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "J", "10\\u2009\\u2013\\u20091",
1154 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "J", "12\\u2009\\u2013\\u20091",
1155 "de", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "J", "10\\u201313 Uhr",
1156 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "J", "00\\u201301 Uhr",
1157
1158 // C
1159 // (for English and German, C should do the same thing as j)
1160 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CC", "10\\u202FAM\\u2009\\u2013\\u20091\\u202FPM",
1161 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "CC", "12\\u2009\\u2013\\u20091\\u202FAM",
1162 "en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CCCCC", "10\\u202Fa\\u2009\\u2013\\u20091\\u202Fp",
1163 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "CCCCC", "12\\u2009\\u2013\\u20091\\u202Fa",
1164 "de", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CC", "10\\u201313 Uhr",
1165 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "CC", "00\\u201301 Uhr",
1166 "de", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CCCCC", "10\\u201313 Uhr",
1167 "de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "CCCCC", "00\\u201301 Uhr",
1168 // (for zh_HK and hi_IN, j maps to ha, but C maps to hB)
1169 "zh_HK", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jj", "\\u4E0A\\u534810\\u6642\\u81F3\\u4E0B\\u53481\\u6642",
1170 "zh_HK", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "\\u4E0A\\u534812\\u6642\\u81F31\\u6642",
1171 "zh_HK", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "hB", "\\u4E0A\\u534810\\u6642 \\u2013 \\u4E0B\\u53481\\u6642",
1172 "zh_HK", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hB", "\\u51CC\\u666812\\u20131\\u6642",
1173 "zh_HK", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CC", "\\u4E0A\\u534810\\u6642\\u81F3\\u4E0B\\u53481\\u6642",
1174 "zh_HK", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "CC", "\\u4E0A\\u534812\\u6642\\u81F31\\u6642",
1175 "hi_IN", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jj", "10 am \\u2013 1 pm",
1176 "hi_IN", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "12\\u20131 am",
1177 "hi_IN", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "hB", "\\u0938\\u0941\\u092C\\u0939 10 \\u2013 \\u0926\\u094B\\u092A\\u0939\\u0930 1",
1178 "hi_IN", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hB", "\\u0930\\u093E\\u0924 12\\u20131",
1179 "hi_IN", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CC", "\\u0938\\u0941\\u092C\\u0939 10 \\u2013 \\u0926\\u094B\\u092A\\u0939\\u0930 1",
1180 "hi_IN", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "CC", "\\u0930\\u093E\\u0924 12\\u20131",
1181
1182 // regression test for ICU-21342
1183 "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 10:00:00", "kk", "24\\u201310",
1184 "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 11:00:00", "kk", "24\\u201311",
1185 "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 12:00:00", "kk", "24\\u201312",
1186 "en-gb-u-hc-h24", "CE 2010 09 27 00:00:00", "CE 2010 09 27 13:00:00", "kk", "24\\u201313",
1187
1188 // regression test for ICU-21343
1189 "de", "CE 2010 09 27 01:00:00", "CE 2010 09 27 10:00:00", "KK", "1\\u2009\\u2013\\u200910 Uhr AM",
1190
1191 // regression test for ICU-21154 (single-date ranges should use the same hour cycle as multi-date ranges)
1192 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "hh", "12\\u202FAM",
1193 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12\\u2009\\u2013\\u20091\\u202FAM",
1194 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "KK", "12\\u202FAM",
1195 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12\\u2009\\u2013\\u20091\\u202FAM", // (this was producing "0 - 1\\u202FAM" before)
1196 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "jj", "12\\u202FAM",
1197 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "12\\u2009\\u2013\\u20091\\u202FAM",
1198
1199 // regression test for ICU-21984 (multiple day-period characters in date-interval patterns)
1200 "en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "MMMdhhmma", "Sep 27, 12:00\\u2009\\u2013\\u20091:00\\u202FAM",
1201 "sq", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "Bhm", "12:00\\u2009\\u2013\\u20091:00 e nat\\u00EBs",
1202 };
1203 expect(DATA, UPRV_LENGTHOF(DATA));
1204 }
1205
1206
expect(const char ** data,int32_t data_length)1207 void DateIntervalFormatTest::expect(const char** data, int32_t data_length) {
1208 int32_t i = 0;
1209 UErrorCode ec = U_ZERO_ERROR;
1210 UnicodeString str, str2;
1211 const char* pattern = data[i++];
1212
1213 while (i<data_length) {
1214 const char* locName = data[i++];
1215 const char* datestr = data[i++];
1216 const char* datestr_2 = data[i++];
1217
1218 Locale loc(locName);
1219 LocalPointer<Calendar> defCal(Calendar::createInstance(loc, ec));
1220 if (U_FAILURE(ec)) {
1221 dataerrln("Calendar::createInstance fails for loc %s with: %s", locName, u_errorName(ec));
1222 return;
1223 }
1224 const char* calType = defCal->getType();
1225
1226 Locale refLoc("root");
1227 if (calType) {
1228 refLoc.setKeywordValue("calendar", calType, ec);
1229 }
1230 SimpleDateFormat ref(pattern, refLoc, ec);
1231 logln( "case %d, locale: %s\n", (i-1)/5, locName);
1232 if (U_FAILURE(ec)) {
1233 dataerrln("contruct SimpleDateFormat in expect failed: %s", u_errorName(ec));
1234 return;
1235 }
1236
1237 // 'f'
1238 logln("original date: %s - %s\n", datestr, datestr_2);
1239 UDate date = ref.parse(ctou(datestr), ec);
1240 if (!assertSuccess("parse 1st data in expect", ec)) return;
1241 UDate date_2 = ref.parse(ctou(datestr_2), ec);
1242 if (!assertSuccess("parse 2nd data in expect", ec)) return;
1243 DateInterval dtitv(date, date_2);
1244
1245 const UnicodeString& oneSkeleton(ctou(data[i++]));
1246
1247 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(oneSkeleton, loc, ec);
1248 if (!assertSuccess("createInstance(skeleton) in expect", ec)) return;
1249 FieldPosition pos(FieldPosition::DONT_CARE);
1250 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1251 if (!assertSuccess("format in expect", ec)) return;
1252 assertEquals((UnicodeString)"\"" + locName + "\\" + oneSkeleton + "\\" + ctou(datestr) + "\\" + ctou(datestr_2) + "\"", ctou(data[i++]), str);
1253
1254 logln("interval date:" + str + "\"" + locName + "\", "
1255 + "\"" + datestr + "\", "
1256 + "\"" + datestr_2 + "\", " + oneSkeleton);
1257 delete dtitvfmt;
1258 }
1259 }
1260
1261
1262 /*
1263 * Test format using user defined DateIntervalInfo
1264 */
testFormatUserDII()1265 void DateIntervalFormatTest::testFormatUserDII() {
1266 // first item is date pattern
1267 const char* DATA[] = {
1268 "yyyy MM dd HH:mm:ss",
1269 "en", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "Oct 10, 2007 --- Oct 10, 2008",
1270
1271 "en", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 Oct 10 - Nov 2007",
1272
1273 "en", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "Nov 10, 2007 --- Nov 20, 2007",
1274
1275 "en", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "Jan 10, 2007",
1276
1277 "en", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "Jan 10, 2007",
1278
1279 "en", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "Jan 10, 2007",
1280
1281 "zh", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "2007\\u5e7410\\u670810\\u65e5 --- 2008\\u5e7410\\u670810\\u65e5",
1282
1283 "zh", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 10\\u6708 10 - 11\\u6708 2007",
1284
1285 "zh", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "2007\\u5e7411\\u670810\\u65e5 --- 2007\\u5e7411\\u670820\\u65e5",
1286
1287 "zh", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1288
1289 "zh", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1290
1291 "zh", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "2007\\u5e741\\u670810\\u65e5", // (fixed expected result per ticket:6626:)
1292
1293 "de", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "10. Okt. 2007 --- 10. Okt. 2008",
1294
1295
1296 "de", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "10. Nov. 2007 --- 20. Nov. 2007",
1297
1298 "de", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "10. Jan. 2007",
1299
1300 "de", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "10. Jan. 2007",
1301
1302
1303 "es", "2007 10 10 10:10:10", "2008 10 10 10:10:10", "10 oct 2007 --- 10 oct 2008",
1304
1305 "es", "2007 10 10 10:10:10", "2007 11 10 10:10:10", "2007 oct 10 - nov 2007",
1306
1307 "es", "2007 11 10 10:10:10", "2007 11 20 10:10:10", "10 nov 2007 --- 20 nov 2007",
1308
1309 "es", "2007 01 10 10:00:10", "2007 01 10 14:10:10", "10 ene 2007",
1310
1311 "es", "2007 01 10 10:00:10", "2007 01 10 10:20:10", "10 ene 2007",
1312
1313 "es", "2007 01 10 10:10:10", "2007 01 10 10:10:20", "10 ene 2007",
1314 };
1315 expectUserDII(DATA, UPRV_LENGTHOF(DATA));
1316 }
1317
1318 /*
1319 * Test format using UDisplayContext
1320 */
1321 #define CAP_NONE UDISPCTX_CAPITALIZATION_NONE
1322 #define CAP_BEGIN UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
1323 #define CAP_LIST UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
1324 #define CAP_ALONE UDISPCTX_CAPITALIZATION_FOR_STANDALONE
1325 #define _DAY (24.0*60.0*60.0*1000.0)
1326
testContext()1327 void DateIntervalFormatTest::testContext() {
1328 static const UDate startDate = 1285599629000.0; // 2010-Sep-27 0800 in America/Los_Angeles
1329 typedef struct {
1330 const char * locale;
1331 const char * skeleton;
1332 UDisplayContext context;
1333 const UDate deltaDate;
1334 const UChar* expectResult;
1335 } DateIntervalContextItem;
1336 static const DateIntervalContextItem testItems[] = {
1337 { "cs", "MMMEd", CAP_NONE, 60.0*_DAY, u"po 27. 9. – pá 26. 11." },
1338 { "cs", "yMMMM", CAP_NONE, 60.0*_DAY, u"září–listopad 2010" },
1339 { "cs", "yMMMM", CAP_NONE, 1.0*_DAY, u"září 2010" },
1340 #if !UCONFIG_NO_BREAK_ITERATION
1341 { "cs", "MMMEd", CAP_BEGIN, 60.0*_DAY, u"Po 27. 9. – pá 26. 11." },
1342 { "cs", "yMMMM", CAP_BEGIN, 60.0*_DAY, u"Září–listopad 2010" },
1343 { "cs", "yMMMM", CAP_BEGIN, 1.0*_DAY, u"Září 2010" },
1344 { "cs", "MMMEd", CAP_LIST, 60.0*_DAY, u"Po 27. 9. – pá 26. 11." },
1345 { "cs", "yMMMM", CAP_LIST, 60.0*_DAY, u"Září–listopad 2010" },
1346 { "cs", "yMMMM", CAP_LIST, 1.0*_DAY, u"Září 2010" },
1347 #endif
1348 { "cs", "MMMEd", CAP_ALONE, 60.0*_DAY, u"po 27. 9. – pá 26. 11." },
1349 { "cs", "yMMMM", CAP_ALONE, 60.0*_DAY, u"září–listopad 2010" },
1350 { "cs", "yMMMM", CAP_ALONE, 1.0*_DAY, u"září 2010" },
1351 { nullptr, nullptr, CAP_NONE, 0, nullptr }
1352 };
1353 const DateIntervalContextItem* testItemPtr;
1354 for ( testItemPtr = testItems; testItemPtr->locale != nullptr; ++testItemPtr ) {
1355 UErrorCode status = U_ZERO_ERROR;
1356 Locale locale(testItemPtr->locale);
1357 UnicodeString skeleton(testItemPtr->skeleton, -1, US_INV);
1358 LocalPointer<DateIntervalFormat> fmt(DateIntervalFormat::createInstance(skeleton, locale, status));
1359 if (U_FAILURE(status)) {
1360 errln("createInstance failed for locale %s skeleton %s: %s",
1361 testItemPtr->locale, testItemPtr->skeleton, u_errorName(status));
1362 continue;
1363 }
1364 fmt->adoptTimeZone(TimeZone::createTimeZone("America/Los_Angeles"));
1365
1366 fmt->setContext(testItemPtr->context, status);
1367 if (U_FAILURE(status)) {
1368 errln("setContext failed for locale %s skeleton %s context %04X: %s",
1369 testItemPtr->locale, testItemPtr->skeleton, (unsigned)testItemPtr->context, u_errorName(status));
1370 } else {
1371 UDisplayContext getContext = fmt->getContext(UDISPCTX_TYPE_CAPITALIZATION, status);
1372 if (U_FAILURE(status)) {
1373 errln("getContext failed for locale %s skeleton %s context %04X: %s",
1374 testItemPtr->locale, testItemPtr->skeleton, (unsigned)testItemPtr->context, u_errorName(status));
1375 } else if (getContext != testItemPtr->context) {
1376 errln("getContext failed for locale %s skeleton %s context %04X: got context %04X",
1377 testItemPtr->locale, testItemPtr->skeleton, (unsigned)testItemPtr->context, (unsigned)getContext);
1378 }
1379 }
1380
1381 status = U_ZERO_ERROR;
1382 DateInterval interval(startDate, startDate + testItemPtr->deltaDate);
1383 UnicodeString getResult;
1384 FieldPosition pos(FieldPosition::DONT_CARE);
1385 fmt->format(&interval, getResult, pos, status);
1386 if (U_FAILURE(status)) {
1387 errln("format failed for locale %s skeleton %s context %04X: %s",
1388 testItemPtr->locale, testItemPtr->skeleton, (unsigned)testItemPtr->context, u_errorName(status));
1389 continue;
1390 }
1391 UnicodeString expectResult(true, testItemPtr->expectResult, -1);
1392 if (getResult != expectResult) {
1393 errln(UnicodeString("format expected ") + expectResult + UnicodeString(" but got ") + getResult);
1394 }
1395 }
1396 }
1397
testSetIntervalPatternNoSideEffect()1398 void DateIntervalFormatTest::testSetIntervalPatternNoSideEffect() {
1399 UErrorCode ec = U_ZERO_ERROR;
1400 LocalPointer<DateIntervalInfo> dtitvinf(new DateIntervalInfo(ec), ec);
1401 if (U_FAILURE(ec)) {
1402 errln("Failure encountered: %s", u_errorName(ec));
1403 return;
1404 }
1405 UnicodeString expected;
1406 dtitvinf->getIntervalPattern(ctou("yMd"), UCAL_DATE, expected, ec);
1407 dtitvinf->setIntervalPattern(ctou("yMd"), UCAL_DATE, ctou("M/d/y\\u2009\\u2013\\u2009d"), ec);
1408 if (U_FAILURE(ec)) {
1409 errln("Failure encountered: %s", u_errorName(ec));
1410 return;
1411 }
1412 dtitvinf.adoptInsteadAndCheckErrorCode(new DateIntervalInfo(ec), ec);
1413 if (U_FAILURE(ec)) {
1414 errln("Failure encountered: %s", u_errorName(ec));
1415 return;
1416 }
1417 UnicodeString actual;
1418 dtitvinf->getIntervalPattern(ctou("yMd"), UCAL_DATE, actual, ec);
1419 if (U_FAILURE(ec)) {
1420 errln("Failure encountered: %s", u_errorName(ec));
1421 return;
1422 }
1423 if (expected != actual) {
1424 errln("DateIntervalInfo.setIntervalPattern should have no side effects.");
1425 }
1426 }
1427
testYearFormats()1428 void DateIntervalFormatTest::testYearFormats() {
1429 const Locale &enLocale = Locale::getEnglish();
1430 UErrorCode status = U_ZERO_ERROR;
1431 LocalPointer<Calendar> fromTime(Calendar::createInstance(enLocale, status));
1432 LocalPointer<Calendar> toTime(Calendar::createInstance(enLocale, status));
1433 if (U_FAILURE(status)) {
1434 errln("Failure encountered: %s", u_errorName(status));
1435 return;
1436 }
1437 // April 26, 113. Three digit year so that we can test 2 digit years;
1438 // 4 digit years with padded 0's and full years.
1439 fromTime->set(113, 3, 26);
1440 // April 28, 113.
1441 toTime->set(113, 3, 28);
1442 {
1443 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yyyyMd", enLocale, status));
1444 if (U_FAILURE(status)) {
1445 dataerrln("Failure encountered: %s", u_errorName(status));
1446 return;
1447 }
1448 UnicodeString actual;
1449 UnicodeString expected(ctou("4/26/0113\\u2009\\u2013\\u20094/28/0113"));
1450 FieldPosition pos;
1451 dif->format(*fromTime, *toTime, actual, pos, status);
1452 if (U_FAILURE(status)) {
1453 errln("Failure encountered: %s", u_errorName(status));
1454 return;
1455 }
1456 if (actual != expected) {
1457 errln("Expected " + expected + ", got: " + actual);
1458 }
1459 }
1460 {
1461 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yyMd", enLocale, status));
1462 if (U_FAILURE(status)) {
1463 errln("Failure encountered: %s", u_errorName(status));
1464 return;
1465 }
1466 UnicodeString actual;
1467 UnicodeString expected(ctou("4/26/13\\u2009\\u2013\\u20094/28/13"));
1468 FieldPosition pos(FieldPosition::DONT_CARE);
1469 dif->format(*fromTime, *toTime, actual, pos, status);
1470 if (U_FAILURE(status)) {
1471 errln("Failure encountered: %s", u_errorName(status));
1472 return;
1473 }
1474 if (actual != expected) {
1475 errln("Expected " + expected + ", got: " + actual);
1476 }
1477 }
1478 {
1479 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance("yMd", enLocale, status));
1480 if (U_FAILURE(status)) {
1481 errln("Failure encountered: %s", u_errorName(status));
1482 return;
1483 }
1484 UnicodeString actual;
1485 UnicodeString expected(ctou("4/26/113\\u2009\\u2013\\u20094/28/113"));
1486 FieldPosition pos(FieldPosition::DONT_CARE);
1487 dif->format(*fromTime, *toTime, actual, pos, status);
1488 if (U_FAILURE(status)) {
1489 errln("Failure encountered: %s", u_errorName(status));
1490 return;
1491 }
1492 if (actual != expected) {
1493 errln("Expected " + expected + ", got: " + actual);
1494 }
1495 }
1496 }
1497
expectUserDII(const char ** data,int32_t data_length)1498 void DateIntervalFormatTest::expectUserDII(const char** data,
1499 int32_t data_length) {
1500 int32_t i = 0;
1501 UnicodeString str;
1502 UErrorCode ec = U_ZERO_ERROR;
1503 const char* pattern = data[0];
1504 i++;
1505
1506 while ( i < data_length ) {
1507 const char* locName = data[i++];
1508 Locale loc(locName);
1509 SimpleDateFormat ref(pattern, loc, ec);
1510 if (U_FAILURE(ec)) {
1511 dataerrln("contruct SimpleDateFormat in expectUserDII failed: %s", u_errorName(ec));
1512 return;
1513 }
1514 const char* datestr = data[i++];
1515 const char* datestr_2 = data[i++];
1516 UDate date = ref.parse(ctou(datestr), ec);
1517 if (!assertSuccess("parse in expectUserDII", ec)) return;
1518 UDate date_2 = ref.parse(ctou(datestr_2), ec);
1519 if (!assertSuccess("parse in expectUserDII", ec)) return;
1520 DateInterval dtitv(date, date_2);
1521
1522 ec = U_ZERO_ERROR;
1523 // test user created DateIntervalInfo
1524 DateIntervalInfo* dtitvinf = new DateIntervalInfo(ec);
1525 dtitvinf->setFallbackIntervalPattern("{0} --- {1}", ec);
1526 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_MONTH, "yyyy MMM d - MMM y",ec);
1527 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1528 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_HOUR_OF_DAY, "yyyy MMM d HH:mm - HH:mm", ec);
1529 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1530 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_ABBR_MONTH_DAY, loc, *dtitvinf, ec);
1531 delete dtitvinf;
1532 if (!assertSuccess("createInstance(skeleton,dtitvinf) in expectUserDII", ec)) return;
1533 FieldPosition pos(FieldPosition::DONT_CARE);
1534 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1535 if (!assertSuccess("format in expectUserDII", ec)) return;
1536 assertEquals((UnicodeString)"\"" + locName + "\\" + datestr + "\\" + datestr_2 + "\"", ctou(data[i++]), str);
1537 #ifdef DTIFMTTS_DEBUG
1538 char result[1000];
1539 char mesg[1000];
1540 PRINTMESG("interval format using user defined DateIntervalInfo\n");
1541 str.extract(0, str.length(), result, "UTF-8");
1542 sprintf(mesg, "interval date: %s\n", result);
1543 PRINTMESG(mesg);
1544 #endif
1545 delete dtitvfmt;
1546 }
1547 }
1548
1549
testStress()1550 void DateIntervalFormatTest::testStress() {
1551 if(quick){
1552 logln("Quick mode: Skipping test");
1553 return;
1554 }
1555 const char* DATA[] = {
1556 "yyyy MM dd HH:mm:ss",
1557 "2007 10 10 10:10:10", "2008 10 10 10:10:10",
1558 "2007 10 10 10:10:10", "2007 11 10 10:10:10",
1559 "2007 11 10 10:10:10", "2007 11 20 10:10:10",
1560 "2007 01 10 10:00:10", "2007 01 10 14:10:10",
1561 "2007 01 10 10:00:10", "2007 01 10 10:20:10",
1562 "2007 01 10 10:10:10", "2007 01 10 10:10:20",
1563 };
1564
1565 const char* testLocale[][3] = {
1566 //{"th", "", ""},
1567 {"en", "", ""},
1568 {"zh", "", ""},
1569 {"de", "", ""},
1570 {"ar", "", ""},
1571 {"en", "GB", ""},
1572 {"fr", "", ""},
1573 {"it", "", ""},
1574 {"nl", "", ""},
1575 {"zh", "TW", ""},
1576 {"ja", "", ""},
1577 {"pt", "BR", ""},
1578 {"ru", "", ""},
1579 {"pl", "", ""},
1580 {"tr", "", ""},
1581 {"es", "", ""},
1582 {"ko", "", ""},
1583 {"sv", "", ""},
1584 {"fi", "", ""},
1585 {"da", "", ""},
1586 {"pt", "PT", ""},
1587 {"ro", "", ""},
1588 {"hu", "", ""},
1589 {"he", "", ""},
1590 {"in", "", ""},
1591 {"cs", "", ""},
1592 {"el", "", ""},
1593 {"no", "", ""},
1594 {"vi", "", ""},
1595 {"bg", "", ""},
1596 {"hr", "", ""},
1597 {"lt", "", ""},
1598 {"sk", "", ""},
1599 {"sl", "", ""},
1600 {"sr", "", ""},
1601 {"ca", "", ""},
1602 {"lv", "", ""},
1603 {"uk", "", ""},
1604 {"hi", "", ""},
1605 };
1606
1607 uint32_t localeIndex;
1608 for ( localeIndex = 0; localeIndex < UPRV_LENGTHOF(testLocale); ++localeIndex ) {
1609 char locName[32];
1610 uprv_strcpy(locName, testLocale[localeIndex][0]);
1611 uprv_strcat(locName, testLocale[localeIndex][1]);
1612 stress(DATA, UPRV_LENGTHOF(DATA), Locale(testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2]), locName);
1613 }
1614 }
1615
1616
stress(const char ** data,int32_t data_length,const Locale & loc,const char * locName)1617 void DateIntervalFormatTest::stress(const char** data, int32_t data_length,
1618 const Locale& loc, const char* locName) {
1619 UnicodeString skeleton[] = {
1620 "EEEEdMMMMy",
1621 "dMMMMy",
1622 "dMMMM",
1623 "MMMMy",
1624 "EEEEdMMMM",
1625 "EdMMMy",
1626 "dMMMy",
1627 "dMMM",
1628 "MMMy",
1629 "EdMMM",
1630 "EdMy",
1631 "dMy",
1632 "dM",
1633 "My",
1634 "EdM",
1635 "d",
1636 "Ed",
1637 "y",
1638 "M",
1639 "MMM",
1640 "MMMM",
1641 "hm",
1642 "hmv",
1643 "hmz",
1644 "h",
1645 "hv",
1646 "hz",
1647 "EEddMMyyyy", // following could be normalized
1648 "EddMMy",
1649 "hhmm",
1650 "hhmmzz",
1651 "hms", // following could not be normalized
1652 "dMMMMMy",
1653 "EEEEEdM",
1654 };
1655
1656 int32_t i = 0;
1657 UErrorCode ec = U_ZERO_ERROR;
1658 UnicodeString str, str2;
1659 SimpleDateFormat ref(data[i++], loc, ec);
1660 if (!assertSuccess("construct SimpleDateFormat", ec)) return;
1661
1662 #ifdef DTIFMTTS_DEBUG
1663 char result[1000];
1664 char mesg[1000];
1665 sprintf(mesg, "locale: %s\n", locName);
1666 PRINTMESG(mesg);
1667 #endif
1668
1669 while (i<data_length) {
1670
1671 // 'f'
1672 const char* datestr = data[i++];
1673 const char* datestr_2 = data[i++];
1674 #ifdef DTIFMTTS_DEBUG
1675 sprintf(mesg, "original date: %s - %s\n", datestr, datestr_2);
1676 PRINTMESG(mesg)
1677 #endif
1678 UDate date = ref.parse(ctou(datestr), ec);
1679 if (!assertSuccess("parse", ec)) return;
1680 UDate date_2 = ref.parse(ctou(datestr_2), ec);
1681 if (!assertSuccess("parse", ec)) return;
1682 DateInterval dtitv(date, date_2);
1683
1684 for ( uint32_t skeletonIndex = 0;
1685 skeletonIndex < UPRV_LENGTHOF(skeleton);
1686 ++skeletonIndex ) {
1687 const UnicodeString& oneSkeleton = skeleton[skeletonIndex];
1688 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(oneSkeleton, loc, ec);
1689 if (!assertSuccess("createInstance(skeleton)", ec)) return;
1690 /*
1691 // reset the calendar to be Gregorian calendar for "th"
1692 if ( uprv_strcmp(locName, "th") == 0 ) {
1693 GregorianCalendar* gregCal = new GregorianCalendar(loc, ec);
1694 if (!assertSuccess("GregorianCalendar()", ec)) return;
1695 const DateFormat* dformat = dtitvfmt->getDateFormat();
1696 DateFormat* newOne = dformat->clone();
1697 newOne->adoptCalendar(gregCal);
1698 //dtitvfmt->adoptDateFormat(newOne, ec);
1699 dtitvfmt->setDateFormat(*newOne, ec);
1700 delete newOne;
1701 if (!assertSuccess("adoptDateFormat()", ec)) return;
1702 }
1703 */
1704 FieldPosition pos(FieldPosition::DONT_CARE);
1705 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1706 if (!assertSuccess("format", ec)) return;
1707 #ifdef DTIFMTTS_DEBUG
1708 oneSkeleton.extract(0, oneSkeleton.length(), result, "UTF-8");
1709 sprintf(mesg, "interval by skeleton: %s\n", result);
1710 PRINTMESG(mesg)
1711 str.extract(0, str.length(), result, "UTF-8");
1712 sprintf(mesg, "interval date: %s\n", result);
1713 PRINTMESG(mesg)
1714 #endif
1715 delete dtitvfmt;
1716 }
1717
1718 // test user created DateIntervalInfo
1719 ec = U_ZERO_ERROR;
1720 DateIntervalInfo* dtitvinf = new DateIntervalInfo(ec);
1721 dtitvinf->setFallbackIntervalPattern("{0} --- {1}", ec);
1722 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_MONTH, "yyyy MMM d - MMM y",ec);
1723 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1724 dtitvinf->setIntervalPattern(UDAT_YEAR_ABBR_MONTH_DAY, UCAL_HOUR_OF_DAY, "yyyy MMM d HH:mm - HH:mm", ec);
1725 if (!assertSuccess("DateIntervalInfo::setIntervalPattern", ec)) return;
1726 DateIntervalFormat* dtitvfmt = DateIntervalFormat::createInstance(UDAT_YEAR_ABBR_MONTH_DAY, loc, *dtitvinf, ec);
1727 delete dtitvinf;
1728 if (!assertSuccess("createInstance(skeleton,dtitvinf)", ec)) return;
1729 FieldPosition pos(FieldPosition::DONT_CARE);
1730 dtitvfmt->format(&dtitv, str.remove(), pos, ec);
1731 if ( uprv_strcmp(locName, "th") ) {
1732 if (!assertSuccess("format", ec)) return;
1733 #ifdef DTIFMTTS_DEBUG
1734 PRINTMESG("interval format using user defined DateIntervalInfo\n");
1735 str.extract(0, str.length(), result, "UTF-8");
1736 sprintf(mesg, "interval date: %s\n", result);
1737 PRINTMESG(mesg)
1738 #endif
1739 } else {
1740 // for "th", the default calendar is Budhist,
1741 // not Gregorian.
1742 assertTrue("Default calendar for \"th\" is Budhist", ec == U_ILLEGAL_ARGUMENT_ERROR);
1743 ec = U_ZERO_ERROR;
1744 }
1745 delete dtitvfmt;
1746 }
1747 }
1748
testTicket11583_2()1749 void DateIntervalFormatTest::testTicket11583_2() {
1750 UErrorCode status = U_ZERO_ERROR;
1751 LocalPointer<DateIntervalFormat> fmt(
1752 DateIntervalFormat::createInstance("yMMM", "es-US", status));
1753 if (!assertSuccess("Error create format object", status)) {
1754 return;
1755 }
1756 DateInterval interval((UDate) 1232364615000.0, (UDate) 1328787015000.0);
1757 UnicodeString appendTo;
1758 FieldPosition fpos(FieldPosition::DONT_CARE);
1759 UnicodeString expected("ene de 2009\\u2009\\u2013\\u2009feb de 2012");
1760 assertEquals(
1761 "",
1762 expected.unescape(),
1763 fmt->format(&interval, appendTo, fpos, status));
1764 if (!assertSuccess("Error formatting", status)) {
1765 return;
1766 }
1767 }
1768
1769
testTicket11985()1770 void DateIntervalFormatTest::testTicket11985() {
1771 UErrorCode status = U_ZERO_ERROR;
1772 LocalPointer<DateIntervalFormat> fmt(
1773 DateIntervalFormat::createInstance(UDAT_HOUR_MINUTE, Locale::getEnglish(), status));
1774 if (!assertSuccess("createInstance", status)) {
1775 return;
1776 }
1777 UnicodeString pattern;
1778 static_cast<const SimpleDateFormat*>(fmt->getDateFormat())->toPattern(pattern);
1779 assertEquals("Format pattern", u"h:mm\u202Fa", pattern);
1780 }
1781
1782 // Ticket 11669 - thread safety of DateIntervalFormat::format(). This test failed before
1783 // the implementation was fixed.
1784
1785 static const DateIntervalFormat *gIntervalFormatter = NULL; // The Formatter to be used concurrently by test threads.
1786 static const DateInterval *gInterval = NULL; // The date interval to be formatted concurrently.
1787 static const UnicodeString *gExpectedResult = NULL;
1788
threadFunc11669(int32_t threadNum)1789 void DateIntervalFormatTest::threadFunc11669(int32_t threadNum) {
1790 (void)threadNum;
1791 for (int loop=0; loop<1000; ++loop) {
1792 UErrorCode status = U_ZERO_ERROR;
1793 FieldPosition pos(FieldPosition::DONT_CARE);
1794 UnicodeString result;
1795 gIntervalFormatter->format(gInterval, result, pos, status);
1796 if (U_FAILURE(status)) {
1797 errln("%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1798 return;
1799 }
1800 if (result != *gExpectedResult) {
1801 errln("%s:%d Expected \"%s\", got \"%s\"", __FILE__, __LINE__, CStr(*gExpectedResult)(), CStr(result)());
1802 return;
1803 }
1804 }
1805 }
1806
testTicket11669()1807 void DateIntervalFormatTest::testTicket11669() {
1808 UErrorCode status = U_ZERO_ERROR;
1809 LocalPointer<DateIntervalFormat> formatter(DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getEnglish(), status), status);
1810 LocalPointer<TimeZone> tz(TimeZone::createTimeZone("America/Los_Angleles"), status);
1811 LocalPointer<Calendar> intervalStart(Calendar::createInstance(*tz, Locale::getEnglish(), status), status);
1812 LocalPointer<Calendar> intervalEnd(Calendar::createInstance(*tz, Locale::getEnglish(), status), status);
1813 if (U_FAILURE(status)) {
1814 errcheckln(status, "%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1815 return;
1816 }
1817
1818 intervalStart->set(2009, 6, 1, 14, 0);
1819 intervalEnd->set(2009, 6, 2, 14, 0);
1820 DateInterval interval(intervalStart->getTime(status), intervalEnd->getTime(status));
1821 FieldPosition pos(FieldPosition::DONT_CARE);
1822 UnicodeString expectedResult;
1823 formatter->format(&interval, expectedResult, pos, status);
1824 if (U_FAILURE(status)) {
1825 errln("%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1826 return;
1827 }
1828
1829 gInterval = &interval;
1830 gIntervalFormatter = formatter.getAlias();
1831 gExpectedResult = &expectedResult;
1832
1833 ThreadPool<DateIntervalFormatTest> threads(this, 4, &DateIntervalFormatTest::threadFunc11669);
1834 threads.start();
1835 threads.join();
1836
1837 gInterval = NULL; // Don't leave dangling pointers lying around. Not strictly necessary.
1838 gIntervalFormatter = NULL;
1839 gExpectedResult = NULL;
1840 }
1841
1842
1843 // testTicket12065
1844 // Using a DateIntervalFormat to format shouldn't change its state in any way
1845 // that changes how the behavior of operator ==.
testTicket12065()1846 void DateIntervalFormatTest::testTicket12065() {
1847 UErrorCode status = U_ZERO_ERROR;
1848 LocalPointer<DateIntervalFormat> formatter(DateIntervalFormat::createInstance(UDAT_YEAR_MONTH_DAY, Locale::getEnglish(), status), status);
1849 if (formatter.isNull()) {
1850 dataerrln("FAIL: DateIntervalFormat::createInstance failed for Locale::getEnglish()");
1851 return;
1852 }
1853 LocalPointer<DateIntervalFormat> clone(formatter->clone());
1854 if (*formatter != *clone) {
1855 errln("%s:%d DateIntervalFormat and clone are not equal.", __FILE__, __LINE__);
1856 return;
1857 }
1858 DateInterval interval((UDate) 1232364615000.0, (UDate) 1328787015000.0);
1859 UnicodeString appendTo;
1860 FieldPosition fpos(FieldPosition::DONT_CARE);
1861 formatter->format(&interval, appendTo, fpos, status);
1862 if (*formatter != *clone) {
1863 errln("%s:%d DateIntervalFormat and clone are not equal after formatting.", __FILE__, __LINE__);
1864 return;
1865 }
1866 if (U_FAILURE(status)) {
1867 errln("%s:%d %s", __FILE__, __LINE__, u_errorName(status));
1868 }
1869 }
1870
1871
testFormattedDateInterval()1872 void DateIntervalFormatTest::testFormattedDateInterval() {
1873 IcuTestErrorCode status(*this, "testFormattedDateInterval");
1874 LocalPointer<DateIntervalFormat> fmt(DateIntervalFormat::createInstance(u"dMMMMy", "en-US", status), status);
1875
1876 {
1877 const char16_t* message = u"FormattedDateInterval test 1";
1878 const char16_t* expectedString = u"July 20\u2009\u2013\u200925, 2018";
1879 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1880 if (status.errIfFailureAndReset()) { return; }
1881 LocalPointer<Calendar> input2(Calendar::createInstance("en-GB", status));
1882 if (status.errIfFailureAndReset()) { return; }
1883 input1->set(2018, 6, 20);
1884 input2->set(2018, 6, 25);
1885 FormattedDateInterval result = fmt->formatToValue(*input1, *input2, status);
1886 static const UFieldPositionWithCategory expectedFieldPositions[] = {
1887 // field, begin index, end index
1888 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 0, 4},
1889 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 5, 7},
1890 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 5, 7},
1891 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 10, 12},
1892 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 10, 12},
1893 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 14, 18}};
1894 checkMixedFormattedValue(
1895 message,
1896 result,
1897 expectedString,
1898 expectedFieldPositions,
1899 UPRV_LENGTHOF(expectedFieldPositions));
1900 }
1901
1902 {
1903 const char16_t* message = u"FormattedDateInterval identical dates test: no span field";
1904 const char16_t* expectedString = u"July 20, 2018";
1905 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1906 input1->set(2018, 6, 20);
1907 FormattedDateInterval result = fmt->formatToValue(*input1, *input1, status);
1908 static const UFieldPositionWithCategory expectedFieldPositions[] = {
1909 // field, begin index, end index
1910 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 0, 4},
1911 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 5, 7},
1912 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 9, 13}};
1913 checkMixedFormattedValue(
1914 message,
1915 result,
1916 expectedString,
1917 expectedFieldPositions,
1918 UPRV_LENGTHOF(expectedFieldPositions));
1919 }
1920
1921 // Test sample code
1922 {
1923 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1924 LocalPointer<Calendar> input2(Calendar::createInstance("en-GB", status));
1925 input1->set(2018, 6, 20);
1926 input2->set(2018, 7, 3);
1927
1928 // Let fmt be a DateIntervalFormat for locale en-US and skeleton dMMMMy
1929 // Let input1 be July 20, 2018 and input2 be August 3, 2018:
1930 FormattedDateInterval result = fmt->formatToValue(*input1, *input2, status);
1931 assertEquals("Expected output from format",
1932 u"July 20\u2009\u2013\u2009August 3, 2018", result.toString(status));
1933 ConstrainedFieldPosition cfpos;
1934 cfpos.constrainField(UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0);
1935 if (result.nextPosition(cfpos, status)) {
1936 assertEquals("Expect start index", 0, cfpos.getStart());
1937 assertEquals("Expect end index", 7, cfpos.getLimit());
1938 } else {
1939 // No such span: can happen if input dates are equal.
1940 }
1941 assertFalse("No more than one occurrence of the field",
1942 result.nextPosition(cfpos, status));
1943 }
1944
1945 // To test the fallback pattern behavior, make a custom DateIntervalInfo.
1946 DateIntervalInfo dtitvinf(status);
1947 dtitvinf.setFallbackIntervalPattern("<< {1} --- {0} >>", status);
1948 fmt.adoptInsteadAndCheckErrorCode(
1949 DateIntervalFormat::createInstance(u"dMMMMy", "en-US", dtitvinf, status),
1950 status);
1951
1952 {
1953 const char16_t* message = u"FormattedDateInterval with fallback format test 1";
1954 const char16_t* expectedString = u"<< July 25, 2018 --- July 20, 2018 >>";
1955 LocalPointer<Calendar> input1(Calendar::createInstance("en-GB", status));
1956 if (status.errIfFailureAndReset()) { return; }
1957 LocalPointer<Calendar> input2(Calendar::createInstance("en-GB", status));
1958 if (status.errIfFailureAndReset()) { return; }
1959 input1->set(2018, 6, 20);
1960 input2->set(2018, 6, 25);
1961 FormattedDateInterval result = fmt->formatToValue(*input1, *input2, status);
1962 static const UFieldPositionWithCategory expectedFieldPositions[] = {
1963 // field, begin index, end index
1964 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 1, 3, 16},
1965 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 3, 7},
1966 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 8, 10},
1967 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 12, 16},
1968 {UFIELD_CATEGORY_DATE_INTERVAL_SPAN, 0, 21, 34},
1969 {UFIELD_CATEGORY_DATE, UDAT_MONTH_FIELD, 21, 25},
1970 {UFIELD_CATEGORY_DATE, UDAT_DATE_FIELD, 26, 28},
1971 {UFIELD_CATEGORY_DATE, UDAT_YEAR_FIELD, 30, 34}};
1972 checkMixedFormattedValue(
1973 message,
1974 result,
1975 expectedString,
1976 expectedFieldPositions,
1977 UPRV_LENGTHOF(expectedFieldPositions));
1978 }
1979 }
1980
testCreateInstanceForAllLocales()1981 void DateIntervalFormatTest::testCreateInstanceForAllLocales() {
1982 IcuTestErrorCode status(*this, "testCreateInstanceForAllLocales");
1983 int32_t locale_count = 0;
1984 const Locale* locales = icu::Locale::getAvailableLocales(locale_count);
1985 // Iterate through all locales
1986 for (int32_t i = 0; i < locale_count; i++) {
1987 std::unique_ptr<icu::StringEnumeration> calendars(
1988 icu::Calendar::getKeywordValuesForLocale(
1989 "calendar", locales[i], false, status));
1990 int32_t calendar_count = calendars->count(status);
1991 if (status.errIfFailureAndReset()) { break; }
1992 // In quick mode, only run 1/5 of locale combination
1993 // to make the test run faster.
1994 if (quick && (i % 5 != 0)) continue;
1995 LocalPointer<DateIntervalFormat> fmt(
1996 DateIntervalFormat::createInstance(u"dMMMMy", locales[i], status),
1997 status);
1998 if (status.errIfFailureAndReset(locales[i].getName())) {
1999 continue;
2000 }
2001 // Iterate through all calendars in this locale
2002 for (int32_t j = 0; j < calendar_count; j++) {
2003 // In quick mode, only run 1/7 of locale/calendar combination
2004 // to make the test run faster.
2005 if (quick && ((i * j) % 7 != 0)) continue;
2006 const char* calendar = calendars->next(nullptr, status);
2007 Locale locale(locales[i]);
2008 locale.setKeywordValue("calendar", calendar, status);
2009 fmt.adoptInsteadAndCheckErrorCode(
2010 DateIntervalFormat::createInstance(u"dMMMMy", locale, status),
2011 status);
2012 status.errIfFailureAndReset(locales[i].getName());
2013 }
2014 }
2015 }
2016
testFormatMillisecond()2017 void DateIntervalFormatTest::testFormatMillisecond() {
2018 struct
2019 {
2020 int year;
2021 int month;
2022 int day;
2023 int from_hour;
2024 int from_miniute;
2025 int from_second;
2026 int from_millisecond;
2027 int to_hour;
2028 int to_miniute;
2029 int to_second;
2030 int to_millisecond;
2031 const char* skeleton;
2032 const char16_t* expected;
2033 }
2034 kTestCases [] =
2035 {
2036 // From To
2037 // y m d h m s ms h m s ms skeleton expected
2038 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "ms", u"23:45"},
2039 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "msS", u"23:45.3"},
2040 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "msSS", u"23:45.32"},
2041 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "msSSS", u"23:45.321"},
2042 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "ms", u"23:45"},
2043 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "msS", u"23:45.3\u2009\u2013\u200923:45.9"},
2044 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "msSS", u"23:45.32\u2009\u2013\u200923:45.98"},
2045 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "msSSS", u"23:45.321\u2009\u2013\u200923:45.987"},
2046 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "ms", u"23:45\u2009\u2013\u200923:46"},
2047 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "msS", u"23:45.3\u2009\u2013\u200923:46.9"},
2048 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "msSS", u"23:45.32\u2009\u2013\u200923:46.98"},
2049 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "msSSS", u"23:45.321\u2009\u2013\u200923:46.987"},
2050 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "ms", u"23:45\u2009\u2013\u200924:45"},
2051 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "msS", u"23:45.3\u2009\u2013\u200924:45.9"},
2052 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "msSS", u"23:45.32\u2009\u2013\u200924:45.98"},
2053 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "msSSS", u"23:45.321\u2009\u2013\u200924:45.987"},
2054 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "s", u"45"},
2055 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "sS", u"45.3"},
2056 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "sSS", u"45.32"},
2057 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "sSSS", u"45.321"},
2058 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "s", u"45"},
2059 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "sS", u"45.3\u2009\u2013\u200945.9"},
2060 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "sSS", u"45.32\u2009\u2013\u200945.98"},
2061 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "sSSS", u"45.321\u2009\u2013\u200945.987"},
2062 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "s", u"45\u2009\u2013\u200946"},
2063 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "sS", u"45.3\u2009\u2013\u200946.9"},
2064 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "sSS", u"45.32\u2009\u2013\u200946.98"},
2065 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "sSSS", u"45.321\u2009\u2013\u200946.987"},
2066 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "s", u"45\u2009\u2013\u200945"},
2067 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "sS", u"45.3\u2009\u2013\u200945.9"},
2068 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "sSS", u"45.32\u2009\u2013\u200945.98"},
2069 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "sSSS", u"45.321\u2009\u2013\u200945.987"},
2070 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "S", u"3"},
2071 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "SS", u"32"},
2072 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 321, "SSS", u"321"},
2073
2074 // Same millisecond but in different second.
2075 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 321, "S", u"3\u2009\u2013\u20093"},
2076 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 321, "SS", u"32\u2009\u2013\u200932"},
2077 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 321, "SSS", u"321\u2009\u2013\u2009321"},
2078
2079 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "S", u"3\u2009\u2013\u20099"},
2080 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "SS", u"32\u2009\u2013\u200998"},
2081 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 45, 987, "SSS", u"321\u2009\u2013\u2009987"},
2082 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "S", u"3\u2009\u2013\u20099"},
2083 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "SS", u"32\u2009\u2013\u200998"},
2084 { 2019, 2, 10, 1, 23, 45, 321, 1, 23, 46, 987, "SSS", u"321\u2009\u2013\u2009987"},
2085 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "S", u"3\u2009\u2013\u20099"},
2086 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "SS", u"32\u2009\u2013\u200998"},
2087 { 2019, 2, 10, 1, 23, 45, 321, 2, 24, 45, 987, "SSS", u"321\u2009\u2013\u2009987"},
2088 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, nullptr},
2089 };
2090
2091 const Locale &enLocale = Locale::getEnglish();
2092 IcuTestErrorCode status(*this, "testFormatMillisecond");
2093 LocalPointer<Calendar> calendar(Calendar::createInstance(enLocale, status));
2094 if (status.errIfFailureAndReset()) { return; }
2095
2096 for (int32_t i = 0; kTestCases[i].year > 0; i++) {
2097 LocalPointer<DateIntervalFormat> fmt(DateIntervalFormat::createInstance(
2098 kTestCases[i].skeleton, enLocale, status));
2099 if (status.errIfFailureAndReset()) { continue; }
2100
2101 calendar->clear();
2102 calendar->set(kTestCases[i].year, kTestCases[i].month, kTestCases[i].day,
2103 kTestCases[i].from_hour, kTestCases[i].from_miniute, kTestCases[i].from_second);
2104 UDate from = calendar->getTime(status) + kTestCases[i].from_millisecond;
2105 if (status.errIfFailureAndReset()) { continue; }
2106
2107 calendar->clear();
2108 calendar->set(kTestCases[i].year, kTestCases[i].month, kTestCases[i].day,
2109 kTestCases[i].to_hour, kTestCases[i].to_miniute, kTestCases[i].to_second);
2110 UDate to = calendar->getTime(status) + kTestCases[i].to_millisecond;
2111 FormattedDateInterval res = fmt->formatToValue(DateInterval(from, to), status);
2112 if (status.errIfFailureAndReset()) { continue; }
2113
2114 UnicodeString formatted = res.toString(status);
2115 if (status.errIfFailureAndReset()) { continue; }
2116 if (formatted != kTestCases[i].expected) {
2117 std::string tmp1;
2118 std::string tmp2;
2119 errln("Case %d for skeleton %s : Got %s but expect %s",
2120 i, kTestCases[i].skeleton, formatted.toUTF8String<std::string>(tmp1).c_str(),
2121 UnicodeString(kTestCases[i].expected).toUTF8String<std::string>(tmp2).c_str());
2122 }
2123 }
2124 }
2125
testTicket20707()2126 void DateIntervalFormatTest::testTicket20707() {
2127 IcuTestErrorCode status(*this, "testTicket20707");
2128
2129 const char16_t timeZone[] = u"UTC";
2130 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"};
2131
2132 // Clomuns: hh, HH, kk, KK, jj, JJs, CC
2133 UnicodeString expected[][7] = {
2134 // Hour-cycle: k
2135 {u"12\u202FAM", u"24", u"24", u"12\u202FAM", u"24", u"0 (hour: 24)", u"12\u202FAM"},
2136 // Hour-cycle: H
2137 {u"12\u202FAM", u"00", u"00", u"12\u202FAM", u"00", u"0 (hour: 00)", u"12\u202FAM"},
2138 // Hour-cycle: h
2139 {u"12\u202FAM", u"00", u"00", u"12\u202FAM", u"12\u202FAM", u"0 (hour: 12)", u"12\u202FAM"},
2140 // Hour-cycle: K
2141 {u"0\u202FAM", u"00", u"00", u"0\u202FAM", u"0\u202FAM", u"0 (hour: 00)", u"0\u202FAM"},
2142 {u"12\u202FAM", u"00", u"00", u"12\u202FAM", u"12\u202FAM", u"0 (hour: 12)", u"12\u202FAM"},
2143 {u"12\u202FAM", u"00", u"00", u"12\u202FAM", u"12\u202FAM", u"0 (hour: 12)", u"12\u202FAM"},
2144 // Hour-cycle: K
2145 {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"}
2146 };
2147
2148 int32_t i = 0;
2149 for (Locale locale : locales) {
2150 int32_t j = 0;
2151 for (const UnicodeString skeleton : {u"hh", u"HH", u"kk", u"KK", u"jj", u"JJs", u"CC"}) {
2152 LocalPointer<DateIntervalFormat> dtifmt(DateIntervalFormat::createInstance(skeleton, locale, status));
2153 if (status.errDataIfFailureAndReset()) {
2154 continue;
2155 }
2156 FieldPosition fposition;
2157 UnicodeString result;
2158 LocalPointer<Calendar> calendar(Calendar::createInstance(TimeZone::createTimeZone(timeZone), status));
2159 calendar->setTime(UDate(1563235200000), status);
2160 dtifmt->format(*calendar, *calendar, result, fposition, status);
2161
2162 assertEquals("Formatted result", expected[i][j++], result);
2163 }
2164 i++;
2165 }
2166 }
2167
getCategoryAndField(const FormattedDateInterval & formatted,std::vector<int32_t> & categories,std::vector<int32_t> & fields,IcuTestErrorCode & status)2168 void DateIntervalFormatTest::getCategoryAndField(
2169 const FormattedDateInterval& formatted,
2170 std::vector<int32_t>& categories,
2171 std::vector<int32_t>& fields,
2172 IcuTestErrorCode& status) {
2173 categories.clear();
2174 fields.clear();
2175 ConstrainedFieldPosition cfpos;
2176 while (formatted.nextPosition(cfpos, status)) {
2177 categories.push_back(cfpos.getCategory());
2178 fields.push_back(cfpos.getField());
2179 }
2180 }
2181
verifyCategoryAndField(const FormattedDateInterval & formatted,const std::vector<int32_t> & categories,const std::vector<int32_t> & fields,IcuTestErrorCode & status)2182 void DateIntervalFormatTest::verifyCategoryAndField(
2183 const FormattedDateInterval& formatted,
2184 const std::vector<int32_t>& categories,
2185 const std::vector<int32_t>& fields,
2186 IcuTestErrorCode& status) {
2187 ConstrainedFieldPosition cfpos;
2188 int32_t i = 0;
2189 while (formatted.nextPosition(cfpos, status)) {
2190 assertEquals("Category", cfpos.getCategory(), categories[i]);
2191 assertEquals("Field", cfpos.getField(), fields[i]);
2192 i++;
2193 }
2194 }
2195
testTicket21222GregorianEraDiff()2196 void DateIntervalFormatTest::testTicket21222GregorianEraDiff() {
2197 IcuTestErrorCode status(*this, " ");
2198
2199 LocalPointer<Calendar> cal(Calendar::createInstance(*TimeZone::getGMT(), status));
2200 if (U_FAILURE(status)) {
2201 errln("Failure encountered: %s", u_errorName(status));
2202 return;
2203 }
2204 std::vector<int32_t> expectedCategory;
2205 std::vector<int32_t> expectedField;
2206
2207 // Test Gregorian calendar
2208 LocalPointer<DateIntervalFormat> g(
2209 DateIntervalFormat::createInstance(
2210 u"h", Locale("en"), status));
2211 if (U_FAILURE(status)) {
2212 errln("Failure encountered: %s", u_errorName(status));
2213 return;
2214 }
2215 g->setTimeZone(*(TimeZone::getGMT()));
2216 cal->setTime(Calendar::getNow(), status);
2217 cal->set(123, UCAL_APRIL, 5, 6, 0);
2218 FormattedDateInterval formatted;
2219
2220 UDate date0123Apr5AD = cal->getTime(status);
2221
2222 cal->set(UCAL_YEAR, 124);
2223 UDate date0124Apr5AD = cal->getTime(status);
2224
2225 cal->set(UCAL_ERA, 0);
2226 UDate date0124Apr5BC = cal->getTime(status);
2227
2228 cal->set(UCAL_YEAR, 123);
2229 UDate date0123Apr5BC = cal->getTime(status);
2230
2231 DateInterval bothAD(date0123Apr5AD, date0124Apr5AD);
2232 DateInterval bothBC(date0124Apr5BC, date0123Apr5BC);
2233 DateInterval BCtoAD(date0123Apr5BC, date0124Apr5AD);
2234
2235 formatted = g->formatToValue(bothAD, status);
2236 assertEquals("Gregorian - calendar both dates in AD",
2237 u"4/5/123, 6\u202FAM\u2009\u2013\u20094/5/124, 6\u202FAM",
2238 formatted.toString(status));
2239
2240 formatted = g->formatToValue(bothBC, status);
2241 assertEquals("Gregorian - calendar both dates in BC",
2242 u"4/5/124, 6\u202FAM\u2009\u2013\u20094/5/123, 6\u202FAM",
2243 formatted.toString(status));
2244
2245 formatted = g->formatToValue(BCtoAD, status);
2246 assertEquals("Gregorian - BC to AD",
2247 u"4/5/123 BC, 6\u202FAM\u2009\u2013\u20094/5/124 AD, 6\u202FAM",
2248 formatted.toString(status));
2249 }
2250
testTicket21222ROCEraDiff()2251 void DateIntervalFormatTest::testTicket21222ROCEraDiff() {
2252 IcuTestErrorCode status(*this, "testTicket21222ROCEraDiff");
2253
2254 LocalPointer<Calendar> cal(Calendar::createInstance(*TimeZone::getGMT(), status));
2255 if (U_FAILURE(status)) {
2256 errln("Failure encountered: %s", u_errorName(status));
2257 return;
2258 }
2259 std::vector<int32_t> expectedCategory;
2260 std::vector<int32_t> expectedField;
2261
2262 // Test roc calendar
2263 LocalPointer<DateIntervalFormat> roc(
2264 DateIntervalFormat::createInstance(
2265 u"h", Locale("zh-Hant-TW@calendar=roc"), status));
2266 if (U_FAILURE(status)) {
2267 errln("Failure encountered: %s", u_errorName(status));
2268 return;
2269 }
2270 roc->setTimeZone(*(TimeZone::getGMT()));
2271
2272 FormattedDateInterval formatted;
2273 // set date1910Jan2 to 1910/1/2 AD which is prior to MG
2274 cal->set(1910, UCAL_JANUARY, 2, 6, 0);
2275 UDate date1910Jan2 = cal->getTime(status);
2276
2277 // set date1911Jan2 to 1911/1/2 AD which is also prior to MG
2278 cal->set(UCAL_YEAR, 1911);
2279 UDate date1911Jan2 = cal->getTime(status);
2280
2281 // set date1912Jan2 to 1912/1/2 AD which is after MG
2282 cal->set(UCAL_YEAR, 1912);
2283 UDate date1912Jan2 = cal->getTime(status);
2284
2285 // set date1913Jan2 to 1913/1/2 AD which is also after MG
2286 cal->set(UCAL_YEAR, 1913);
2287 UDate date1913Jan2 = cal->getTime(status);
2288
2289 DateInterval bothBeforeMG(date1910Jan2, date1911Jan2);
2290 DateInterval beforeAfterMG(date1911Jan2, date1913Jan2);
2291 DateInterval bothAfterMG(date1912Jan2, date1913Jan2);
2292
2293 formatted = roc->formatToValue(bothAfterMG, status);
2294 assertEquals("roc calendar - both dates in MG Era",
2295 u"民國1/1/2 上午6時\u2009\u2013\u2009民國2/1/2 上午6時",
2296 formatted.toString(status));
2297 getCategoryAndField(formatted, expectedCategory,
2298 expectedField, status);
2299
2300 formatted = roc->formatToValue(beforeAfterMG, status);
2301 assertEquals("roc calendar - prior MG Era and in MG Era",
2302 u"民國前1/1/2 上午6時\u2009\u2013\u2009民國2/1/2 上午6時",
2303 formatted.toString(status));
2304 verifyCategoryAndField(formatted, expectedCategory, expectedField, status);
2305
2306 formatted = roc->formatToValue(bothBeforeMG, status);
2307 assertEquals("roc calendar - both dates prior MG Era",
2308 u"民國前2/1/2 上午6時\u2009\u2013\u2009民國前1/1/2 上午6時",
2309 formatted.toString(status));
2310 verifyCategoryAndField(formatted, expectedCategory, expectedField, status);
2311 }
2312
testTicket21222JapaneseEraDiff()2313 void DateIntervalFormatTest::testTicket21222JapaneseEraDiff() {
2314 IcuTestErrorCode status(*this, "testTicket21222JapaneseEraDiff");
2315
2316 LocalPointer<Calendar> cal(Calendar::createInstance(*TimeZone::getGMT(), status));
2317 if (U_FAILURE(status)) {
2318 errln("Failure encountered: %s", u_errorName(status));
2319 return;
2320 }
2321 std::vector<int32_t> expectedCategory;
2322 std::vector<int32_t> expectedField;
2323
2324 // Test roc calendar
2325 // Test Japanese calendar
2326 LocalPointer<DateIntervalFormat> japanese(
2327 DateIntervalFormat::createInstance(
2328 u"h", Locale("ja@calendar=japanese"), status));
2329 if (U_FAILURE(status)) {
2330 errln("Failure encountered: %s", u_errorName(status));
2331 return;
2332 }
2333 japanese->setTimeZone(*(TimeZone::getGMT()));
2334
2335 FormattedDateInterval formatted;
2336
2337 cal->set(2019, UCAL_MARCH, 2, 6, 0);
2338 UDate date2019Mar2 = cal->getTime(status);
2339
2340 cal->set(UCAL_MONTH, UCAL_APRIL);
2341 cal->set(UCAL_DAY_OF_MONTH, 3);
2342 UDate date2019Apr3 = cal->getTime(status);
2343
2344 cal->set(UCAL_MONTH, UCAL_MAY);
2345 cal->set(UCAL_DAY_OF_MONTH, 4);
2346 UDate date2019May4 = cal->getTime(status);
2347
2348 cal->set(UCAL_MONTH, UCAL_JUNE);
2349 cal->set(UCAL_DAY_OF_MONTH, 5);
2350 UDate date2019Jun5 = cal->getTime(status);
2351
2352 DateInterval bothBeforeReiwa(date2019Mar2, date2019Apr3);
2353 DateInterval beforeAfterReiwa(date2019Mar2, date2019May4);
2354 DateInterval bothAfterReiwa(date2019May4, date2019Jun5);
2355
2356 formatted = japanese->formatToValue(bothAfterReiwa, status);
2357 assertEquals("japanese calendar - both dates in Reiwa",
2358 u"R1/5/4 午前6時~R1/6/5 午前6時",
2359 formatted.toString(status));
2360 getCategoryAndField(formatted, expectedCategory,
2361 expectedField, status);
2362
2363 formatted = japanese->formatToValue(bothBeforeReiwa, status);
2364 assertEquals("japanese calendar - both dates before Reiwa",
2365 u"H31/3/2 午前6時~H31/4/3 午前6時",
2366 formatted.toString(status));
2367 verifyCategoryAndField(formatted, expectedCategory, expectedField, status);
2368
2369 formatted = japanese->formatToValue(beforeAfterReiwa, status);
2370 assertEquals("japanese calendar - date before and in Reiwa",
2371 u"H31/3/2 午前6時~R1/5/4 午前6時",
2372 formatted.toString(status));
2373 verifyCategoryAndField(formatted, expectedCategory, expectedField, status);
2374 }
2375
testTicket21939()2376 void DateIntervalFormatTest::testTicket21939() {
2377 IcuTestErrorCode err(*this, "testTicket21939");
2378 LocalPointer<DateIntervalFormat> dif(DateIntervalFormat::createInstance(u"rMdhm", Locale::forLanguageTag("en-u-ca-chinese", err), err));
2379
2380 if (assertSuccess("Error creating DateIntervalFormat", err)) {
2381 const DateFormat* df = dif->getDateFormat();
2382 const SimpleDateFormat* sdf = dynamic_cast<const SimpleDateFormat*>(df);
2383 UnicodeString pattern;
2384 assertEquals("Wrong pattern", u"M/d/r, h:mm\u202Fa", sdf->toPattern(pattern));
2385 }
2386 }
2387
2388 #endif /* #if !UCONFIG_NO_FORMATTING */
2389