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 #include "dtfmrgts.h"
13
14 #include "unicode/timezone.h"
15 #include "unicode/gregocal.h"
16 #include "unicode/smpdtfmt.h"
17 #include "unicode/datefmt.h"
18 #include "unicode/simpletz.h"
19 #include "unicode/resbund.h"
20 #include "cmemory.h"
21
22 // *****************************************************************************
23 // class DateFormatRegressionTest
24 // *****************************************************************************
25
26 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;
27
28 void
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)29 DateFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
30 {
31 // if (exec) logln((UnicodeString)"TestSuite DateFormatRegressionTest");
32 switch (index) {
33 CASE(0,Test4029195)
34 CASE(1,Test4052408)
35 CASE(2,Test4056591)
36 CASE(3,Test4059917)
37 CASE(4,Test4060212)
38 CASE(5,Test4061287)
39 CASE(6,Test4065240)
40 CASE(7,Test4071441)
41 CASE(8,Test4073003)
42 CASE(9,Test4089106)
43 CASE(10,Test4100302)
44 CASE(11,Test4101483)
45 CASE(12,Test4103340)
46 CASE(13,Test4103341)
47 CASE(14,Test4104136)
48 CASE(15,Test4104522)
49 CASE(16,Test4106807)
50 CASE(17,Test4108407)
51 CASE(18,Test4134203)
52 CASE(19,Test4151631)
53 CASE(20,Test4151706)
54 CASE(21,Test4162071)
55 CASE(22,Test4182066)
56 CASE(23,Test4210209)
57 CASE(24,Test714)
58 CASE(25,Test1684)
59 CASE(26,Test5554)
60 CASE(27,Test9237)
61 CASE(28,TestParsing)
62 CASE(29,Test12902_yWithGregoCalInThaiLoc)
63 CASE(30,TestT10334)
64 CASE(31,TestT10619)
65 CASE(32,TestT10855)
66 CASE(33,TestT10858)
67 CASE(34,TestT10906)
68 CASE(35,TestT13380)
69 default: name = ""; break;
70 }
71 }
72
73 /**
74 * @bug 4029195
75 */
Test4029195(void)76 void DateFormatRegressionTest::Test4029195(void)
77 {
78 UErrorCode status = U_ZERO_ERROR;
79
80 UDate today = Calendar::getNow();
81 logln((UnicodeString) "today: " + today);
82
83 SimpleDateFormat *sdf = (SimpleDateFormat*) DateFormat::createDateInstance();
84 if (failure(status, "SimpleDateFormat::createDateInstance")) {
85 return;
86 }
87 UnicodeString pat;
88 if(sdf == NULL){
89 dataerrln("Error calling DateFormat::createDateTimeInstance");
90 return;
91 }
92
93 pat = sdf->toPattern(pat);
94 logln("pattern: " + pat);
95 UnicodeString fmtd;
96
97 FieldPosition pos(FieldPosition::DONT_CARE);
98 fmtd = sdf->format(today, fmtd, pos);
99 logln("today: " + fmtd);
100
101 sdf->applyPattern("G yyyy DDD");
102 UnicodeString todayS;
103 todayS = sdf->format(today, todayS, pos);
104 logln("today: " + todayS);
105 //try {
106 today = sdf->parse(todayS, status);
107 failure(status, "sdf->parse");
108 logln((UnicodeString)"today date: " + today);
109 /*} catch(Exception e) {
110 logln("Error reparsing date: " + e.getMessage());
111 }*/
112
113 //try {
114 UnicodeString rt;
115 rt = sdf->format(sdf->parse(todayS, status), rt, pos);
116 failure(status, "sdf->parse");
117 logln("round trip: " + rt);
118 if(rt != todayS)
119 errln("Fail: Want " + todayS + " Got " + rt);
120 /*}
121 catch (ParseException e) {
122 errln("Fail: " + e);
123 e.printStackTrace();
124 }*/
125
126 delete sdf;
127 }
128
129 /**
130 * @bug 4052408
131 */
Test4052408(void)132 void DateFormatRegressionTest::Test4052408(void)
133 {
134
135 DateFormat *fmt = DateFormat::createDateTimeInstance(DateFormat::SHORT,
136 DateFormat::SHORT, Locale::getUS());
137 if (fmt == NULL) {
138 dataerrln("Error calling DateFormat::createDateTimeInstance");
139 return;
140 }
141
142 UDate dt = date(97, UCAL_MAY, 3, 8, 55);
143 UnicodeString str;
144 str = fmt->format(dt, str);
145 logln(str);
146
147 if(str != "5/3/97, 8:55 AM")
148 errln("Fail: Test broken; Want 5/3/97 8:55 AM Got " + str);
149
150 UnicodeString expected[] = {
151 (UnicodeString) "", //"ERA_FIELD",
152 (UnicodeString) "97", //"YEAR_FIELD",
153 (UnicodeString) "5", //"MONTH_FIELD",
154 (UnicodeString) "3", //"DATE_FIELD",
155 (UnicodeString) "", //"HOUR_OF_DAY1_FIELD",
156 (UnicodeString) "", //"HOUR_OF_DAY0_FIELD",
157 (UnicodeString) "55", //"MINUTE_FIELD",
158 (UnicodeString) "", //"SECOND_FIELD",
159 (UnicodeString) "", //"MILLISECOND_FIELD",
160 (UnicodeString) "", //"DAY_OF_WEEK_FIELD",
161 (UnicodeString) "", //"DAY_OF_YEAR_FIELD",
162 (UnicodeString) "", //"DAY_OF_WEEK_IN_MONTH_FIELD",
163 (UnicodeString) "", //"WEEK_OF_YEAR_FIELD",
164 (UnicodeString) "", //"WEEK_OF_MONTH_FIELD",
165 (UnicodeString) "AM", //"AM_PM_FIELD",
166 (UnicodeString) "8", //"HOUR1_FIELD",
167 (UnicodeString) "", //"HOUR0_FIELD",
168 (UnicodeString) "" //"TIMEZONE_FIELD"
169 };
170
171 //Hashtable expected;// = new Hashtable();
172 //expected.put(new LongKey(DateFormat.MONTH_FIELD), "5");
173 //expected.put(new LongKey(DateFormat.DATE_FIELD), "3");
174 //expected.put(new LongKey(DateFormat.YEAR_FIELD), "97");
175 //expected.put(new LongKey(DateFormat.HOUR1_FIELD), "8");
176 //expected.put(new LongKey(DateFormat.MINUTE_FIELD), "55");
177 //expected.put(new LongKey(DateFormat.AM_PM_FIELD), "AM");
178
179 //StringBuffer buf = new StringBuffer();
180 UnicodeString fieldNames[] = {
181 (UnicodeString) "ERA_FIELD",
182 (UnicodeString) "YEAR_FIELD",
183 (UnicodeString) "MONTH_FIELD",
184 (UnicodeString) "DATE_FIELD",
185 (UnicodeString) "HOUR_OF_DAY1_FIELD",
186 (UnicodeString) "HOUR_OF_DAY0_FIELD",
187 (UnicodeString) "MINUTE_FIELD",
188 (UnicodeString) "SECOND_FIELD",
189 (UnicodeString) "MILLISECOND_FIELD",
190 (UnicodeString) "DAY_OF_WEEK_FIELD",
191 (UnicodeString) "DAY_OF_YEAR_FIELD",
192 (UnicodeString) "DAY_OF_WEEK_IN_MONTH_FIELD",
193 (UnicodeString) "WEEK_OF_YEAR_FIELD",
194 (UnicodeString) "WEEK_OF_MONTH_FIELD",
195 (UnicodeString) "AM_PM_FIELD",
196 (UnicodeString) "HOUR1_FIELD",
197 (UnicodeString) "HOUR0_FIELD",
198 (UnicodeString) "TIMEZONE_FIELD"
199 };
200
201 UBool pass = TRUE;
202 for(int i = 0; i <= 17; ++i) {
203 FieldPosition pos(i);
204 UnicodeString buf;
205 fmt->format(dt, buf, pos);
206 //char[] dst = new char[pos.getEndIndex() - pos.getBeginIndex()];
207 UnicodeString dst;
208 buf.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), dst);
209 UnicodeString str(dst);
210 logln((UnicodeString)"" + i + (UnicodeString)": " + fieldNames[i] +
211 (UnicodeString)", \"" + str + (UnicodeString)"\", " +
212 pos.getBeginIndex() + (UnicodeString)", " +
213 pos.getEndIndex());
214 UnicodeString exp = expected[i];
215 if((exp.length() == 0 && str.length() == 0) || str == exp)
216 logln(" ok");
217 else {
218 errln(UnicodeString(" expected ") + exp);
219 pass = FALSE;
220 }
221
222 }
223 if( ! pass)
224 errln("Fail: FieldPosition not set right by DateFormat");
225
226 delete fmt;
227 }
228
229 /**
230 * @bug 4056591
231 * Verify the function of the [s|g]et2DigitYearStart() API.
232 */
Test4056591(void)233 void DateFormatRegressionTest::Test4056591(void)
234 {
235 UErrorCode status = U_ZERO_ERROR;
236
237 //try {
238 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("yyMMdd"), Locale::getUS(), status);
239 if (failure(status, "new SimpleDateFormat", TRUE)) {
240 delete fmt;
241 return;
242 }
243 UDate start = date(1809-1900, UCAL_DECEMBER, 25);
244 fmt->set2DigitYearStart(start, status);
245 failure(status, "fmt->setTwoDigitStartDate");
246 if( (fmt->get2DigitYearStart(status) != start) || failure(status, "get2DigitStartDate"))
247 errln("get2DigitYearStart broken");
248 UDate dates [] = {
249 date(1809-1900, UCAL_DECEMBER, 25),
250 date(1909-1900, UCAL_DECEMBER, 24),
251 date(1809-1900, UCAL_DECEMBER, 26),
252 date(1861-1900, UCAL_DECEMBER, 25),
253 };
254
255 UnicodeString strings [] = {
256 (UnicodeString) "091225",
257 (UnicodeString) "091224",
258 (UnicodeString) "091226",
259 (UnicodeString) "611225"
260 };
261
262 /*Object[] DATA = {
263 "091225", new Date(1809-1900, Calendar.DECEMBER, 25),
264 "091224", new Date(1909-1900, Calendar.DECEMBER, 24),
265 "091226", new Date(1809-1900, Calendar.DECEMBER, 26),
266 "611225", new Date(1861-1900, Calendar.DECEMBER, 25),
267 };*/
268
269 for(int i = 0; i < 4; i++) {
270 UnicodeString s = strings[i];
271 UDate exp = dates[i];
272 UDate got = fmt->parse(s, status);
273 failure(status, "fmt->parse");
274 logln(s + " -> " + got + "; exp " + exp);
275 if(got != exp)
276 errln("set2DigitYearStart broken");
277 }
278 /*}
279 catch (ParseException e) {
280 errln("Fail: " + e);
281 e.printStackTrace();
282 }*/
283
284 delete fmt;
285 }
286
287 /**
288 * @bug 4059917
289 */
Test4059917(void)290 void DateFormatRegressionTest::Test4059917(void)
291 {
292 UErrorCode status = U_ZERO_ERROR;
293
294 UnicodeString myDate;
295
296 SimpleDateFormat fmt(UnicodeString(u"yyyy/MM/dd"), status );
297 if (failure(status, "new SimpleDateFormat", TRUE)) return;
298 myDate = "1997/01/01";
299 aux917( &fmt, myDate );
300
301 SimpleDateFormat fmt2( UnicodeString(u"yyyyMMdd"), status );
302 if(failure(status, "new SimpleDateFormat")) return;
303 myDate = "19970101";
304 aux917(&fmt2, myDate );
305 }
306
aux917(SimpleDateFormat * fmt,UnicodeString & str)307 void DateFormatRegressionTest::aux917( SimpleDateFormat *fmt, UnicodeString& str ) {
308 //try {
309 UnicodeString pat;
310 pat = fmt->toPattern(pat);
311 logln( "==================" );
312 logln( "testIt: pattern=" + pat +
313 " string=" + str );
314
315
316 Formattable o;
317 //Object o;
318 ParsePosition pos(0);
319 fmt->parseObject( str, o, pos );
320 //logln( UnicodeString("Parsed object: ") + o );
321
322 UErrorCode status = U_ZERO_ERROR;
323 UnicodeString formatted;
324 FieldPosition poss(FieldPosition::DONT_CARE);
325 formatted = fmt->format( o, formatted, poss, status );
326 failure(status, "fmt->format");
327 logln( "Formatted string: " + formatted );
328 if( formatted != str)
329 errln("Fail: Want " + str + " Got " + formatted);
330 /*}
331 catch (ParseException e) {
332 errln("Fail: " + e);
333 e.printStackTrace();
334 }*/
335 }
336
337 /**
338 * @bug 4060212
339 */
Test4060212(void)340 void DateFormatRegressionTest::Test4060212(void)
341 {
342 UnicodeString dateString = "1995-040.05:01:29";
343
344 logln( "dateString= " + dateString );
345 logln("Using yyyy-DDD.hh:mm:ss");
346 UErrorCode status = U_ZERO_ERROR;
347 SimpleDateFormat formatter(UnicodeString("yyyy-DDD.hh:mm:ss"), status);
348 if (failure(status, "new SimpleDateFormat", TRUE)) return;
349 ParsePosition pos(0);
350 UDate myDate = formatter.parse( dateString, pos );
351 UnicodeString myString;
352 LocalPointer<DateFormat> fmt(DateFormat::createDateTimeInstance( DateFormat::FULL,
353 DateFormat::LONG));
354 if (!fmt.isValid()) {
355 dataerrln("Error calling DateFormat::createDateTimeInstance");
356 return;
357 }
358
359 myString = fmt->format( myDate, myString);
360 logln( myString );
361
362 LocalPointer<Calendar> cal(new GregorianCalendar(status));
363 failure(status, "new GregorianCalendar");
364 cal->setTime(myDate, status);
365 failure(status, "cal->setTime");
366 if ((cal->get(UCAL_DAY_OF_YEAR, status) != 40) || failure(status, "cal->get"))
367 errln((UnicodeString) "Fail: Got " + cal->get(UCAL_DAY_OF_YEAR, status) +
368 " Want 40");
369
370 // this is an odd usage of "ddd" and it doesn't
371 // work now that date values are range checked per #3579.
372 logln("Using yyyy-ddd.hh:mm:ss");
373 SimpleDateFormat formatter2(UnicodeString(u"yyyy-ddd.hh:mm:ss"), status);
374 if(failure(status, "new SimpleDateFormat")) return;
375 pos.setIndex(0);
376 myDate = formatter2.parse( dateString, pos );
377 myString = fmt->format( myDate, myString );
378 logln( myString );
379 cal->setTime(myDate, status);
380 failure(status, "cal->setTime");
381 if ((cal->get(UCAL_DAY_OF_YEAR, status) != 40) || failure(status, "cal->get"))
382 errln((UnicodeString) "Fail: Got " + cal->get(UCAL_DAY_OF_YEAR, status) +
383 " Want 40");
384 }
385
386 /**
387 * @bug 4061287
388 */
Test4061287(void)389 void DateFormatRegressionTest::Test4061287(void)
390 {
391 UErrorCode status = U_ZERO_ERROR;
392
393 SimpleDateFormat *df = new SimpleDateFormat(UnicodeString("dd/MM/yyyy"), status);
394 if (U_FAILURE(status)) {
395 dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
396 delete df;
397 return;
398 }
399 failure(status, "new SimpleDateFormat");
400 //try {
401 logln(UnicodeString("") + df->parse("35/01/1971", status));
402 failure(status, "df->parse(\"35/01/1971\")");
403 //logln(df.parse("35/01/1971").toString());
404 //}
405 /*catch (ParseException e) {
406 errln("Fail: " + e);
407 e.printStackTrace();
408 }*/
409 df->setLenient(FALSE);
410 UBool ok = FALSE;
411 //try {
412 logln(UnicodeString("") + df->parse("35/01/1971", status));
413 if(U_FAILURE(status))
414 ok = TRUE;
415 //logln(df.parse("35/01/1971").toString());
416 //} catch (ParseException e) {ok=TRUE;}
417 if(!ok)
418 errln("Fail: Lenient not working");
419 delete df;
420 }
421
422 /**
423 * @bug 4065240
424 */
Test4065240(void)425 void DateFormatRegressionTest::Test4065240(void)
426 {
427 UDate curDate;
428 DateFormat *shortdate, *fulldate;
429 UnicodeString strShortDate, strFullDate;
430 Locale saveLocale = Locale::getDefault();
431 TimeZone *saveZone = TimeZone::createDefault();
432
433 UErrorCode status = U_ZERO_ERROR;
434 //try {
435 Locale *curLocale = new Locale("de","DE");
436 Locale::setDefault(*curLocale, status);
437 failure(status, "Locale::setDefault");
438 // {sfb} adoptDefault instead of setDefault
439 //TimeZone::setDefault(TimeZone::createTimeZone("EST"));
440 TimeZone::adoptDefault(TimeZone::createTimeZone("EST"));
441 curDate = date(98, 0, 1);
442 shortdate = DateFormat::createDateInstance(DateFormat::SHORT);
443 if (shortdate == NULL){
444 dataerrln("Error calling DateFormat::createDateInstance");
445 return;
446 }
447
448 fulldate = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
449 if (fulldate == NULL){
450 dataerrln("Error calling DateFormat::createDateTimeInstance");
451 return;
452 }
453 strShortDate = "The current date (short form) is ";
454 UnicodeString temp;
455 temp = shortdate->format(curDate, temp);
456 strShortDate += temp;
457 strFullDate = "The current date (long form) is ";
458 UnicodeString temp2;
459 fulldate->format(curDate, temp2);
460 strFullDate += temp2;
461
462 logln(strShortDate);
463 logln(strFullDate);
464
465 // {sfb} What to do with resource bundle stuff?????
466
467 // Check to see if the resource is present; if not, we can't test
468 ResourceBundle *bundle = new ResourceBundle(
469 NULL, *curLocale, status);
470 failure(status, "new ResourceBundle");
471 //(UnicodeString) "java.text.resources.DateFormatZoneData", curLocale);
472
473 // {sfb} API change to ResourceBundle -- add getLocale()
474 /*if (bundle->getLocale().getLanguage(temp) == UnicodeString("de")) {
475 // UPDATE THIS AS ZONE NAME RESOURCE FOR <EST> in de_DE is updated
476 if (!strFullDate.endsWith(UnicodeString("GMT-05:00")))
477 errln("Fail: Want GMT-05:00");
478 }
479 else {
480 logln("*** TEST COULD NOT BE COMPLETED BECAUSE DateFormatZoneData ***");
481 logln("*** FOR LOCALE de OR de_DE IS MISSING ***");
482 }*/
483 //}
484 //finally {
485 Locale::setDefault(saveLocale, status);
486 failure(status, "Locale::setDefault");
487 TimeZone::setDefault(*saveZone);
488 //}
489 delete shortdate;
490 delete fulldate;
491 delete saveZone;
492 delete curLocale;
493 delete bundle;
494 }
495
496 /*
497 DateFormat.equals is too narrowly defined. As a result, MessageFormat
498 does not work correctly. DateFormat.equals needs to be written so
499 that the Calendar sub-object is not compared using Calendar.equals,
500 but rather compared for equivalency. This may necessitate adding a
501 (package private) method to Calendar to test for equivalency.
502
503 Currently this bug breaks MessageFormat.toPattern
504 */
505 /**
506 * @bug 4071441
507 */
Test4071441(void)508 void DateFormatRegressionTest::Test4071441(void)
509 {
510 DateFormat *fmtA = DateFormat::createInstance();
511 DateFormat *fmtB = DateFormat::createInstance();
512
513 if (fmtA == NULL || fmtB == NULL){
514 dataerrln("Error calling DateFormat::createInstance");
515 delete fmtA;
516 delete fmtB;
517 return;
518 }
519
520 // {sfb} Is it OK to cast away const here?
521 Calendar *calA = (Calendar*) fmtA->getCalendar();
522 Calendar *calB = (Calendar*) fmtB->getCalendar();
523 if(!calA || !calB) {
524 errln("Couldn't get proper calendars, exiting");
525 delete fmtA;
526 delete fmtB;
527 return;
528 }
529 UDate epoch = date(0, 0, 0);
530 UDate xmas = date(61, UCAL_DECEMBER, 25);
531
532 UErrorCode status = U_ZERO_ERROR;
533 calA->setTime(epoch, status);
534 failure(status, "calA->setTime");
535 calB->setTime(epoch, status);
536 failure(status, "calB->setTime");
537 if (*calA != *calB)
538 errln("Fail: Can't complete test; Calendar instances unequal");
539 if (*fmtA != *fmtB)
540 errln("Fail: DateFormat unequal when Calendars equal");
541 calB->setTime(xmas, status);
542 failure(status, "calB->setTime");
543 if (*calA == *calB)
544 errln("Fail: Can't complete test; Calendar instances equal");
545 if (*fmtA != *fmtB)
546 errln("Fail: DateFormat unequal when Calendars equivalent");
547
548 logln("DateFormat.equals ok");
549
550 delete fmtA;
551 delete fmtB;
552 }
553
554 /* The java.text.DateFormat.parse(String) method expects for the
555 US locale a string formatted according to mm/dd/yy and parses it
556 correctly.
557
558 When given a string mm/dd/yyyy [sic] it only parses up to the first
559 two y's, typically resulting in a date in the year 1919.
560
561 Please extend the parsing method(s) to handle strings with
562 four-digit year values (probably also applicable to various
563 other locales. */
564 /**
565 * @bug 4073003
566 */
Test4073003(void)567 void DateFormatRegressionTest::Test4073003(void)
568 {
569 //try {
570 UErrorCode ec = U_ZERO_ERROR;
571 SimpleDateFormat fmt("MM/dd/yy", Locale::getUK(), ec);
572 if (U_FAILURE(ec)) {
573 dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec));
574 return;
575 }
576 UnicodeString tests [] = {
577 (UnicodeString) "12/25/61",
578 (UnicodeString) "12/25/1961",
579 (UnicodeString) "4/3/2010",
580 (UnicodeString) "4/3/10"
581 };
582 UErrorCode status = U_ZERO_ERROR;
583 for(int i= 0; i < 4; i+=2) {
584 UDate d = fmt.parse(tests[i], status);
585 failure(status, "fmt.parse");
586 UDate dd = fmt.parse(tests[i+1], status);
587 failure(status, "fmt.parse");
588 UnicodeString s;
589 s = fmt.format(d, s);
590 UnicodeString ss;
591 ss = fmt.format(dd, ss);
592 if (d != dd)
593 errln((UnicodeString) "Fail: " + d + " != " + dd);
594 if (s != ss)
595 errln((UnicodeString)"Fail: " + s + " != " + ss);
596 logln("Ok: " + s + " " + d);
597 }
598 }
599
600 /**
601 * @bug 4089106
602 */
Test4089106(void)603 void DateFormatRegressionTest::Test4089106(void)
604 {
605 TimeZone *def = TimeZone::createDefault();
606 //try {
607 TimeZone *z = new SimpleTimeZone((int)(1.25 * 3600000), "FAKEZONE");
608 TimeZone::setDefault(*z);
609 UErrorCode status = U_ZERO_ERROR;
610 SimpleDateFormat *f = new SimpleDateFormat(status);
611 if(U_FAILURE(status)) {
612 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status));
613 delete f;
614 delete def;
615 delete z;
616 return;
617 }
618 failure(status, "new SimpleDateFormat");
619 if (f->getTimeZone()!= *z)
620 errln("Fail: SimpleTimeZone should use TimeZone.getDefault()");
621
622 //}
623 //finally {
624 TimeZone::setDefault(*def);
625 //}
626
627 delete z;
628 delete f;
629 delete def;
630 }
631
632 /**
633 * @bug 4100302
634 */
635
636 // {sfb} not applicable in C++??
637
Test4100302(void)638 void DateFormatRegressionTest::Test4100302(void)
639 {
640 /* Locale locales [] = {
641 Locale::CANADA,
642 Locale::CANADA_FRENCH,
643 Locale::CHINA,
644 Locale::CHINESE,
645 Locale::ENGLISH,
646 Locale::FRANCE,
647 Locale::FRENCH,
648 Locale::GERMAN,
649 Locale::GERMANY,
650 Locale::ITALIAN,
651 Locale::ITALY,
652 Locale::JAPAN,
653 Locale::JAPANESE,
654 Locale::KOREA,
655 Locale::KOREAN,
656 Locale::PRC,
657 Locale::SIMPLIFIED_CHINESE,
658 Locale::TAIWAN,
659 Locale::TRADITIONAL_CHINESE,
660 Locale::UK,
661 Locale::US
662 };
663 //try {
664 UBool pass = TRUE;
665 for(int i = 0; i < 21; i++) {
666
667 Format *format = DateFormat::createDateTimeInstance(DateFormat::FULL,
668 DateFormat::FULL, locales[i]);
669 byte[] bytes;
670
671 ByteArrayOutputStream baos = new ByteArrayOutputStream();
672 ObjectOutputStream oos = new ObjectOutputStream(baos);
673
674 oos.writeObject(format);
675 oos.flush();
676
677 baos.close();
678 bytes = baos.toByteArray();
679
680 ObjectInputStream ois =
681 new ObjectInputStream(new ByteArrayInputStream(bytes));
682
683 if (!format.equals(ois.readObject())) {
684 pass = FALSE;
685 logln("DateFormat instance for locale " +
686 locales[i] + " is incorrectly serialized/deserialized.");
687 } else {
688 logln("DateFormat instance for locale " +
689 locales[i] + " is OKAY.");
690 }
691 }
692 if (!pass) errln("Fail: DateFormat serialization/equality bug");
693 }
694 catch (IOException e) {
695 errln("Fail: " + e);
696 e.printStackTrace();
697 }
698 catch (ClassNotFoundException e) {
699 errln("Fail: " + e);
700 e.printStackTrace();
701 }
702 */}
703
704 /**
705 * @bug 4101483
706 */
Test4101483(void)707 void DateFormatRegressionTest::Test4101483(void)
708 {
709 UErrorCode status = U_ZERO_ERROR;
710 SimpleDateFormat sdf(UnicodeString("z"), Locale::getUS(), status);
711 if (failure(status, "new SimpleDateFormat", TRUE)) return;
712 FieldPosition fp(UDAT_TIMEZONE_FIELD);
713 //Date d = date(9234567890L);
714 UDate d = 9234567890.0;
715 //StringBuffer buf = new StringBuffer("");
716 UnicodeString buf;
717 sdf.format(d, buf, fp);
718 //logln(sdf.format(d, buf, fp).toString());
719 logln(dateToString(d) + " => " + buf);
720 logln(UnicodeString("beginIndex = ") + fp.getBeginIndex());
721 logln(UnicodeString("endIndex = ") + fp.getEndIndex());
722 if (fp.getBeginIndex() == fp.getEndIndex())
723 errln("Fail: Empty field");
724 }
725
726 /**
727 * @bug 4103340
728 * @bug 4138203
729 * This bug really only works in Locale.US, since that's what the locale
730 * used for Date.toString() is. Bug 4138203 reports that it fails on Korean
731 * NT; it would actually have failed on any non-US locale. Now it should
732 * work on all locales.
733 */
Test4103340(void)734 void DateFormatRegressionTest::Test4103340(void)
735 {
736 UErrorCode status = U_ZERO_ERROR;
737
738 // choose a date that is the FIRST of some month
739 // and some arbitrary time
740 UDate d = date(97, 3, 1, 1, 1, 1);
741 SimpleDateFormat df(UnicodeString(u"MMMM"), Locale::getUS(), status);
742 if (failure(status, "new SimpleDateFormat", TRUE)) return;
743
744 UnicodeString s;
745 s = dateToString(d, s);
746 UnicodeString s2;
747 FieldPosition pos(FieldPosition::DONT_CARE);
748 s2 = df.format(d, s2, pos);
749 logln("Date=" + s);
750 logln("DF=" + s2);
751 UnicodeString substr;
752 s2.extract(0,2, substr);
753 if (s.indexOf(substr) == -1)
754 errln("Months should match");
755 }
756
757 /**
758 * @bug 4103341
759 */
Test4103341(void)760 void DateFormatRegressionTest::Test4103341(void)
761 {
762 LocalPointer<TimeZone> saveZone(TimeZone::createDefault());
763 if (!saveZone.isValid()) {
764 dataerrln("TimeZone::createDefault() failed.");
765 return;
766 }
767 // {sfb} changed from setDefault to adoptDefault
768 TimeZone::adoptDefault(TimeZone::createTimeZone("CST"));
769 UErrorCode status = U_ZERO_ERROR;
770 SimpleDateFormat simple(UnicodeString("MM/dd/yyyy HH:mm"), status);
771 if(U_FAILURE(status)) {
772 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status));
773 } else {
774 LocalPointer<TimeZone> temp(TimeZone::createDefault());
775 if(simple.getTimeZone() != *temp)
776 errln("Fail: SimpleDateFormat not using default zone");
777 }
778 TimeZone::adoptDefault(saveZone.orphan());
779 }
780
781 /**
782 * @bug 4104136
783 */
Test4104136(void)784 void DateFormatRegressionTest::Test4104136(void)
785 {
786 UErrorCode status = U_ZERO_ERROR;
787 SimpleDateFormat *sdf = new SimpleDateFormat(status);
788 if(U_FAILURE(status)) {
789 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status));
790 delete sdf;
791 return;
792 }
793 if(failure(status, "new SimpleDateFormat")) return;
794 UnicodeString pattern = "'time' hh:mm";
795 sdf->applyPattern(pattern);
796 logln("pattern: \"" + pattern + "\"");
797
798 UnicodeString strings [] = {
799 (UnicodeString)"time 10:30",
800 (UnicodeString) "time 10:x",
801 (UnicodeString) "time 10x"
802 };
803
804 ParsePosition ppos [] = {
805 ParsePosition(10),
806 ParsePosition(0),
807 ParsePosition(0)
808 };
809
810 UDate dates [] = {
811 date(70, UCAL_JANUARY, 1, 10, 30),
812 -1,
813 -1
814 };
815
816 /*Object[] DATA = {
817 "time 10:30", new ParsePosition(10), new Date(70, Calendar.JANUARY, 1, 10, 30),
818 "time 10:x", new ParsePosition(0), null,
819 "time 10x", new ParsePosition(0), null,
820 };*/
821
822 for(int i = 0; i < 3; i++) {
823 UnicodeString text = strings[i];
824 ParsePosition finish = ppos[i];
825 UDate exp = dates[i];
826
827 ParsePosition pos(0);
828 UDate d = sdf->parse(text, pos);
829 logln(" text: \"" + text + "\"");
830 logln(" index: %d", pos.getIndex());
831 logln((UnicodeString) " result: " + d);
832 if(pos.getIndex() != finish.getIndex())
833 errln(UnicodeString("Fail: Expected pos ") + finish.getIndex());
834 if (! ((d == 0 && exp == -1) || (d == exp)))
835 errln((UnicodeString) "Fail: Expected result " + exp);
836 }
837
838 delete sdf;
839 }
840
841 /**
842 * @bug 4104522
843 * CANNOT REPRODUCE
844 * According to the bug report, this test should throw a
845 * StringIndexOutOfBoundsException during the second parse. However,
846 * this is not seen.
847 */
Test4104522(void)848 void DateFormatRegressionTest::Test4104522(void)
849 {
850 UErrorCode status = U_ZERO_ERROR;
851
852 SimpleDateFormat *sdf = new SimpleDateFormat(status);
853 if(U_FAILURE(status)) {
854 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status));
855 delete sdf;
856 return;
857 }
858 failure(status, "new SimpleDateFormat");
859 UnicodeString pattern = "'time' hh:mm";
860 sdf->applyPattern(pattern);
861 logln("pattern: \"" + pattern + "\"");
862
863 // works correctly
864 ParsePosition pp(0);
865 UnicodeString text = "time ";
866 UDate dt = sdf->parse(text, pp);
867 logln(" text: \"" + text + "\"" +
868 " date: " + dt);
869
870 // works wrong
871 pp.setIndex(0);
872 text = "time";
873 dt = sdf->parse(text, pp);
874 logln(" text: \"" + text + "\"" +
875 " date: " + dt);
876
877 delete sdf;
878 }
879
880 /**
881 * @bug 4106807
882 */
Test4106807(void)883 void DateFormatRegressionTest::Test4106807(void)
884 {
885 UDate dt;
886 DateFormat *df = DateFormat::createDateTimeInstance();
887
888 UErrorCode status = U_ZERO_ERROR;
889 SimpleDateFormat *sdfs [] = {
890 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss"), status),
891 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss'Z'"), status),
892 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss''"), status),
893 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss'a''a'"), status),
894 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss %"), status)
895 };
896 if(U_FAILURE(status)) {
897 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status));
898 delete sdfs[0];
899 delete sdfs[1];
900 delete sdfs[2];
901 delete sdfs[3];
902 delete sdfs[4];
903 return;
904 }
905
906 failure(status, "new SimpleDateFormat");
907
908 UnicodeString strings [] = {
909 (UnicodeString) "19980211140000",
910 (UnicodeString) "19980211140000",
911 (UnicodeString) "19980211140000",
912 (UnicodeString) "19980211140000a",
913 (UnicodeString) "19980211140000 "
914 };
915
916 /*Object[] data = {
917 new SimpleDateFormat("yyyyMMddHHmmss"), "19980211140000",
918 new SimpleDateFormat("yyyyMMddHHmmss'Z'"), "19980211140000",
919 new SimpleDateFormat("yyyyMMddHHmmss''"), "19980211140000",
920 new SimpleDateFormat("yyyyMMddHHmmss'a''a'"), "19980211140000a",
921 new SimpleDateFormat("yyyyMMddHHmmss %"), "19980211140000 ",
922 };*/
923 GregorianCalendar *gc = new GregorianCalendar(status);
924 failure(status, "new GregorianCalendar");
925 TimeZone *timeZone = TimeZone::createDefault();
926
927 TimeZone *gmt = timeZone->clone();
928
929 gmt->setRawOffset(0);
930
931 for(int32_t i = 0; i < 5; i++) {
932 SimpleDateFormat *format = sdfs[i];
933 UnicodeString dateString = strings[i];
934 //try {
935 format->setTimeZone(*gmt);
936 dt = format->parse(dateString, status);
937 // {sfb} some of these parses will fail purposely
938 if(U_FAILURE(status))
939 break;
940 status = U_ZERO_ERROR;
941 UnicodeString fmtd;
942 FieldPosition pos(FieldPosition::DONT_CARE);
943 fmtd = df->format(dt, fmtd, pos);
944 logln(fmtd);
945 //logln(df->format(dt));
946 gc->setTime(dt, status);
947 failure(status, "gc->getTime");
948 logln(UnicodeString("") + gc->get(UCAL_ZONE_OFFSET, status));
949 failure(status, "gc->get");
950 UnicodeString s;
951 s = format->format(dt, s, pos);
952 logln(s);
953 /*}
954 catch (ParseException e) {
955 logln("No way Jose");
956 }*/
957 }
958
959 delete timeZone;
960 delete df;
961 for(int32_t j = 0; j < 5; j++)
962 delete sdfs [j];
963 delete gc;
964 delete gmt;
965 }
966
967 /*
968 Synopsis: Chinese time zone CTT is not recogonized correctly.
969 Description: Platform Chinese Windows 95 - ** Time zone set to CST **
970 */
971 /**
972 * @bug 4108407
973 */
974
975 // {sfb} what to do with this one ??
Test4108407(void)976 void DateFormatRegressionTest::Test4108407(void)
977 {
978 /*long l = System.currentTimeMillis();
979 logln("user.timezone = " + System.getProperty("user.timezone", "?"));
980 logln("Time Zone :" +
981 DateFormat.getDateInstance().getTimeZone().getID());
982 logln("Default format :" +
983 DateFormat.getDateInstance().format(new Date(l)));
984 logln("Full format :" +
985 DateFormat.getDateInstance(DateFormat.FULL).format(new
986 Date(l)));
987 logln("*** Set host TZ to CST ***");
988 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");*/
989 }
990
991 /**
992 * @bug 4134203
993 * SimpleDateFormat won't parse "GMT"
994 */
Test4134203(void)995 void DateFormatRegressionTest::Test4134203(void)
996 {
997 UErrorCode status = U_ZERO_ERROR;
998 UnicodeString dateFormat = "MM/dd/yy HH:mm:ss zzz";
999 SimpleDateFormat fmt (dateFormat, status);
1000 if (failure(status, "new SimpleDateFormat", TRUE)) return;
1001 ParsePosition p0(0);
1002 UDate d = fmt.parse("01/22/92 04:52:00 GMT", p0);
1003 logln(dateToString(d));
1004 if(p0 == ParsePosition(0))
1005 errln("Fail: failed to parse 'GMT'");
1006 // In the failure case an exception is thrown by parse();
1007 // if no exception is thrown, the test passes.
1008 }
1009
1010 /**
1011 * @bug 4151631
1012 * SimpleDateFormat incorrect handling of 2 single quotes in format()
1013 */
Test4151631(void)1014 void DateFormatRegressionTest::Test4151631(void)
1015 {
1016 UnicodeString pattern = "'TO_DATE('''dd'-'MM'-'yyyy HH:mm:ss''' , ''DD-MM-YYYY HH:MI:SS'')'";
1017 logln("pattern=" + pattern);
1018 UErrorCode status = U_ZERO_ERROR;
1019 SimpleDateFormat format(pattern, Locale::getUS(), status);
1020 if (failure(status, "new SimpleDateFormat", TRUE)) return;
1021 UnicodeString result;
1022 FieldPosition pos(FieldPosition::DONT_CARE);
1023 result = format.format(date(1998-1900, UCAL_JUNE, 30, 13, 30, 0), result, pos);
1024 if (result != "TO_DATE('30-06-1998 13:30:00' , 'DD-MM-YYYY HH:MI:SS')") {
1025 errln("Fail: result=" + result);
1026 }
1027 else {
1028 logln("Pass: result=" + result);
1029 }
1030 }
1031
1032 /**
1033 * @bug 4151706
1034 * 'z' at end of date format throws index exception in SimpleDateFormat
1035 * CANNOT REPRODUCE THIS BUG ON 1.2FCS
1036 */
Test4151706(void)1037 void DateFormatRegressionTest::Test4151706(void)
1038 {
1039 UnicodeString dateString("Thursday, 31-Dec-98 23:00:00 GMT");
1040 UErrorCode status = U_ZERO_ERROR;
1041 SimpleDateFormat fmt(UnicodeString("EEEE, dd-MMM-yy HH:mm:ss z"), Locale::getUS(), status);
1042 if (failure(status, "new SimpleDateFormat", TRUE)) return;
1043 //try {
1044 UDate d = fmt.parse(dateString, status);
1045 failure(status, "fmt->parse");
1046 // {sfb} what about next two lines?
1047 //if (d.getTime() != Date.UTC(1998-1900, Calendar.DECEMBER, 31, 23, 0, 0))
1048 // errln("Incorrect value: " + d);
1049 /*} catch (Exception e) {
1050 errln("Fail: " + e);
1051 }*/
1052 UnicodeString temp;
1053 FieldPosition pos(FieldPosition::DONT_CARE);
1054 logln(dateString + " -> " + fmt.format(d, temp, pos));
1055 }
1056
1057 /**
1058 * @bug 4162071
1059 * Cannot reproduce this bug under 1.2 FCS -- it may be a convoluted duplicate
1060 * of some other bug that has been fixed.
1061 */
1062 void
Test4162071(void)1063 DateFormatRegressionTest::Test4162071(void)
1064 {
1065 UnicodeString dateString("Thu, 30-Jul-1999 11:51:14 GMT");
1066 UnicodeString format("EEE', 'dd-MMM-yyyy HH:mm:ss z"); // RFC 822/1123
1067 UErrorCode status = U_ZERO_ERROR;
1068 SimpleDateFormat df(format, Locale::getUS(), status);
1069 if(U_FAILURE(status)) {
1070 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status));
1071 return;
1072 }
1073
1074 //try {
1075 UDate x = df.parse(dateString, status);
1076 if(U_SUCCESS(status))
1077 logln("Parse format \"" + format + "\" ok");
1078 else
1079 errln("Parse format \"" + format + "\" failed.");
1080 UnicodeString temp;
1081 FieldPosition pos(FieldPosition::DONT_CARE);
1082 logln(dateString + " -> " + df.format(x, temp, pos));
1083 //} catch (Exception e) {
1084 // errln("Parse format \"" + format + "\" failed.");
1085 //}
1086 }
1087
1088 /**
1089 * DateFormat shouldn't parse year "-1" as a two-digit year (e.g., "-1" -> 1999).
1090 */
Test4182066(void)1091 void DateFormatRegressionTest::Test4182066(void) {
1092 UErrorCode status = U_ZERO_ERROR;
1093 SimpleDateFormat fmt("MM/dd/yy", Locale::getUS(), status);
1094 SimpleDateFormat dispFmt("MMM dd yyyy GG", Locale::getUS(), status);
1095 if (U_FAILURE(status)) {
1096 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status));
1097 return;
1098 }
1099
1100 /* We expect 2-digit year formats to put 2-digit years in the right
1101 * window. Out of range years, that is, anything less than "00" or
1102 * greater than "99", are treated as literal years. So "1/2/3456"
1103 * becomes 3456 AD. Likewise, "1/2/-3" becomes -3 AD == 2 BC.
1104 */
1105 const char* STRINGS[] = {
1106 "02/29/00",
1107 "01/23/01",
1108 "04/05/-1",
1109 "01/23/-9",
1110 "11/12/1314",
1111 "10/31/1",
1112 "09/12/+1",
1113 "09/12/001",
1114 };
1115 int32_t STRINGS_COUNT = UPRV_LENGTHOF(STRINGS);
1116 UDate FAIL_DATE = (UDate) 0;
1117 UDate DATES[] = {
1118 date(2000-1900, UCAL_FEBRUARY, 29),
1119 date(2001-1900, UCAL_JANUARY, 23),
1120 date( -1-1900, UCAL_APRIL, 5),
1121 date( -9-1900, UCAL_JANUARY, 23),
1122 date(1314-1900, UCAL_NOVEMBER, 12),
1123 date( 1-1900, UCAL_OCTOBER, 31),
1124 FAIL_DATE, // "+1" isn't recognized by US NumberFormat
1125 date( 1-1900, UCAL_SEPTEMBER,12),
1126 };
1127
1128 UnicodeString out;
1129 UBool pass = TRUE;
1130 for (int32_t i=0; i<STRINGS_COUNT; ++i) {
1131 UnicodeString str(STRINGS[i]);
1132 UDate expected = DATES[i];
1133 status = U_ZERO_ERROR;
1134 UDate actual = fmt.parse(str, status);
1135 if (U_FAILURE(status)) {
1136 actual = FAIL_DATE;
1137 }
1138 UnicodeString actStr;
1139 if (actual == FAIL_DATE) {
1140 actStr.append("null");
1141 } else {
1142 // Yuck: See j25
1143 ((DateFormat*)&dispFmt)->format(actual, actStr);
1144 }
1145
1146 if (expected == actual) {
1147 out.append(str + " => " + actStr + "\n");
1148 } else {
1149 UnicodeString expStr;
1150 if (expected == FAIL_DATE) {
1151 expStr.append("null");
1152 } else {
1153 // Yuck: See j25
1154 ((DateFormat*)&dispFmt)->format(expected, expStr);
1155 }
1156 out.append("FAIL: " + str + " => " + actStr
1157 + ", expected " + expStr + "\n");
1158 pass = FALSE;
1159 }
1160 }
1161 if (pass) {
1162 log(out);
1163 } else {
1164 err(out);
1165 }
1166 }
1167
1168 /**
1169 * j32 {JDK Bug 4210209 4209272}
1170 * DateFormat cannot parse Feb 29 2000 when setLenient(false)
1171 */
1172 void
Test4210209(void)1173 DateFormatRegressionTest::Test4210209(void) {
1174 UErrorCode status = U_ZERO_ERROR;
1175 UnicodeString pattern("MMM d, yyyy");
1176 SimpleDateFormat sfmt(pattern, Locale::getUS(), status);
1177 SimpleDateFormat sdisp("MMM dd yyyy GG", Locale::getUS(), status);
1178 DateFormat& fmt = *(DateFormat*)&sfmt; // Yuck: See j25
1179 DateFormat& disp = *(DateFormat*)&sdisp; // Yuck: See j25
1180 if (U_FAILURE(status)) {
1181 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status));
1182 return;
1183 }
1184 Calendar* calx = (Calendar*)fmt.getCalendar(); // cast away const!
1185 calx->setLenient(FALSE);
1186 UDate d = date(2000-1900, UCAL_FEBRUARY, 29);
1187 UnicodeString s, ss;
1188 fmt.format(d, s);
1189 logln(disp.format(d, ss.remove()) + " f> " + pattern +
1190 " => \"" + s + "\"");
1191 ParsePosition pos(0);
1192 d = fmt.parse(s, pos);
1193 logln(UnicodeString("\"") + s + "\" p> " + pattern +
1194 " => " + disp.format(d, ss.remove()));
1195 logln(UnicodeString("Parse pos = ") + pos.getIndex() +
1196 ", error pos = " + pos.getErrorIndex());
1197 if (pos.getErrorIndex() != -1) {
1198 errln(UnicodeString("FAIL: Error index should be -1"));
1199 }
1200
1201 // The underlying bug is in GregorianCalendar. If the following lines
1202 // succeed, the bug is fixed. If the bug isn't fixed, they will throw
1203 // an exception.
1204 GregorianCalendar cal(status);
1205 if (U_FAILURE(status)) {
1206 errln("FAIL: Unable to create Calendar");
1207 return;
1208 }
1209 cal.clear();
1210 cal.setLenient(FALSE);
1211 cal.set(2000, UCAL_FEBRUARY, 29); // This should work!
1212 logln(UnicodeString("Attempt to set Calendar to Feb 29 2000: ") +
1213 disp.format(cal.getTime(status), ss.remove()));
1214 if (U_FAILURE(status)) {
1215 errln("FAIL: Unable to set Calendar to Feb 29 2000");
1216 }
1217 }
1218
Test714(void)1219 void DateFormatRegressionTest::Test714(void)
1220 {
1221 //try {
1222 UDate d(978103543000.);
1223 DateFormat *fmt = DateFormat::createDateTimeInstance(DateFormat::NONE,
1224 DateFormat::MEDIUM,
1225 Locale::getUS());
1226 if (fmt == NULL) {
1227 dataerrln("Error calling DateFormat::createDateTimeInstance");
1228 return;
1229 }
1230
1231 UnicodeString s;
1232 UnicodeString tests =
1233 (UnicodeString) "7:25:43 AM" ;
1234 UErrorCode status = U_ZERO_ERROR;
1235 fmt->format (d,s);
1236 if(U_FAILURE(status))
1237 {
1238 errln((UnicodeString) "Fail, errmsg " + u_errorName(status));
1239 return;
1240 }
1241
1242 if(s != tests)
1243 {
1244 errln((UnicodeString) "Fail: " + s + " != " + tests);
1245 }
1246 else
1247 {
1248 logln("OK: " + s + " == " + tests);
1249 }
1250
1251 delete fmt;
1252 }
1253
1254 class Test1684Data {
1255 public:
1256 int32_t year;
1257 int32_t month;
1258 int32_t date;
1259 int32_t womyear;
1260 int32_t wommon;
1261 int32_t wom;
1262 int32_t dow;
1263 UnicodeString data;
1264 UnicodeString normalized;
1265
Test1684Data(int32_t xyear,int32_t xmonth,int32_t xdate,int32_t xwomyear,int32_t xwommon,int32_t xwom,int32_t xdow,const char * xdata,const char * xnormalized)1266 Test1684Data(int32_t xyear, int32_t xmonth, int32_t xdate,
1267 int32_t xwomyear, int32_t xwommon, int32_t xwom, int32_t xdow,
1268 const char *xdata, const char *xnormalized) :
1269 year(xyear),
1270 month(xmonth-1),
1271 date(xdate),
1272 womyear(xwomyear),
1273 wommon(xwommon-1),
1274 wom(xwom),
1275 dow(xdow),
1276 data(xdata,""),
1277 normalized((xnormalized==NULL)?xdata:xnormalized,"")
1278 { }
1279 };
1280
Test1684(void)1281 void DateFormatRegressionTest::Test1684(void)
1282 {
1283 // July 2001 August 2001 January 2002
1284 // Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1285 // 1 2 3 4 5 6 7 1 2 3 4 1 2 3 4 5
1286 // 8 9 10 11 12 13 14 5 6 7 8 9 10 11 6 7 8 9 10 11 12
1287 // 15 16 17 18 19 20 21 12 13 14 15 16 17 18 13 14 15 16 17 18 19
1288 // 22 23 24 25 26 27 28 19 20 21 22 23 24 25 20 21 22 23 24 25 26
1289 // 29 30 31 26 27 28 29 30 31 27 28 29 30 31
1290 Test1684Data *tests[] = {
1291 new Test1684Data(2001, 8, 6, 2001,8,2,UCAL_MONDAY, "2001 08 02 Mon", NULL),
1292 new Test1684Data(2001, 8, 7, 2001,8,2,UCAL_TUESDAY, "2001 08 02 Tue", NULL),
1293 new Test1684Data(2001, 8, 5,/*12,*/ 2001,8,2,UCAL_SUNDAY, "2001 08 02 Sun", NULL),
1294 new Test1684Data(2001, 8,6, /*7, 30,*/ 2001,7,6,UCAL_MONDAY, "2001 07 06 Mon", "2001 08 02 Mon"),
1295 new Test1684Data(2001, 8,7, /*7, 31,*/ 2001,7,6,UCAL_TUESDAY, "2001 07 06 Tue", "2001 08 02 Tue"),
1296 new Test1684Data(2001, 8, 5, 2001,7,6,UCAL_SUNDAY, "2001 07 06 Sun", "2001 08 02 Sun"),
1297 new Test1684Data(2001, 7, 30, 2001,8,1,UCAL_MONDAY, "2001 08 01 Mon", "2001 07 05 Mon"),
1298 new Test1684Data(2001, 7, 31, 2001,8,1,UCAL_TUESDAY, "2001 08 01 Tue", "2001 07 05 Tue"),
1299 new Test1684Data(2001, 7,29, /*8, 5,*/ 2001,8,1,UCAL_SUNDAY, "2001 08 01 Sun", "2001 07 05 Sun"),
1300 new Test1684Data(2001, 12, 31, 2001,12,6,UCAL_MONDAY, "2001 12 06 Mon", NULL),
1301 new Test1684Data(2002, 1, 1, 2002,1,1,UCAL_TUESDAY, "2002 01 01 Tue", NULL),
1302 new Test1684Data(2002, 1, 2, 2002,1,1,UCAL_WEDNESDAY, "2002 01 01 Wed", NULL),
1303 new Test1684Data(2002, 1, 3, 2002,1,1,UCAL_THURSDAY, "2002 01 01 Thu", NULL),
1304 new Test1684Data(2002, 1, 4, 2002,1,1,UCAL_FRIDAY, "2002 01 01 Fri", NULL),
1305 new Test1684Data(2002, 1, 5, 2002,1,1,UCAL_SATURDAY, "2002 01 01 Sat", NULL),
1306 new Test1684Data(2001,12,30, /*2002, 1, 6,*/ 2002,1,1,UCAL_SUNDAY, "2002 01 01 Sun", "2001 12 06 Sun")
1307 };
1308
1309 #define kTest1684Count UPRV_LENGTHOF(tests)
1310
1311 int32_t pass = 0, error = 0, warning = 0;
1312 int32_t i;
1313
1314 UErrorCode status = U_ZERO_ERROR;
1315 UnicodeString pattern("yyyy MM WW EEE","");
1316 Calendar *cal = new GregorianCalendar(status);
1317 SimpleDateFormat *sdf = new SimpleDateFormat(pattern,status);
1318 if (U_FAILURE(status)) {
1319 dataerrln("Error constructing SimpleDateFormat");
1320 for(i=0;i<kTest1684Count;i++) {
1321 delete tests[i];
1322 }
1323 delete cal;
1324 delete sdf;
1325 return;
1326 }
1327 cal->setFirstDayOfWeek(UCAL_SUNDAY);
1328 cal->setMinimalDaysInFirstWeek(1);
1329
1330 sdf->adoptCalendar(cal);
1331
1332 cal = sdf->getCalendar()->clone(); // sdf may have deleted calendar
1333
1334 if(!cal || !sdf || U_FAILURE(status)) {
1335 errln(UnicodeString("Error setting up test: ") + u_errorName(status));
1336 }
1337
1338 for (i = 0; i < kTest1684Count; ++i) {
1339 Test1684Data &test = *(tests[i]);
1340 logln(UnicodeString("#") + i + UnicodeString("\n-----\nTesting round trip of ") + test.year +
1341 " " + (test.month + 1) +
1342 " " + test.date +
1343 " (written as) " + test.data);
1344
1345 cal->clear();
1346 cal->set(test.year, test.month, test.date);
1347 UDate ms = cal->getTime(status);
1348
1349 cal->clear();
1350 cal->set(UCAL_YEAR, test.womyear);
1351 cal->set(UCAL_MONTH, test.wommon);
1352 cal->set(UCAL_WEEK_OF_MONTH, test.wom);
1353 cal->set(UCAL_DAY_OF_WEEK, test.dow);
1354 UDate ms2 = cal->getTime(status);
1355
1356 if (ms2 != ms) {
1357 errln((UnicodeString)"\nError: GregorianUCAL_DOM gave " + ms +
1358 "\n GregorianUCAL_WOM gave " + ms2);
1359 error++;
1360 } else {
1361 pass++;
1362 }
1363
1364 ms2 = sdf->parse(test.data, status);
1365 if(U_FAILURE(status)) {
1366 errln("parse exception: " + UnicodeString(u_errorName(status)));
1367 }
1368
1369 if (ms2!=ms) {
1370 errln((UnicodeString)"\nError: GregorianCalendar gave " + ms +
1371 "\n SimpleDateFormat.parse gave " + ms2);
1372 error++;
1373 } else {
1374 pass++;
1375 }
1376
1377 UnicodeString result;
1378 sdf->format(ms, result);
1379 if (result != test.normalized) {
1380 errln("\nWarning: format of '" + test.data + "' gave" +
1381 "\n '" + result + "'" +
1382 "\n expected '" + test.normalized + "'");
1383 warning++;
1384 } else {
1385 pass++;
1386 }
1387
1388 UDate ms3;
1389 ms3 = sdf->parse(result, status);
1390 if(U_FAILURE(status)) {
1391 errln("parse exception 2: " + (UnicodeString)u_errorName(status));
1392 }
1393
1394 if (ms3!=ms) {
1395 error++;
1396 errln((UnicodeString)"\nError: Re-parse of '" + result + "' gave time of " +
1397 "\n " + ms3 +
1398 "\n not " + ms);
1399 } else {
1400 pass++;
1401 }
1402 }
1403
1404 UnicodeString info
1405 = UnicodeString("Passed: ") + pass + ", Warnings: " + warning + ", Errors: " + error;
1406 if (error > 0) {
1407 errln(info);
1408 } else {
1409 logln(info);
1410 }
1411
1412 for(i=0;i<kTest1684Count;i++) {
1413 delete tests[i];
1414 }
1415 delete cal;
1416 delete sdf;
1417 }
1418
Test5554(void)1419 void DateFormatRegressionTest::Test5554(void)
1420 {
1421 UErrorCode status = U_ZERO_ERROR;
1422 UnicodeString pattern("Z","");
1423 UnicodeString newfoundland("Canada/Newfoundland", "");
1424 TimeZone *zone = TimeZone::createTimeZone(newfoundland);
1425 Calendar *cal = new GregorianCalendar(zone, status);
1426 SimpleDateFormat *sdf = new SimpleDateFormat(pattern,status);
1427 if (U_FAILURE(status)) {
1428 dataerrln("Error constructing SimpleDateFormat");
1429 delete cal;
1430 delete sdf;
1431 return;
1432 }
1433 cal->set(2007, 1, 14);
1434 UDate date = cal->getTime(status);
1435 if (U_FAILURE(status)) {
1436 errln("Error getting time to format");
1437 return;
1438 }
1439 sdf->adoptCalendar(cal);
1440 UnicodeString result;
1441 UnicodeString correct("-0330", "");
1442 sdf->format(date, result);
1443 if (result != correct) {
1444 errln("\nError: Newfoundland Z of Jan 14, 2007 gave '" + result + "', expected '" + correct + "'");
1445 }
1446 delete sdf;
1447 }
1448
Test9237(void)1449 void DateFormatRegressionTest::Test9237(void)
1450 {
1451 UErrorCode status = U_ZERO_ERROR;
1452 UnicodeString pattern("VVVV");
1453
1454 SimpleDateFormat fmt(pattern, status); // default locale
1455 SimpleDateFormat fmtDE(pattern, Locale("de_DE"), status);
1456 if (U_FAILURE(status)) {
1457 dataerrln("Error constructing SimpleDateFormat");
1458 return;
1459 }
1460
1461 // copy constructor
1462 SimpleDateFormat fmtCopyDE(fmtDE);
1463 UnicodeString resDE, resCopyDE;
1464
1465 fmtDE.format(0.0, resDE);
1466 fmtCopyDE.format(0.0, resCopyDE);
1467
1468 if (resDE != resCopyDE) {
1469 errln(UnicodeString("Error: different result by the copied instance - org:") + resDE + " copy:" + resCopyDE);
1470 }
1471
1472 // test for assignment operator
1473 fmt = fmtDE;
1474
1475 UnicodeString resAssigned;
1476 fmt.format(0.0, resAssigned);
1477
1478 if (resDE != resAssigned) {
1479 errln(UnicodeString("Error: different results by the assigned instance - org:") + resDE + " assigned:" + resAssigned);
1480 }
1481 }
1482
TestParsing(void)1483 void DateFormatRegressionTest::TestParsing(void) {
1484 UErrorCode status = U_ZERO_ERROR;
1485 UnicodeString pattern("EEE-WW-MMMM-yyyy");
1486 UnicodeString text("mon-02-march-2011");
1487 int32_t expectedDay = 7;
1488
1489 SimpleDateFormat format(pattern, status);
1490 if (U_FAILURE(status)) {
1491 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
1492 return;
1493 }
1494
1495 Calendar *cal = new GregorianCalendar(status);
1496 if (cal == NULL || U_FAILURE(status)) {
1497 errln("Unable to create calendar - %s", u_errorName(status));
1498 return;
1499 }
1500
1501 ParsePosition pos(0);
1502 format.parse(text, *cal, pos);
1503
1504 if (cal->get(UCAL_DAY_OF_MONTH, status) != expectedDay) {
1505 errln("Parsing failed: day of month should be '7' with pattern: \"" + pattern + "\" for text: \"" + text + "\"");
1506 }
1507
1508 delete cal;
1509 }
1510
Test12902_yWithGregoCalInThaiLoc(void)1511 void DateFormatRegressionTest::Test12902_yWithGregoCalInThaiLoc(void) {
1512 UErrorCode status = U_ZERO_ERROR;
1513 UDate testDate = 43200000.0; // 1970-Jan-01 12:00 GMT
1514 const char* skeleton = "y";
1515 // Note that in locale "th", the availableFormats for skeleton "y" differ by calendar:
1516 // for buddhist (default calendar): y{"G y"}
1517 // for gregorian: y{"y"}
1518 const char* expectFormat = "1970"; // format for skeleton y in Thai locale with Gregorian calendar
1519 UnicodeString getFmtStr;
1520
1521 const TimeZone* gmtZone = TimeZone::getGMT();
1522 LocalPointer<GregorianCalendar> pureGregoCal(new GregorianCalendar(*gmtZone, Locale::getEnglish(), status));
1523 if (U_FAILURE(status)) {
1524 dataerrln("Fail in new GregorianCalendar(GMT, en): %s", u_errorName(status));
1525 return;
1526 }
1527 LocalPointer<DateFormat> df1(DateFormat::createInstanceForSkeleton(pureGregoCal.orphan(), skeleton, "th", status));
1528 if (U_FAILURE(status)) {
1529 dataerrln("Fail in DateFormat::createInstanceForSkeleton for th with Grego cal: %s", u_errorName(status));
1530 return;
1531 }
1532 status = U_ZERO_ERROR;
1533 getFmtStr.remove();
1534 getFmtStr = df1->format(testDate, getFmtStr);
1535 if (U_FAILURE(status)) {
1536 errln("Fail in DateFormat::format for th with Grego cal: %s", u_errorName(status));
1537 } else if (getFmtStr != expectFormat) {
1538 char getFormat[32];
1539 getFmtStr.extract(0, getFmtStr.length(), getFormat, 32);
1540 errln("Error in DateFormat::format for th with Grego cal, expect: %s, get: %s", expectFormat, getFormat);
1541 }
1542
1543 LocalPointer<DateFormat> df2(DateFormat::createInstanceForSkeleton(skeleton, "th-u-ca-gregory", status));
1544 if (U_FAILURE(status)) {
1545 dataerrln("Fail in DateFormat::createInstanceForSkeleton for th-u-ca-gregory: %s", u_errorName(status));
1546 return;
1547 }
1548 status = U_ZERO_ERROR;
1549 getFmtStr.remove();
1550 getFmtStr = df2->format(testDate, getFmtStr);
1551 if (U_FAILURE(status)) {
1552 errln("Fail in DateFormat::format for th-u-ca-gregory: %s", u_errorName(status));
1553 } else if (getFmtStr != expectFormat) {
1554 char getFormat[32];
1555 getFmtStr.extract(0, getFmtStr.length(), getFormat, 32);
1556 errln("Error in DateFormat::format for th with Grego cal, expect: %s, get: %s", expectFormat, getFormat);
1557 }
1558 }
1559
TestT10334(void)1560 void DateFormatRegressionTest::TestT10334(void) {
1561 UErrorCode status = U_ZERO_ERROR;
1562 UnicodeString pattern("'--: 'EEE-WW-MMMM-yyyy");
1563 UnicodeString text("--mon-02-march-2011");
1564 SimpleDateFormat format(pattern, status);
1565
1566 logln("pattern["+pattern+"] text["+text+"]");
1567
1568 if (U_FAILURE(status)) {
1569 dataerrln("Fail creating SimpleDateFormat object - %s", u_errorName(status));
1570 return;
1571 }
1572
1573 format.setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, FALSE, status);
1574 format.parse(text, status);
1575 if (!U_FAILURE(status)) {
1576 errln("parse partial match did NOT fail in strict mode - %s", u_errorName(status));
1577 }
1578
1579 status = U_ZERO_ERROR;
1580 format.setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, TRUE, status);
1581 format.parse(text, status);
1582 if (U_FAILURE(status)) {
1583 errln("parse partial match failure in lenient mode - %s", u_errorName(status));
1584 }
1585
1586 status = U_ZERO_ERROR;
1587 pattern = UnicodeString("YYYY MM dd");
1588 text = UnicodeString("2013 12 10");
1589 format.applyPattern(pattern);
1590 UDate referenceDate = format.parse(text, status);
1591
1592 FieldPosition fp(FieldPosition::DONT_CARE);
1593 UnicodeString formattedString("");
1594 pattern = UnicodeString("YYYY LL dd ee cc qq QQ");
1595 format.applyPattern(pattern);
1596 format.format(referenceDate, formattedString, fp, status);
1597 logln("ref date: " + formattedString);
1598
1599
1600 char patternArray[] = "YYYY LLL dd eee ccc qqq QQQ";
1601 pattern = UnicodeString(patternArray);
1602 text = UnicodeString("2013 12 10 03 3 04 04");
1603 status = U_ZERO_ERROR;
1604 format.setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, TRUE, status);
1605 format.applyPattern(pattern);
1606 ParsePosition pp(0);
1607 format.parse(text, pp);
1608 if (pp.getErrorIndex() != -1) {
1609 errln("numeric parse error");
1610 }
1611
1612 status = U_ZERO_ERROR;
1613 format.setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, FALSE, status);
1614 format.parse(text, status);
1615 if (!U_FAILURE(status)) {
1616 errln("numeric parse did NOT fail in strict mode", u_errorName(status));
1617 }
1618
1619 }
1620
1621
1622 typedef struct {
1623 const char * locale;
1624 UBool leniency;
1625 UnicodeString parseString;
1626 UnicodeString pattern;
1627 UnicodeString expectedResult; // null indicates expected error
1628 } TestDateFormatLeniencyItem;
1629
1630
TestT10619(void)1631 void DateFormatRegressionTest::TestT10619(void) {
1632 const UDate july022008 = 1215000001979.0;
1633 const TestDateFormatLeniencyItem items[] = {
1634 //locale leniency parse String pattern expected result
1635 { "en", true, UnicodeString("2008-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2008-July 02") },
1636 { "en", false, UnicodeString("2008-07 03"), UnicodeString("yyyy-LLLL dd"), UnicodeString("") },
1637 { "en", true, UnicodeString("2008-Jan. 04"), UnicodeString("yyyy-LLL dd"), UnicodeString("2008-Jan 04") },
1638 { "en", false, UnicodeString("2008-Jan. 05"), UnicodeString("yyyy-LLL dd"), UnicodeString("") },
1639 { "en", true, UnicodeString("2008-Jan--06"), UnicodeString("yyyy-MMM -- dd"), UnicodeString("2008-Jan 06") },
1640 { "en", false, UnicodeString("2008-Jan--07"), UnicodeString("yyyy-MMM -- dd"), UnicodeString("") },
1641 { "en", true, UnicodeString("6 Jan 08 2008"), UnicodeString("eee MMM dd yyyy"), UnicodeString("Sat Jan 08 2008") },
1642 { "en", false, UnicodeString("6 Jan 09 2008"), UnicodeString("eee MMM dd yyyy"), UnicodeString("") },
1643 // terminator
1644 { NULL, true, UnicodeString(""), UnicodeString(""), UnicodeString("") }
1645 };
1646 UErrorCode status = U_ZERO_ERROR;
1647 Calendar* cal = Calendar::createInstance(status);
1648 if (U_FAILURE(status)) {
1649 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
1650 } else {
1651 cal->setTime(july022008, status);
1652 const TestDateFormatLeniencyItem * itemPtr;
1653 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
1654
1655 Locale locale = Locale::createFromName(itemPtr->locale);
1656 status = U_ZERO_ERROR;
1657 ParsePosition pos(0);
1658 SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status);
1659 if (U_FAILURE(status)) {
1660 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
1661 continue;
1662 }
1663 logln("parsing " + itemPtr->parseString);
1664 sdmft->setLenient(itemPtr->leniency);
1665 sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status);
1666 sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status);
1667 sdmft->setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, itemPtr->leniency, status);
1668 sdmft->parse(itemPtr->parseString, pos);
1669
1670 delete sdmft;
1671 if(pos.getErrorIndex() > -1) {
1672 if(itemPtr->expectedResult.length() != 0) {
1673 errln("error: unexpected error - " + itemPtr->parseString + " - error index " + pos.getErrorIndex() +
1674 " - leniency " + itemPtr->leniency);
1675 continue;
1676 } else {
1677 continue;
1678 }
1679 }
1680 }
1681 }
1682 delete cal;
1683
1684 }
1685
1686
1687 typedef struct {
1688 UnicodeString text;
1689 UnicodeString pattern;
1690 int initialParsePos;
1691 } T10855Data;
1692
TestT10855(void)1693 void DateFormatRegressionTest::TestT10855(void) {
1694 // NOTE: these should NOT parse
1695 const T10855Data items[] = {
1696 //parse String pattern initial parse pos
1697 { UnicodeString("September 30, 1998"), UnicodeString("MM-dd-yyyy"), 0},
1698 { UnicodeString("123-73-1950"), UnicodeString("MM-dd-yyyy"), -1},
1699 { UnicodeString("12-23-1950"), UnicodeString("MM-dd-yyyy"), -1},
1700 // terminator
1701 { UnicodeString(""), UnicodeString(""), 0}
1702 };
1703 UErrorCode status = U_ZERO_ERROR;
1704
1705 int x = 0;
1706 while(items[x].pattern.length() > 0)
1707 {
1708 status = U_ZERO_ERROR;
1709 logln("Date to parse: \""+items[x].text+"\"");
1710 logln("Starting Index: %d", items[x].initialParsePos);
1711
1712 SimpleDateFormat dateFmt(items[x].pattern, status);
1713 if(U_FAILURE(status)) {
1714 errcheckln(status, "Failed dateFmt: %s", u_errorName(status));
1715 ++x;
1716 continue;
1717 }
1718 status = U_ZERO_ERROR;
1719
1720 dateFmt.setLenient(false);
1721 dateFmt.setTimeZone(*TimeZone::getGMT());
1722
1723 ParsePosition position(items[x].initialParsePos);
1724 logln("set position is now: %d", position.getIndex());
1725 UDate d = dateFmt.parse(items[x].text, position);
1726 if (position.getErrorIndex() != -1 || position.getIndex() == items[x].initialParsePos) {
1727 logln("Parse Failed. ErrorIndex is %d - Index is %d", position.getErrorIndex(), position.getIndex());
1728 } else {
1729 errln("Parse Succeeded...should have failed. Index is %d - ErrorIndex is %d", position.getIndex(), position.getErrorIndex());
1730 }
1731 logln("Parsed date returns %d\n", d);
1732
1733 ++x;
1734 }
1735 }
1736
TestT10906(void)1737 void DateFormatRegressionTest::TestT10906(void) {
1738
1739 UErrorCode status = U_ZERO_ERROR;
1740 UnicodeString pattern = "MM-dd-yyyy";
1741 UnicodeString text = "06-10-2014";
1742 SimpleDateFormat format(pattern, status);
1743 int32_t errorIdx = 0;
1744 ParsePosition pp(-1);
1745 format.parse(text, pp);
1746 errorIdx = pp.getErrorIndex();
1747 if (errorIdx == -1) {
1748 errln("failed to report invalid (negative) starting parse position");
1749 }
1750 }
1751
TestT13380(void)1752 void DateFormatRegressionTest::TestT13380(void) {
1753 UErrorCode errorCode = U_ZERO_ERROR;
1754 LocalPointer<DateFormat> enFmt(DateFormat::createDateInstance(DateFormat::kShort, Locale("en")), errorCode);
1755 if (U_FAILURE(errorCode)) {
1756 errln("failure creating 'en' DateFormat");
1757 }
1758
1759 errorCode = U_ZERO_ERROR;
1760 LocalPointer<DateFormat> tgFmt(DateFormat::createDateInstance(DateFormat::kShort, Locale("tg")), errorCode);
1761 if (U_FAILURE(errorCode)) {
1762 errln("failure creating 'tg' DateFormat");
1763 }
1764 }
1765
TestT10858(void)1766 void DateFormatRegressionTest::TestT10858(void) {
1767 // test for assignment operator on instances with the same locale but different TimeZoneFormat
1768 UErrorCode status = U_ZERO_ERROR;
1769 UnicodeString pattern("VVVV");
1770 Locale loc("en_US");
1771
1772 // Make two identical Formats
1773 SimpleDateFormat fmt_rhs(pattern, loc, status);
1774 SimpleDateFormat fmt_lhs(pattern, loc, status);
1775
1776 // Setup a custom TimeZoneFormat
1777 TimeZoneFormat* tzFmt = TimeZoneFormat::createInstance(Locale("de_DE"), status);
1778 tzFmt->setGMTPattern(UnicodeString("UTC{0}"), status);
1779 tzFmt->setGMTZeroFormat(UnicodeString("UTC"), status);
1780
1781 // Set custom TimeZoneFormat in fmt1 before assignment. Use
1782 // adoptTimeZoneFormat instead of setTimeZoneFormat to delegate
1783 // cleanup of tzFmt to SimpleDateFormat
1784 fmt_rhs.adoptTimeZoneFormat(tzFmt);
1785
1786 // Make sure TimeZoneFormat is DIFFERENT between fmt_lhs & fmt_rhs at this point.
1787 // Direct comparison with TimeZoneFormat::operator== does not suffice as it only
1788 // checks for 'semantically equal' rather than 'identical' -- compare results of
1789 // SimpleDateFormat::format() instead
1790 UnicodeString res_rhs; fmt_rhs.format(0.0, res_rhs);
1791 UnicodeString res_lhs_pre_assign; fmt_lhs.format(0.0, res_lhs_pre_assign);
1792 if (res_lhs_pre_assign == res_rhs) {
1793 errln(UnicodeString("Error: adoptTimeZoneFormat failed to set custom TimeZoneFormat into 'fmt_rhs'"));
1794 }
1795
1796 // Invoke assignment operator and make sure formatted outputs from both objects are
1797 // now identical (i.e. TimeZoneFormat, among other members, is correctly copied to LHS)
1798 fmt_lhs = fmt_rhs;
1799 UnicodeString res_lhs_post_assign; fmt_lhs.format(0.0, res_lhs_post_assign);
1800 if (res_lhs_post_assign != res_rhs) {
1801 errln(UnicodeString("Error: assigned instance did not take up TimeZoneFormat from original"));
1802 }
1803 }
1804
1805 #endif /* #if !UCONFIG_NO_FORMATTING */
1806
1807 //eof
1808