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