1 /********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING
12 #include "unicode/timezone.h"
13 #include "unicode/gregocal.h"
14 #include "unicode/smpdtfmt.h"
15 #include "unicode/datefmt.h"
16 #include "unicode/simpletz.h"
17 #include "unicode/strenum.h"
18 #include "unicode/dtfmtsym.h"
21 #include "caltest.h" // for fieldName
22 // *****************************************************************************
23 // class DateFormatTest
24 // *****************************************************************************
26 void DateFormatTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
28 // if (exec) logln((UnicodeString)"TestSuite DateFormatTest");
30 TESTCASE(0,TestEquals
);
31 TESTCASE(1,TestTwoDigitYearDSTParse
);
32 TESTCASE(2,TestFieldPosition
);
33 TESTCASE(3,TestPartialParse994
);
34 TESTCASE(4,TestRunTogetherPattern985
);
35 TESTCASE(5,TestRunTogetherPattern917
);
36 TESTCASE(6,TestCzechMonths459
);
37 TESTCASE(7,TestLetterDPattern212
);
38 TESTCASE(8,TestDayOfYearPattern195
);
39 TESTCASE(9,TestQuotePattern161
);
40 TESTCASE(10,TestBadInput135
);
41 TESTCASE(11,TestBadInput135a
);
42 TESTCASE(12,TestTwoDigitYear
);
43 TESTCASE(13,TestDateFormatZone061
);
44 TESTCASE(14,TestDateFormatZone146
);
45 TESTCASE(15,TestLocaleDateFormat
);
46 TESTCASE(16,TestWallyWedel
);
47 TESTCASE(17,TestDateFormatCalendar
);
48 TESTCASE(18,TestSpaceParsing
);
49 TESTCASE(19,TestExactCountFormat
);
50 TESTCASE(20,TestWhiteSpaceParsing
);
51 TESTCASE(21,TestInvalidPattern
);
52 TESTCASE(22,TestGeneral
);
53 TESTCASE(23,TestGreekMay
);
54 default: name
= ""; break;
58 // Test written by Wally Wedel and emailed to me.
59 void DateFormatTest::TestWallyWedel()
61 UErrorCode status
= U_ZERO_ERROR
;
63 * Instantiate a TimeZone so we can get the ids.
65 TimeZone
*tz
= new SimpleTimeZone(7,"");
67 * Computational variables.
69 int32_t offset
, hours
, minutes
;
71 * Instantiate a SimpleDateFormat set up to produce a full time
74 SimpleDateFormat
*sdf
= new SimpleDateFormat((UnicodeString
)"zzzz", status
);
76 * A String array for the time zone ids.
79 StringEnumeration
* ids
= TimeZone::createEnumeration();
80 ids_length
= ids
->count(status
);
82 * How many ids do we have?
84 logln("Time Zone IDs size: %d", ids_length
);
86 * Column headings (sort of)
88 logln("Ordinal ID offset(h:m) name");
90 * Loop through the tzs.
92 UDate today
= Calendar::getNow();
93 Calendar
*cal
= Calendar::createInstance(status
);
94 for (int32_t i
= 0; i
< ids_length
; i
++) {
95 // logln(i + " " + ids[i]);
96 const UnicodeString
* id
= ids
->snext(status
);
97 TimeZone
*ttz
= TimeZone::createTimeZone(*id
);
98 // offset = ttz.getRawOffset();
99 cal
->setTimeZone(*ttz
);
100 cal
->setTime(today
, status
);
101 offset
= cal
->get(UCAL_ZONE_OFFSET
, status
) + cal
->get(UCAL_DST_OFFSET
, status
);
102 // logln(i + " " + ids[i] + " offset " + offset);
103 const char* sign
= "+";
108 hours
= offset
/3600000;
109 minutes
= (offset%3600000
)/60000;
110 UnicodeString dstOffset
= (UnicodeString
)"" + sign
+ (hours
< 10 ? "0" : "") +
111 (int32_t)hours
+ ":" + (minutes
< 10 ? "0" : "") + (int32_t)minutes
;
113 * Instantiate a date so we can display the time zone name.
115 sdf
->setTimeZone(*ttz
);
119 UnicodeString fmtOffset
;
120 FieldPosition
pos(0);
121 sdf
->format(today
,fmtOffset
, pos
);
122 // UnicodeString fmtOffset = tzS.toString();
123 UnicodeString
*fmtDstOffset
= 0;
124 if (fmtOffset
.startsWith("GMT"))
126 //fmtDstOffset = fmtOffset->substring(3);
127 fmtDstOffset
= new UnicodeString();
128 fmtOffset
.extract(3, fmtOffset
.length(), *fmtDstOffset
);
133 UBool ok
= fmtDstOffset
== 0 || *fmtDstOffset
== dstOffset
;
136 logln(UnicodeString() + i
+ " " + *id
+ " " + dstOffset
+
138 (fmtDstOffset
!= 0 ? " ok" : " ?"));
142 errln(UnicodeString() + i
+ " " + *id
+ " " + dstOffset
+
143 " " + fmtOffset
+ " *** FAIL ***");
149 // delete ids; // TODO: BAD API
155 // -------------------------------------
161 DateFormatTest::TestEquals()
163 DateFormat
* fmtA
= DateFormat::createDateTimeInstance(DateFormat::MEDIUM
, DateFormat::FULL
);
164 DateFormat
* fmtB
= DateFormat::createDateTimeInstance(DateFormat::MEDIUM
, DateFormat::FULL
);
165 if (!(*fmtA
== *fmtB
)) errln((UnicodeString
)"FAIL");
170 // -------------------------------------
173 * Test the parsing of 2-digit years.
176 DateFormatTest::TestTwoDigitYearDSTParse(void)
178 UErrorCode status
= U_ZERO_ERROR
;
179 SimpleDateFormat
* fullFmt
= new SimpleDateFormat((UnicodeString
)"EEE MMM dd HH:mm:ss.SSS zzz yyyy G", status
);
180 SimpleDateFormat
*fmt
= new SimpleDateFormat((UnicodeString
)"dd-MMM-yy h:mm:ss 'o''clock' a z", Locale::getEnglish(), status
);
181 //DateFormat* fmt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, Locale::ENGLISH);
182 UnicodeString
* s
= new UnicodeString("03-Apr-04 2:20:47 o'clock AM PST", "");
186 UDate d
= fmt
->parse(*s
, status
);
187 logln(*s
+ " P> " + ((DateFormat
*)fullFmt
)->format(d
, str
));
188 int32_t y
, m
, day
, hr
, min
, sec
;
189 dateToFields(d
, y
, m
, day
, hr
, min
, sec
);
191 errln((UnicodeString
)"FAIL: Should parse to hour " + hour
);
193 if (U_FAILURE(status
))
194 errln((UnicodeString
)"FAIL: " + (int32_t)status
);
201 // -------------------------------------
203 UChar
toHexString(int32_t i
) { return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10))); }
206 DateFormatTest::escape(UnicodeString
& s
)
209 for (int32_t i
=0; i
<s
.length(); ++i
)
211 UChar c
= s
[(int32_t)i
];
212 if (c
<= (UChar
)0x7F) buf
+= c
;
214 buf
+= (UChar
)0x5c; buf
+= (UChar
)0x55;
215 buf
+= toHexString((c
& 0xF000) >> 12);
216 buf
+= toHexString((c
& 0x0F00) >> 8);
217 buf
+= toHexString((c
& 0x00F0) >> 4);
218 buf
+= toHexString(c
& 0x000F);
224 // -------------------------------------
227 * This MUST be kept in sync with DateFormatSymbols.gPatternChars.
229 static const char* PATTERN_CHARS
= "GyMdkHmsSEDFwWahKzYeugAZ";
232 * A list of the names of all the fields in DateFormat.
233 * This MUST be kept in sync with DateFormat.
235 static const char* DATEFORMAT_FIELD_NAMES
[] = {
240 "HOUR_OF_DAY1_FIELD",
241 "HOUR_OF_DAY0_FIELD",
247 "DAY_OF_WEEK_IN_MONTH_FIELD",
248 "WEEK_OF_YEAR_FIELD",
249 "WEEK_OF_MONTH_FIELD",
256 "EXTENDED_YEAR_FIELD",
258 "MILLISECONDS_IN_DAY_FIELD",
262 static const int32_t DATEFORMAT_FIELD_NAMES_LENGTH
=
263 sizeof(DATEFORMAT_FIELD_NAMES
) / sizeof(DATEFORMAT_FIELD_NAMES
[0]);
266 * Verify that returned field position indices are correct.
268 void DateFormatTest::TestFieldPosition() {
269 UErrorCode ec
= U_ZERO_ERROR
;
274 DateFormatSymbols
rootSyms(Locale(""), ec
);
275 assertSuccess("DateFormatSymbols", ec
);
276 assertEquals("patternChars", PATTERN_CHARS
, rootSyms
.getLocalPatternChars(buf
));
277 assertEquals("patternChars", PATTERN_CHARS
, DateFormatSymbols::getPatternUChars());
278 assertTrue("DATEFORMAT_FIELD_NAMES", DATEFORMAT_FIELD_NAMES_LENGTH
== UDAT_FIELD_COUNT
);
279 assertTrue("Data", UDAT_FIELD_COUNT
== uprv_strlen(PATTERN_CHARS
));
281 // Create test formatters
282 const int32_t COUNT
= 4;
283 DateFormat
* dateFormats
[COUNT
];
284 dateFormats
[0] = DateFormat::createDateTimeInstance(DateFormat::kFull
, DateFormat::kFull
, Locale::getUS());
285 dateFormats
[1] = DateFormat::createDateTimeInstance(DateFormat::kFull
, DateFormat::kFull
, Locale::getFrance());
286 // Make the pattern "G y M d..."
287 buf
.remove().append(PATTERN_CHARS
);
288 for (j
=buf
.length()-1; j
>=0; --j
) buf
.insert(j
, (UChar
)32/*' '*/);
289 dateFormats
[2] = new SimpleDateFormat(buf
, Locale::getUS(), ec
);
290 // Make the pattern "GGGG yyyy MMMM dddd..."
291 for (j
=buf
.length()-1; j
>=0; j
-=2) {
292 for (i
=0; i
<3; ++i
) {
293 buf
.insert(j
, buf
.charAt(j
));
296 dateFormats
[3] = new SimpleDateFormat(buf
, Locale::getUS(), ec
);
298 UDate aug13
= 871508052513.0;
300 // Expected output field values for above DateFormats on aug13
301 // Fields are given in order of DateFormat field number
302 const char* EXPECTED
[] = {
303 "", "1997", "August", "13", "", "", "34", "12", "",
304 "Wednesday", "", "", "", "", "PM", "2", "", "PDT", "", "", "", "", "", "",
306 "", "1997", "ao\\u00FBt", "13", "", "14", "34", "", "",
307 "mercredi", "", "", "", "", "", "", "", "HAP (\\u00C9UA)", "", "", "", "", "", "",
309 "AD", "1997", "8", "13", "14", "14", "34", "12", "5",
310 "Wed", "225", "2", "33", "3", "PM", "2", "2", "PDT", "1997", "4", "1997", "2450674", "52452513", "-0700",
312 "AD", "1997", "August", "0013", "0014", "0014", "0034", "0012", "5130",
313 "Wednesday", "0225", "0002", "0033", "0003", "PM", "0002", "0002", "Pacific Daylight Time", "1997", "0004", "1997", "2450674", "52452513", "-0700",
316 const int32_t EXPECTED_LENGTH
= sizeof(EXPECTED
)/sizeof(EXPECTED
[0]);
318 assertTrue("data size", EXPECTED_LENGTH
== COUNT
* UDAT_FIELD_COUNT
);
320 TimeZone
* PT
= TimeZone::createTimeZone("America/Los_Angeles");
321 for (j
= 0, exp
= 0; j
< COUNT
; ++j
) {
323 DateFormat
* df
= dateFormats
[j
];
324 df
->setTimeZone(*PT
);
325 if (df
->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
326 logln(" Pattern = " + ((SimpleDateFormat
*) df
)->toPattern(buf
.remove()));
328 logln(" Pattern = ? (not a SimpleDateFormat)");
330 logln((UnicodeString
)" Result = " + df
->format(aug13
, buf
.remove()));
332 for (i
= 0; i
< UDAT_FIELD_COUNT
; ++i
, ++exp
) {
333 FieldPosition
pos(i
);
334 df
->format(aug13
, buf
.remove(), pos
);
336 buf
.extractBetween(pos
.getBeginIndex(), pos
.getEndIndex(), field
);
337 assertEquals((UnicodeString
)"field #" + i
+ " " + DATEFORMAT_FIELD_NAMES
[i
],
338 ctou(EXPECTED
[exp
]), field
);
342 for (i
=0; i
<COUNT
; ++i
) {
343 delete dateFormats
[i
];
348 // -------------------------------------
351 * General parse/format tests. Add test cases as needed.
353 void DateFormatTest::TestGeneral() {
354 const char* DATA
[] = {
355 "yyyy MM dd HH:mm:ss.SSS",
357 // Milliseconds are left-justified, since they format as fractions of a second
358 "y/M/d H:mm:ss.S", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.6", "2004 03 10 16:36:31.600",
359 "y/M/d H:mm:ss.SS", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.57", "2004 03 10 16:36:31.570",
360 "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567",
361 "y/M/d H:mm:ss.SSSS", "pf", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.568", "2004/3/10 16:36:31.5680",
363 expect(DATA
, sizeof(DATA
)/sizeof(DATA
[0]), Locale("en", "", ""));
366 // -------------------------------------
369 * Verify that strings which contain incomplete specifications are parsed
370 * correctly. In some instances, this means not being parsed at all, and
371 * returning an appropriate error.
374 DateFormatTest::TestPartialParse994()
376 UErrorCode status
= U_ZERO_ERROR
;
377 SimpleDateFormat
* f
= new SimpleDateFormat(status
);
379 tryPat994(f
, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", date(97, 1 - 1, 17, 10, 11, 42));
380 tryPat994(f
, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null
);
381 tryPat994(f
, "yy/MM/dd HH:mm:ss", "97/01/17 10", null
);
382 tryPat994(f
, "yy/MM/dd HH:mm:ss", "97/01/17 ", null
);
383 tryPat994(f
, "yy/MM/dd HH:mm:ss", "97/01/17", null
);
384 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
388 // -------------------------------------
391 DateFormatTest::tryPat994(SimpleDateFormat
* format
, const char* pat
, const char* str
, UDate expected
)
393 UErrorCode status
= U_ZERO_ERROR
;
395 logln(UnicodeString("Pattern \"") + pat
+ "\" String \"" + str
+ "\"");
397 format
->applyPattern(pat
);
398 UDate date
= format
->parse(str
, status
);
399 if (U_FAILURE(status
) || date
== null
)
401 logln((UnicodeString
)"ParseException: " + (int32_t)status
);
402 if (expected
!= null
) errln((UnicodeString
)"FAIL: Expected " + dateToString(expected
));
407 ((DateFormat
*)format
)->format(date
, f
);
408 logln(UnicodeString(" parse(") + str
+ ") -> " + dateToString(date
));
409 logln((UnicodeString
)" format -> " + f
);
410 if (expected
== null
||
411 !(date
== expected
)) errln((UnicodeString
)"FAIL: Expected null");//" + expected);
412 if (!(f
== str
)) errln(UnicodeString("FAIL: Expected ") + str
);
415 //catch(ParseException e) {
416 // logln((UnicodeString)"ParseException: " + e.getMessage());
417 // if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
419 //catch(Exception e) {
420 // errln((UnicodeString)"*** Exception:");
421 // e.printStackTrace();
425 // -------------------------------------
428 * Verify the behavior of patterns in which digits for different fields run together
429 * without intervening separators.
432 DateFormatTest::TestRunTogetherPattern985()
434 UErrorCode status
= U_ZERO_ERROR
;
435 UnicodeString
format("yyyyMMddHHmmssSSS");
436 UnicodeString now
, then
;
438 SimpleDateFormat
*formatter
= new SimpleDateFormat(format
, status
);
439 UDate date1
= Calendar::getNow();
440 ((DateFormat
*)formatter
)->format(date1
, now
);
442 ParsePosition
pos(0);
443 UDate date2
= formatter
->parse(now
, pos
);
444 if (date2
== 0) then
= "Parse stopped at " + pos
.getIndex();
445 else ((DateFormat
*)formatter
)->format(date2
, then
);
447 if (!(date2
== date1
)) errln((UnicodeString
)"FAIL");
449 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
452 // -------------------------------------
455 * Verify the behavior of patterns in which digits for different fields run together
456 * without intervening separators.
459 DateFormatTest::TestRunTogetherPattern917()
461 UErrorCode status
= U_ZERO_ERROR
;
462 SimpleDateFormat
* fmt
;
463 UnicodeString myDate
;
464 fmt
= new SimpleDateFormat((UnicodeString
)"yyyy/MM/dd", status
);
465 myDate
= "1997/02/03";
466 testIt917(fmt
, myDate
, date(97, 2 - 1, 3));
468 fmt
= new SimpleDateFormat((UnicodeString
)"yyyyMMdd", status
);
470 testIt917(fmt
, myDate
, date(97, 3 - 1, 4));
472 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
475 // -------------------------------------
478 DateFormatTest::testIt917(SimpleDateFormat
* fmt
, UnicodeString
& str
, UDate expected
)
480 UErrorCode status
= U_ZERO_ERROR
;
481 UnicodeString pattern
;
482 logln((UnicodeString
)"pattern=" + fmt
->toPattern(pattern
) + " string=" + str
);
485 ((Format
*)fmt
)->parseObject(str
, o
, status
);
487 if (U_FAILURE(status
)) return;
488 //catch(ParseException e) {
489 // e.printStackTrace();
492 logln((UnicodeString
)"Parsed object: " + dateToString(o
.getDate()));
493 if (!(o
.getDate() == expected
)) errln((UnicodeString
)"FAIL: Expected " + dateToString(expected
));
494 UnicodeString formatted
; ((Format
*)fmt
)->format(o
, formatted
, status
);
495 logln((UnicodeString
)"Formatted string: " + formatted
);
496 if (!(formatted
== str
)) errln((UnicodeString
)"FAIL: Expected " + str
);
497 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
500 // -------------------------------------
503 * Verify the handling of Czech June and July, which have the unique attribute that
504 * one is a proper prefix substring of the other.
507 DateFormatTest::TestCzechMonths459()
509 UErrorCode status
= U_ZERO_ERROR
;
510 DateFormat
* fmt
= DateFormat::createDateInstance(DateFormat::FULL
, Locale("cs", "", ""));
511 UnicodeString pattern
;
512 logln((UnicodeString
)"Pattern " + ((SimpleDateFormat
*) fmt
)->toPattern(pattern
));
513 UDate june
= date(97, UCAL_JUNE
, 15);
514 UDate july
= date(97, UCAL_JULY
, 15);
515 UnicodeString juneStr
; fmt
->format(june
, juneStr
);
516 UnicodeString julyStr
; fmt
->format(july
, julyStr
);
518 logln((UnicodeString
)"format(June 15 1997) = " + juneStr
);
519 UDate d
= fmt
->parse(juneStr
, status
);
520 UnicodeString s
; fmt
->format(d
, s
);
521 int32_t month
,yr
,day
,hr
,min
,sec
; dateToFields(d
,yr
,month
,day
,hr
,min
,sec
);
522 logln((UnicodeString
)" -> parse -> " + s
+ " (month = " + month
+ ")");
523 if (month
!= UCAL_JUNE
) errln((UnicodeString
)"FAIL: Month should be June");
524 logln((UnicodeString
)"format(July 15 1997) = " + julyStr
);
525 d
= fmt
->parse(julyStr
, status
);
527 dateToFields(d
,yr
,month
,day
,hr
,min
,sec
);
528 logln((UnicodeString
)" -> parse -> " + s
+ " (month = " + month
+ ")");
529 if (month
!= UCAL_JULY
) errln((UnicodeString
)"FAIL: Month should be July");
531 //catch(ParseException e) {
532 if (U_FAILURE(status
))
533 errln((UnicodeString
)"Exception: " + (int32_t)status
);
538 // -------------------------------------
541 * Test the handling of 'D' in patterns.
544 DateFormatTest::TestLetterDPattern212()
546 UErrorCode status
= U_ZERO_ERROR
;
547 UnicodeString
dateString("1995-040.05:01:29");
548 UnicodeString
bigD("yyyy-DDD.hh:mm:ss");
549 UnicodeString
littleD("yyyy-ddd.hh:mm:ss");
550 UDate expLittleD
= date(95, 0, 1, 5, 1, 29);
551 UDate expBigD
= expLittleD
+ 39 * 24 * 3600000.0;
552 expLittleD
= expBigD
; // Expect the same, with default lenient parsing
553 logln((UnicodeString
)"dateString= " + dateString
);
554 SimpleDateFormat
*formatter
= new SimpleDateFormat(bigD
, status
);
555 ParsePosition
pos(0);
556 UDate myDate
= formatter
->parse(dateString
, pos
);
557 logln((UnicodeString
)"Using " + bigD
+ " -> " + myDate
);
558 if (myDate
!= expBigD
) errln((UnicodeString
)"FAIL: Expected " + dateToString(expBigD
));
560 formatter
= new SimpleDateFormat(littleD
, status
);
561 pos
= ParsePosition(0);
562 myDate
= formatter
->parse(dateString
, pos
);
563 logln((UnicodeString
)"Using " + littleD
+ " -> " + dateToString(myDate
));
564 if (myDate
!= expLittleD
) errln((UnicodeString
)"FAIL: Expected " + dateToString(expLittleD
));
566 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
569 // -------------------------------------
572 * Test the day of year pattern.
575 DateFormatTest::TestDayOfYearPattern195()
577 UErrorCode status
= U_ZERO_ERROR
;
578 UDate today
= Calendar::getNow();
579 int32_t year
,month
,day
,hour
,min
,sec
; dateToFields(today
,year
,month
,day
,hour
,min
,sec
);
580 UDate expected
= date(year
, month
, day
);
581 logln((UnicodeString
)"Test Date: " + dateToString(today
));
582 SimpleDateFormat
* sdf
= (SimpleDateFormat
*)DateFormat::createDateInstance();
583 tryPattern(*sdf
, today
, 0, expected
);
584 tryPattern(*sdf
, today
, "G yyyy DDD", expected
);
586 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
589 // -------------------------------------
592 DateFormatTest::tryPattern(SimpleDateFormat
& sdf
, UDate d
, const char* pattern
, UDate expected
)
594 UErrorCode status
= U_ZERO_ERROR
;
595 if (pattern
!= 0) sdf
.applyPattern(pattern
);
596 UnicodeString thePat
;
597 logln((UnicodeString
)"pattern: " + sdf
.toPattern(thePat
));
598 UnicodeString formatResult
; (*(DateFormat
*)&sdf
).format(d
, formatResult
);
599 logln((UnicodeString
)" format -> " + formatResult
);
601 UDate d2
= sdf
.parse(formatResult
, status
);
602 logln((UnicodeString
)" parse(" + formatResult
+ ") -> " + dateToString(d2
));
603 if (d2
!= expected
) errln((UnicodeString
)"FAIL: Expected " + dateToString(expected
));
604 UnicodeString format2
; (*(DateFormat
*)&sdf
).format(d2
, format2
);
605 logln((UnicodeString
)" format -> " + format2
);
606 if (!(formatResult
== format2
)) errln((UnicodeString
)"FAIL: Round trip drift");
608 //catch(Exception e) {
609 if (U_FAILURE(status
))
610 errln((UnicodeString
)"Error: " + (int32_t)status
);
614 // -------------------------------------
617 * Test the handling of single quotes in patterns.
620 DateFormatTest::TestQuotePattern161()
622 UErrorCode status
= U_ZERO_ERROR
;
623 SimpleDateFormat
* formatter
= new SimpleDateFormat((UnicodeString
)"MM/dd/yyyy 'at' hh:mm:ss a zzz", status
);
624 UDate currentTime_1
= date(97, UCAL_AUGUST
, 13, 10, 42, 28);
625 UnicodeString dateString
; ((DateFormat
*)formatter
)->format(currentTime_1
, dateString
);
626 UnicodeString
exp("08/13/1997 at 10:42:28 AM ");
627 logln((UnicodeString
)"format(" + dateToString(currentTime_1
) + ") = " + dateString
);
628 if (0 != dateString
.compareBetween(0, exp
.length(), exp
, 0, exp
.length())) errln((UnicodeString
)"FAIL: Expected " + exp
);
630 if (U_FAILURE(status
)) errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
633 // -------------------------------------
636 * Verify the correct behavior when handling invalid input strings.
639 DateFormatTest::TestBadInput135()
641 UErrorCode status
= U_ZERO_ERROR
;
642 DateFormat::EStyle looks
[] = {
643 DateFormat::SHORT
, DateFormat::MEDIUM
, DateFormat::LONG
, DateFormat::FULL
645 int32_t looks_length
= (int32_t)(sizeof(looks
) / sizeof(looks
[0]));
646 const char* strings
[] = {
647 "Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
649 int32_t strings_length
= (int32_t)(sizeof(strings
) / sizeof(strings
[0]));
650 DateFormat
*full
= DateFormat::createDateTimeInstance(DateFormat::LONG
, DateFormat::LONG
);
651 UnicodeString
expected("March 1, 2000 1:23:45 AM ");
652 for (int32_t i
= 0; i
< strings_length
;++i
) {
653 const char* text
= strings
[i
];
654 for (int32_t j
= 0; j
< looks_length
;++j
) {
655 DateFormat::EStyle dateLook
= looks
[j
];
656 for (int32_t k
= 0; k
< looks_length
;++k
) {
657 DateFormat::EStyle timeLook
= looks
[k
];
658 DateFormat
*df
= DateFormat::createDateTimeInstance(dateLook
, timeLook
);
659 UnicodeString prefix
= UnicodeString(text
) + ", " + dateLook
+ "/" + timeLook
+ ": ";
661 UDate when
= df
->parse(text
, status
);
662 if (when
== 0 && U_SUCCESS(status
)) {
663 errln(prefix
+ "SHOULD NOT HAPPEN: parse returned 0.");
666 if (U_SUCCESS(status
))
668 UnicodeString format
;
669 full
->format(when
, format
);
670 logln(prefix
+ "OK: " + format
);
671 if (0!=format
.compareBetween(0, expected
.length(), expected
, 0, expected
.length()))
672 errln((UnicodeString
)"FAIL: Expected " + expected
+ " got " + format
);
675 //catch(ParseException e) {
677 status
= U_ZERO_ERROR
;
679 //catch(StringIndexOutOfBoundsException e) {
680 // errln(prefix + "SHOULD NOT HAPPEN: " + (int)status);
687 if (U_FAILURE(status
))
688 errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
691 const char* DateFormatTest::parseFormats
[] = {
700 "h:mm a MMMM d, yyyy"
703 const char* DateFormatTest::inputStrings
[] = {
704 "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
705 "April 1, 1997", "April 1, 1997", 0, 0, 0, 0, 0, "April 1", 0, 0,
706 "Jan 1, 1970", "January 1, 1970", 0, 0, 0, 0, 0, "January 1", 0, 0,
707 "Jan 1 2037", 0, "January 1 2037", 0, 0, 0, 0, "January 1", 0, 0,
708 "1/1/70", 0, 0, "1/1/70", 0, 0, 0, 0, "0001", 0,
709 "5 May 1997", 0, 0, 0, 0, "5 May 1997", "5 May", 0, "0005", 0,
710 "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
711 "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
712 "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
713 "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
714 "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
717 // -------------------------------------
720 * Verify the correct behavior when parsing an array of inputs against an
721 * array of patterns, with known results. The results are encoded after
722 * the input strings in each row.
725 DateFormatTest::TestBadInput135a()
727 UErrorCode status
= U_ZERO_ERROR
;
728 SimpleDateFormat
* dateParse
= new SimpleDateFormat(status
);
729 if(U_FAILURE(status
)) {
730 errln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status
));
736 const uint32_t PF_LENGTH
= (int32_t)(sizeof(parseFormats
)/sizeof(parseFormats
[0]));
737 const uint32_t INPUT_LENGTH
= (int32_t)(sizeof(inputStrings
)/sizeof(inputStrings
[0]));
739 dateParse
->applyPattern("d MMMM, yyyy");
740 dateParse
->adoptTimeZone(TimeZone::createDefault());
742 UnicodeString thePat
;
743 logln(UnicodeString("Trying to parse \"") + s
+ "\" with " + dateParse
->toPattern(thePat
));
745 date
= dateParse
->parse(s
, status
);
746 if (U_SUCCESS(status
))
747 errln((UnicodeString
)"FAIL: Expected exception during parse");
749 //catch(Exception ex) {
751 logln((UnicodeString
)"Exception during parse: " + (int32_t)status
);
752 status
= U_ZERO_ERROR
;
754 for (uint32_t i
= 0; i
< INPUT_LENGTH
; i
+= (PF_LENGTH
+ 1)) {
755 ParsePosition
parsePosition(0);
756 UnicodeString
s( inputStrings
[i
]);
757 for (uint32_t index
= 0; index
< PF_LENGTH
;++index
) {
758 const char* expected
= inputStrings
[i
+ 1 + index
];
759 dateParse
->applyPattern(parseFormats
[index
]);
760 dateParse
->adoptTimeZone(TimeZone::createDefault());
762 parsePosition
.setIndex(0);
763 date
= dateParse
->parse(s
, parsePosition
);
764 if (parsePosition
.getIndex() != 0) {
765 UnicodeString s1
, s2
;
766 s
.extract(0, parsePosition
.getIndex(), s1
);
767 s
.extract(parsePosition
.getIndex(), s
.length(), s2
);
769 errln((UnicodeString
)"ERROR: null result fmt=\"" +
770 parseFormats
[index
] +
771 "\" pos=" + parsePosition
.getIndex() + " " +
775 UnicodeString result
;
776 ((DateFormat
*)dateParse
)->format(date
, result
);
777 logln((UnicodeString
)"Parsed \"" + s
+ "\" using \"" + dateParse
->toPattern(thePat
) + "\" to: " + result
);
779 errln((UnicodeString
)"FAIL: Expected parse failure");
780 else if (!(result
== expected
))
781 errln(UnicodeString("FAIL: Expected ") + expected
);
784 else if (expected
!= 0) {
785 errln(UnicodeString("FAIL: Expected ") + expected
+ " from \"" +
786 s
+ "\" with \"" + dateParse
->toPattern(thePat
) + "\"");
789 //catch(Exception ex) {
790 if (U_FAILURE(status
))
791 errln((UnicodeString
)"An exception was thrown during parse: " + (int32_t)status
);
796 if (U_FAILURE(status
))
797 errln((UnicodeString
)"FAIL: UErrorCode received during test: " + (int32_t)status
);
800 // -------------------------------------
803 * Test the parsing of two-digit years.
806 DateFormatTest::TestTwoDigitYear()
808 UErrorCode ec
= U_ZERO_ERROR
;
809 SimpleDateFormat
fmt("dd/MM/yy", Locale::getUK(), ec
);
811 errln("FAIL: SimpleDateFormat constructor");
814 parse2DigitYear(fmt
, "5/6/17", date(117, UCAL_JUNE
, 5));
815 parse2DigitYear(fmt
, "4/6/34", date(34, UCAL_JUNE
, 4));
818 // -------------------------------------
821 DateFormatTest::parse2DigitYear(DateFormat
& fmt
, const char* str
, UDate expected
)
823 UErrorCode status
= U_ZERO_ERROR
;
825 UDate d
= fmt
.parse(str
, status
);
826 UnicodeString thePat
;
827 logln(UnicodeString("Parsing \"") + str
+ "\" with " + ((SimpleDateFormat
*)&fmt
)->toPattern(thePat
) +
828 " => " + dateToString(d
));
829 if (d
!= expected
) errln((UnicodeString
)"FAIL: Expected " + expected
);
831 //catch(ParseException e) {
832 if (U_FAILURE(status
))
833 errln((UnicodeString
)"FAIL: Got exception");
837 // -------------------------------------
840 * Test the formatting of time zones.
843 DateFormatTest::TestDateFormatZone061()
845 UErrorCode status
= U_ZERO_ERROR
;
847 DateFormat
*formatter
;
848 date
= 859248000000.0;
849 logln((UnicodeString
)"Date 1997/3/25 00:00 GMT: " + date
);
850 formatter
= new SimpleDateFormat((UnicodeString
)"dd-MMM-yyyyy HH:mm", Locale::getUK(), status
);
851 if(U_FAILURE(status
)) {
852 errln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status
));
856 formatter
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
857 UnicodeString temp
; formatter
->format(date
, temp
);
858 logln((UnicodeString
)"Formatted in GMT to: " + temp
);
860 UDate tempDate
= formatter
->parse(temp
, status
);
861 logln((UnicodeString
)"Parsed to: " + dateToString(tempDate
));
862 if (tempDate
!= date
) errln((UnicodeString
)"FAIL: Expected " + dateToString(date
));
864 //catch(Throwable t) {
865 if (U_FAILURE(status
))
866 errln((UnicodeString
)"Date Formatter throws: " + (int32_t)status
);
871 // -------------------------------------
874 * Test the formatting of time zones.
877 DateFormatTest::TestDateFormatZone146()
879 TimeZone
*saveDefault
= TimeZone::createDefault();
882 TimeZone
*thedefault
= TimeZone::createTimeZone("GMT");
883 TimeZone::setDefault(*thedefault
);
884 // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
886 // check to be sure... its GMT all right
887 TimeZone
*testdefault
= TimeZone::createDefault();
888 UnicodeString testtimezone
;
889 testdefault
->getID(testtimezone
);
890 if (testtimezone
== "GMT")
891 logln("Test timezone = " + testtimezone
);
893 errln("Test timezone should be GMT, not " + testtimezone
);
895 UErrorCode status
= U_ZERO_ERROR
;
896 // now try to use the default GMT time zone
897 GregorianCalendar
*greenwichcalendar
=
898 new GregorianCalendar(1997, 3, 4, 23, 0, status
);
899 failure(status
, "new GregorianCalendar");
900 //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
901 //greenwichcalendar.set(1997, 3, 4, 23, 0);
902 // try anything to set hour to 23:00 !!!
903 greenwichcalendar
->set(UCAL_HOUR_OF_DAY
, 23);
905 UDate greenwichdate
= greenwichcalendar
->getTime(status
);
907 UnicodeString DATA
[] = {
908 UnicodeString("simple format: "), UnicodeString("04/04/97 23:00 GMT"),
909 UnicodeString("MM/dd/yy HH:mm z"),
910 UnicodeString("full format: "), UnicodeString("Friday, April 4, 1997 11:00:00 o'clock PM GMT"),
911 UnicodeString("EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z"),
912 UnicodeString("long format: "), UnicodeString("April 4, 1997 11:00:00 PM GMT"),
913 UnicodeString("MMMM d, yyyy h:mm:ss a z"),
914 UnicodeString("default format: "), UnicodeString("04-Apr-97 11:00:00 PM"),
915 UnicodeString("dd-MMM-yy h:mm:ss a"),
916 UnicodeString("short format: "), UnicodeString("4/4/97 11:00 PM"),
917 UnicodeString("M/d/yy h:mm a")
919 int32_t DATA_length
= (int32_t)(sizeof(DATA
) / sizeof(DATA
[0]));
921 for (int32_t i
=0; i
<DATA_length
; i
+=3) {
922 DateFormat
*fmt
= new SimpleDateFormat(DATA
[i
+2], Locale::getEnglish(), status
);
923 if(failure(status
, "new SimpleDateFormat")) break;
924 fmt
->setCalendar(*greenwichcalendar
);
925 UnicodeString result
;
926 result
= fmt
->format(greenwichdate
, result
);
927 logln(DATA
[i
] + result
);
928 if (result
!= DATA
[i
+1])
929 errln("FAIL: Expected " + DATA
[i
+1] + ", got " + result
);
934 TimeZone::adoptDefault(saveDefault
);
937 delete greenwichcalendar
;
943 // -------------------------------------
946 * Test the formatting of dates in different locales.
949 DateFormatTest::TestLocaleDateFormat() // Bug 495
951 UDate testDate
= date(97, UCAL_SEPTEMBER
, 15);
952 DateFormat
*dfFrench
= DateFormat::createDateTimeInstance(DateFormat::FULL
,
953 DateFormat::FULL
, Locale::getFrench());
954 DateFormat
*dfUS
= DateFormat::createDateTimeInstance(DateFormat::FULL
,
955 DateFormat::FULL
, Locale::getUS());
956 UnicodeString
expectedFRENCH ( "lundi 15 septembre 1997 00 h 00 HAP (\\u00C9UA)" );
957 expectedFRENCH
= expectedFRENCH
.unescape();
958 //UnicodeString expectedUS ( "Monday, September 15, 1997 12:00:00 o'clock AM PDT" );
959 UnicodeString
expectedUS ( "Monday, September 15, 1997 12:00:00 AM PDT" );
960 logln((UnicodeString
)"Date set to : " + dateToString(testDate
));
962 dfFrench
->format(testDate
, out
);
963 logln((UnicodeString
)"Date Formated with French Locale " + out
);
964 if (!(out
== expectedFRENCH
))
965 errln((UnicodeString
)"FAIL: Expected " + expectedFRENCH
);
967 dfUS
->format(testDate
, out
);
968 logln((UnicodeString
)"Date Formated with US Locale " + out
);
969 if (!(out
== expectedUS
))
970 errln((UnicodeString
)"FAIL: Expected " + expectedUS
);
976 * Test DateFormat(Calendar) API
978 void DateFormatTest::TestDateFormatCalendar() {
979 DateFormat
*date
=0, *time
=0, *full
=0;
984 UErrorCode ec
= U_ZERO_ERROR
;
986 /* Create a formatter for date fields. */
987 date
= DateFormat::createDateInstance(DateFormat::kShort
, Locale::getUS());
989 errln("FAIL: createDateInstance failed");
993 /* Create a formatter for time fields. */
994 time
= DateFormat::createTimeInstance(DateFormat::kShort
, Locale::getUS());
996 errln("FAIL: createTimeInstance failed");
1000 /* Create a full format for output */
1001 full
= DateFormat::createDateTimeInstance(DateFormat::kFull
, DateFormat::kFull
,
1004 errln("FAIL: createInstance failed");
1008 /* Create a calendar */
1009 cal
= Calendar::createInstance(Locale::getUS(), ec
);
1010 if (cal
== NULL
|| U_FAILURE(ec
)) {
1011 errln((UnicodeString
)"FAIL: Calendar::createInstance failed with " +
1016 /* Parse the date */
1018 str
= UnicodeString("4/5/2001", "");
1020 date
->parse(str
, *cal
, pos
);
1021 if (pos
.getIndex() != str
.length()) {
1022 errln((UnicodeString
)"FAIL: DateFormat::parse(4/5/2001) failed at " +
1027 /* Parse the time */
1028 str
= UnicodeString("5:45 PM", "");
1030 time
->parse(str
, *cal
, pos
);
1031 if (pos
.getIndex() != str
.length()) {
1032 errln((UnicodeString
)"FAIL: DateFormat::parse(17:45) failed at " +
1038 when
= cal
->getTime(ec
);
1039 if (U_FAILURE(ec
)) {
1040 errln((UnicodeString
)"FAIL: cal->getTime() failed with " + u_errorName(ec
));
1044 full
->format(when
, str
);
1045 // Thursday, April 5, 2001 5:45:00 PM PDT 986517900000
1046 if (when
== 986517900000.0) {
1047 logln("Ok: Parsed result: " + str
);
1049 errln("FAIL: Parsed result: " + str
+ ", exp 4/5/2001 5:45 PM");
1060 * Test DateFormat's parsing of space characters. See jitterbug 1916.
1062 void DateFormatTest::TestSpaceParsing() {
1063 const char* DATA
[] = {
1064 "yyyy MM dd HH:mm:ss",
1066 // pattern, input, expected parse or NULL if expect parse failure
1067 "MMMM d yy", " 04 05 06", NULL
, // MMMM wants Apr/April
1068 NULL
, "04 05 06", NULL
,
1069 "MM d yy", " 04 05 06", "2006 04 05 00:00:00",
1070 NULL
, "04 05 06", "2006 04 05 00:00:00",
1071 "MMMM d yy", " Apr 05 06", "2006 04 05 00:00:00",
1072 NULL
, "Apr 05 06", "2006 04 05 00:00:00",
1074 const int32_t DATA_len
= sizeof(DATA
)/sizeof(DATA
[0]);
1076 expectParse(DATA
, DATA_len
, Locale("en"));
1080 * Test handling of "HHmmss" pattern.
1082 void DateFormatTest::TestExactCountFormat() {
1083 const char* DATA
[] = {
1084 "yyyy MM dd HH:mm:ss",
1086 // pattern, input, expected parse or NULL if expect parse failure
1087 "HHmmss", "123456", "1970 01 01 12:34:56",
1088 NULL
, "12345", "1970 01 01 01:23:45",
1090 NULL
, "00-05", NULL
,
1091 NULL
, "12-34", NULL
,
1092 NULL
, "00+05", NULL
,
1093 "ahhmm", "PM730", "1970 01 01 19:30:00",
1095 const int32_t DATA_len
= sizeof(DATA
)/sizeof(DATA
[0]);
1097 expectParse(DATA
, DATA_len
, Locale("en"));
1101 * Test handling of white space.
1103 void DateFormatTest::TestWhiteSpaceParsing() {
1104 const char* DATA
[] = {
1107 // pattern, input, expected parse or null if expect parse failure
1109 // Pattern space run should parse input text space run
1110 "MM d yy", " 04 01 03", "2003 04 01",
1111 NULL
, " 04 01 03 ", "2003 04 01",
1113 const int32_t DATA_len
= sizeof(DATA
)/sizeof(DATA
[0]);
1115 expectParse(DATA
, DATA_len
, Locale("en"));
1119 void DateFormatTest::TestInvalidPattern() {
1120 UErrorCode ec
= U_ZERO_ERROR
;
1121 SimpleDateFormat
f(UnicodeString("Yesterday"), ec
);
1124 f
.format((UDate
)0, out
, pos
);
1126 // The bug is that the call to format() will crash. By not
1127 // crashing, the test passes.
1130 void DateFormatTest::TestGreekMay() {
1131 UErrorCode ec
= U_ZERO_ERROR
;
1132 UDate date
= -9896080848000.0;
1133 SimpleDateFormat
fmt("EEEE, dd MMMM yyyy h:mm:ss a", Locale("el", "", ""), ec
);
1134 if (!assertSuccess("SimpleDateFormat::ct", ec
)) return;
1136 fmt
.format(date
, str
);
1137 ParsePosition
pos(0);
1138 UDate d2
= fmt
.parse(str
, pos
);
1140 errln("FAIL: unable to parse strings where case-folding changes length");
1145 * Test parsing. Input is an array that starts with the following
1148 * [0] = pattern string to parse [i+2] with
1150 * followed by test cases, each of which is 3 array elements:
1152 * [i] = pattern, or NULL to reuse prior pattern
1153 * [i+1] = input string
1154 * [i+2] = expected parse result (parsed with pattern [0])
1156 * If expect parse failure, then [i+2] should be NULL.
1158 void DateFormatTest::expectParse(const char** data
, int32_t data_length
,
1159 const Locale
& loc
) {
1160 const UDate FAIL
= (UDate
) -1;
1161 const UnicodeString
FAIL_STR("parse failure");
1164 UErrorCode ec
= U_ZERO_ERROR
;
1165 SimpleDateFormat
fmt("", loc
, ec
);
1166 SimpleDateFormat
ref(data
[i
++], loc
, ec
);
1167 SimpleDateFormat
gotfmt("G yyyy MM dd HH:mm:ss z", loc
, ec
);
1168 if (U_FAILURE(ec
)) {
1169 errln("FAIL: SimpleDateFormat constructor");
1173 const char* currentPat
= NULL
;
1174 while (i
<data_length
) {
1175 const char* pattern
= data
[i
++];
1176 const char* input
= data
[i
++];
1177 const char* expected
= data
[i
++];
1180 if (pattern
!= NULL
) {
1181 fmt
.applyPattern(pattern
);
1182 currentPat
= pattern
;
1184 UDate got
= fmt
.parse(input
, ec
);
1185 UnicodeString
gotstr(FAIL_STR
);
1186 if (U_FAILURE(ec
)) {
1190 gotfmt
.format(got
, gotstr
);
1193 UErrorCode ec2
= U_ZERO_ERROR
;
1195 UnicodeString
expstr(FAIL_STR
);
1196 if (expected
!= NULL
) {
1198 exp
= ref
.parse(expstr
, ec2
);
1199 if (U_FAILURE(ec2
)) {
1200 // This only happens if expected is in wrong format --
1201 // should never happen once test is debugged.
1202 errln("FAIL: Internal test error");
1208 logln((UnicodeString
)"Ok: " + input
+ " x " +
1209 currentPat
+ " => " + gotstr
);
1211 errln((UnicodeString
)"FAIL: " + input
+ " x " +
1212 currentPat
+ " => " + gotstr
+ ", expected " +
1219 * Test formatting and parsing. Input is an array that starts
1220 * with the following header:
1222 * [0] = pattern string to parse [i+2] with
1224 * followed by test cases, each of which is 3 array elements:
1226 * [i] = pattern, or null to reuse prior pattern
1227 * [i+1] = control string, either "fp", "pf", or "F".
1228 * [i+2..] = data strings
1230 * The number of data strings depends on the control string.
1232 * 1. "y/M/d H:mm:ss.SS", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.56", "2004 03 10 16:36:31.560",
1233 * 'f': Format date [i+2] (as parsed using pattern [0]) and expect string [i+3].
1234 * 'p': Parse string [i+3] and expect date [i+4].
1236 * 2. "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567"
1237 * 'F': Format date [i+2] and expect string [i+3],
1238 * then parse string [i+3] and expect date [i+2].
1240 * 3. "y/M/d H:mm:ss.SSSS", "pf", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.5670",
1241 * 'p': Parse string [i+2] and expect date [i+3].
1242 * 'f': Format date [i+3] and expect string [i+4].
1244 void DateFormatTest::expect(const char** data
, int32_t data_length
,
1245 const Locale
& loc
) {
1247 UErrorCode ec
= U_ZERO_ERROR
;
1248 UnicodeString str
, str2
;
1249 SimpleDateFormat
fmt("", loc
, ec
);
1250 SimpleDateFormat
ref(data
[i
++], loc
, ec
);
1251 SimpleDateFormat
univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc
, ec
);
1252 if (!assertSuccess("construct SimpleDateFormat", ec
)) return;
1254 UnicodeString currentPat
;
1255 while (i
<data_length
) {
1256 const char* pattern
= data
[i
++];
1257 if (pattern
!= NULL
) {
1258 fmt
.applyPattern(pattern
);
1259 currentPat
= pattern
;
1262 const char* control
= data
[i
++];
1264 if (uprv_strcmp(control
, "fp") == 0) {
1266 const char* datestr
= data
[i
++];
1267 const char* string
= data
[i
++];
1268 UDate date
= ref
.parse(datestr
, ec
);
1269 if (!assertSuccess("parse", ec
)) return;
1270 assertEquals((UnicodeString
)"\"" + currentPat
+ "\".format(" + datestr
+ ")",
1272 fmt
.format(date
, str
.remove()));
1274 datestr
= data
[i
++];
1275 date
= ref
.parse(datestr
, ec
);
1276 if (!assertSuccess("parse", ec
)) return;
1277 UDate parsedate
= fmt
.parse(string
, ec
);
1278 if (assertSuccess((UnicodeString
)"\"" + currentPat
+ "\".parse(" + string
+ ")", ec
)) {
1279 assertEquals((UnicodeString
)"\"" + currentPat
+ "\".parse(" + string
+ ")",
1280 univ
.format(date
, str
.remove()),
1281 univ
.format(parsedate
, str2
.remove()));
1285 else if (uprv_strcmp(control
, "pf") == 0) {
1287 const char* string
= data
[i
++];
1288 const char* datestr
= data
[i
++];
1289 UDate date
= ref
.parse(datestr
, ec
);
1290 if (!assertSuccess("parse", ec
)) return;
1291 UDate parsedate
= fmt
.parse(string
, ec
);
1292 if (assertSuccess((UnicodeString
)"\"" + currentPat
+ "\".parse(" + string
+ ")", ec
)) {
1293 assertEquals((UnicodeString
)"\"" + currentPat
+ "\".parse(" + string
+ ")",
1294 univ
.format(date
, str
.remove()),
1295 univ
.format(parsedate
, str2
.remove()));
1299 assertEquals((UnicodeString
)"\"" + currentPat
+ "\".format(" + datestr
+ ")",
1301 fmt
.format(date
, str
.remove()));
1304 else if (uprv_strcmp(control
, "F") == 0) {
1305 const char* datestr
= data
[i
++];
1306 const char* string
= data
[i
++];
1307 UDate date
= ref
.parse(datestr
, ec
);
1308 if (!assertSuccess("parse", ec
)) return;
1309 assertEquals((UnicodeString
)"\"" + currentPat
+ "\".format(" + datestr
+ ")",
1311 fmt
.format(date
, str
.remove()));
1313 UDate parsedate
= fmt
.parse(string
, ec
);
1314 if (assertSuccess((UnicodeString
)"\"" + currentPat
+ "\".parse(" + string
+ ")", ec
)) {
1315 assertEquals((UnicodeString
)"\"" + currentPat
+ "\".parse(" + string
+ ")",
1316 univ
.format(date
, str
.remove()),
1317 univ
.format(parsedate
, str2
.remove()));
1322 errln((UnicodeString
)"FAIL: Invalid control string " + control
);
1328 #endif /* #if !UCONFIG_NO_FORMATTING */