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