]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/dtfmttst.cpp
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / test / intltest / dtfmttst.cpp
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2003, 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 "dtfmttst.h"
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 "cmemory.h"
19
20// *****************************************************************************
21// class DateFormatTest
22// *****************************************************************************
23
24void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
25{
26 // if (exec) logln((UnicodeString)"TestSuite DateFormatTest");
27 switch (index) {
28 TESTCASE(0,TestEquals);
29 TESTCASE(1,TestTwoDigitYearDSTParse);
30 TESTCASE(2,TestFieldPosition);
31 TESTCASE(3,TestPartialParse994);
32 TESTCASE(4,TestRunTogetherPattern985);
33 TESTCASE(5,TestRunTogetherPattern917);
34 TESTCASE(6,TestCzechMonths459);
35 TESTCASE(7,TestLetterDPattern212);
36 TESTCASE(8,TestDayOfYearPattern195);
37 TESTCASE(9,TestQuotePattern161);
38 TESTCASE(10,TestBadInput135);
39 TESTCASE(11,TestBadInput135a);
40 TESTCASE(12,TestTwoDigitYear);
41 TESTCASE(13,TestDateFormatZone061);
42 TESTCASE(14,TestDateFormatZone146);
43 TESTCASE(15,TestLocaleDateFormat);
44 TESTCASE(16,TestWallyWedel);
45 TESTCASE(17,TestDateFormatCalendar);
46 TESTCASE(18,TestSpaceParsing);
47 TESTCASE(19,TestExactCountFormat);
48 TESTCASE(20,TestWhiteSpaceParsing);
49 default: name = ""; break;
50 }
51}
52
53// Test written by Wally Wedel and emailed to me.
54void DateFormatTest::TestWallyWedel()
55{
56 UErrorCode status = U_ZERO_ERROR;
57 /*
58 * Instantiate a TimeZone so we can get the ids.
59 */
60 TimeZone *tz = new SimpleTimeZone(7,"");
61 /*
62 * Computational variables.
63 */
64 int32_t offset, hours, minutes;
65 /*
66 * Instantiate a SimpleDateFormat set up to produce a full time
67 zone name.
68 */
69 SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)"zzzz", status);
70 /*
71 * A String array for the time zone ids.
72 */
73 int32_t ids_length;
74 StringEnumeration* ids = TimeZone::createEnumeration();
75 ids_length = ids->count(status);
76 /*
77 * How many ids do we have?
78 */
79 logln("Time Zone IDs size: %d", ids_length);
80 /*
81 * Column headings (sort of)
82 */
83 logln("Ordinal ID offset(h:m) name");
84 /*
85 * Loop through the tzs.
86 */
87 UDate today = Calendar::getNow();
88 Calendar *cal = Calendar::createInstance(status);
89 for (int32_t i = 0; i < ids_length; i++) {
90 // logln(i + " " + ids[i]);
91 const UnicodeString* id = ids->snext(status);
92 TimeZone *ttz = TimeZone::createTimeZone(*id);
93 // offset = ttz.getRawOffset();
94 cal->setTimeZone(*ttz);
95 cal->setTime(today, status);
96 offset = cal->get(UCAL_ZONE_OFFSET, status) + cal->get(UCAL_DST_OFFSET, status);
97 // logln(i + " " + ids[i] + " offset " + offset);
98 const char* sign = "+";
99 if (offset < 0) {
100 sign = "-";
101 offset = -offset;
102 }
103 hours = offset/3600000;
104 minutes = (offset%3600000)/60000;
105 UnicodeString dstOffset = (UnicodeString)"" + sign + (hours < 10 ? "0" : "") +
106 (int32_t)hours + ":" + (minutes < 10 ? "0" : "") + (int32_t)minutes;
107 /*
108 * Instantiate a date so we can display the time zone name.
109 */
110 sdf->setTimeZone(*ttz);
111 /*
112 * Format the output.
113 */
114 UnicodeString fmtOffset;
115 FieldPosition pos(0);
116 sdf->format(today,fmtOffset, pos);
117 // UnicodeString fmtOffset = tzS.toString();
118 UnicodeString *fmtDstOffset = 0;
119 if (fmtOffset.startsWith("GMT"))
120 {
121 //fmtDstOffset = fmtOffset->substring(3);
122 fmtDstOffset = new UnicodeString();
123 fmtOffset.extract(3, fmtOffset.length(), *fmtDstOffset);
124 }
125 /*
126 * Show our result.
127 */
128 UBool ok = fmtDstOffset == 0 || *fmtDstOffset == dstOffset;
129 if (ok)
130 {
131 logln(UnicodeString() + i + " " + *id + " " + dstOffset +
132 " " + fmtOffset +
133 (fmtDstOffset != 0 ? " ok" : " ?"));
134 }
135 else
136 {
137 errln(UnicodeString() + i + " " + *id + " " + dstOffset +
138 " " + fmtOffset + " *** FAIL ***");
139 }
140 delete ttz;
141 delete fmtDstOffset;
142 }
143 delete cal;
144 // delete ids; // TODO: BAD API
145 delete ids;
146 delete sdf;
147 delete tz;
148}
149
150// -------------------------------------
151
152/**
153 * Test operator==
154 */
155void
156DateFormatTest::TestEquals()
157{
158 DateFormat* fmtA = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
159 DateFormat* fmtB = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
160 if (!(*fmtA == *fmtB)) errln((UnicodeString)"FAIL");
161 delete fmtA;
162 delete fmtB;
163}
164
165// -------------------------------------
166
167/**
168 * Test the parsing of 2-digit years.
169 */
170void
171DateFormatTest::TestTwoDigitYearDSTParse(void)
172{
173 UErrorCode status = U_ZERO_ERROR;
174 SimpleDateFormat* fullFmt = new SimpleDateFormat((UnicodeString)"EEE MMM dd HH:mm:ss.SSS zzz yyyy G", status);
175 SimpleDateFormat *fmt = new SimpleDateFormat((UnicodeString)"dd-MMM-yy h:mm:ss 'o''clock' a z", Locale::getEnglish(), status);
176 //DateFormat* fmt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, Locale::ENGLISH);
177 UnicodeString* s = new UnicodeString("03-Apr-04 2:20:47 o'clock AM PST", "");
178 int32_t hour = 2;
179
180 UnicodeString str;
181 UDate d = fmt->parse(*s, status);
182 logln(*s + " P> " + ((DateFormat*)fullFmt)->format(d, str));
183 int32_t y, m, day, hr, min, sec;
184 dateToFields(d, y, m, day, hr, min, sec);
185 if (hr != hour)
186 errln((UnicodeString)"FAIL: Should parse to hour " + hour);
187
188 if (U_FAILURE(status))
189 errln((UnicodeString)"FAIL: " + (int32_t)status);
190
191 delete s;
192 delete fmt;
193 delete fullFmt;
194}
195
196// -------------------------------------
197
198UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
199
200UnicodeString&
201DateFormatTest::escape(UnicodeString& s)
202{
203 UnicodeString buf;
204 for (int32_t i=0; i<s.length(); ++i)
205 {
206 UChar c = s[(int32_t)i];
207 if (c <= (UChar)0x7F) buf += c;
208 else {
209 buf += (UChar)0x5c; buf += (UChar)0x55;
210 buf += toHexString((c & 0xF000) >> 12);
211 buf += toHexString((c & 0x0F00) >> 8);
212 buf += toHexString((c & 0x00F0) >> 4);
213 buf += toHexString(c & 0x000F);
214 }
215 }
216 return (s = buf);
217}
218
219const char* DateFormatTest::fieldNames[] = {
220 "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
221 "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR",
222 "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", //"DST_OFFSET",
223 "YEAR_WOY", "DOW_LOCAL"
224};
225
226// -------------------------------------
227
228// Map Calendar field number to to DateFormat field number
229const DateFormat::EField
230DateFormatTest::fgCalendarToDateFormatField[] = {
231 DateFormat::kEraField,
232 DateFormat::kYearField,
233 DateFormat::kMonthField,
234 DateFormat::kWeekOfYearField,
235 DateFormat::kWeekOfMonthField,
236 DateFormat::kDateField,
237 DateFormat::kDayOfYearField,
238 DateFormat::kDayOfWeekField,
239 DateFormat::kDayOfWeekInMonthField,
240 DateFormat::kAmPmField,
241 DateFormat::kHour1Field,
242 DateFormat::kHourOfDay0Field,
243 DateFormat::kMinuteField,
244 DateFormat::kSecondField,
245 DateFormat::kMillisecondField,
246 DateFormat::kTimezoneField,
247 DateFormat::kYearWOYField,
248 DateFormat::kDOWLocalField,
249 (DateFormat::EField) -1
250};
251
252/**
253 * Verify that returned field position indices are correct.
254 */
255void
256DateFormatTest::TestFieldPosition(void)
257{
258 UErrorCode status = U_ZERO_ERROR;
259 DateFormat* dateFormats[4];
260 int32_t dateFormats_length = (int32_t)(sizeof(dateFormats) / sizeof(dateFormats[0]));
261
262 /* {sfb} This test was coded incorrectly.
263 / FieldPosition uses the fields in the class you are formatting with
264 / So, for example, to get the DATE field from a DateFormat use
265 / DateFormat::DATE_FIELD, __not__ Calendar::DATE
266 / The ordering of the expected values used previously was wrong.
267 / instead of re-ordering this mess of strings, just transform the index values */
268
269 /* field values, in Calendar order */
270
271 const char* expected[] = {
272 "", "1997", "August", "", "", "13", "", "Wednesday", "", "PM", "2", "",
273 "34", "12", "", "PDT", "",
274 /* Following two added by weiv for two new fields */ "", "",
275 "", "1997", "#",/* # is a marker for "ao\xfbt" == "aou^t" */ "", "", "13", "", "mercredi",
276 "", "", "", "14", "34", "", "", "GMT-07:00", "",
277 /* Following two added by weiv for two new fields */ "", "",
278 "AD", "97", "8", "33", "3", "13", "225", "Wed", "2", "PM", "2",
279 "14", "34", "12", "5", "PDT",
280 /* Following two added by weiv for two new fields */ "97", "4", "",
281 "AD", "1997", "August", "0033",
282 "0003", "0013", "0225", "Wednesday", "0002", "PM", "0002", "0014",
283 "0034", "0012", "513", "Pacific Daylight Time",
284 /* Following two added by weiv for two new fields */ "1997", "0004",
285 ""
286
287 };
288
289 UDate someDate = 871508052513.0;
290 int32_t j, exp;
291
292 dateFormats[0] = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, Locale::getUS());
293 dateFormats[1] = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, Locale::getFrance());
294 dateFormats[2] = new SimpleDateFormat((UnicodeString)"G, yy, M, d, k, H, m, s, S, E, D, F, w, W, a, h, K, z, YY, e", status);
295 dateFormats[3] = new SimpleDateFormat((UnicodeString)"GGGG, yyyy, MMMM, dddd, kkkk, HHHH, mmmm, ssss, SSSS, EEEE, DDDD, FFFF, wwww, WWWW, aaaa, hhhh, KKKK, zzzz, YYYY, eeee", status);
296 for (j = 0, exp = 0; j < dateFormats_length;++j) {
297 UnicodeString str;
298 DateFormat* df = dateFormats[j];
299 logln((UnicodeString)" Pattern = " + ((SimpleDateFormat*)df)->toPattern(str));
300 str.truncate(0);
301 logln((UnicodeString)" Result = " + df->format(someDate, str));
302 for (int32_t i = 0; i < UCAL_FIELD_COUNT;++i) {
303 UnicodeString field;
304 getFieldText(df, i, someDate, field);
305 UnicodeString expStr;
306 if(expected[exp][0]!='#') {
307 expStr=UnicodeString(expected[exp]);
308 } else {
309 /* we cannot have latin-1 characters in source code, therefore we fix up the string for "aou^t" */
310 expStr.append((UChar)0x61).append((UChar)0x6f).append((UChar32)0xfb).append((UChar)0x74);
311 }
312
313 if (!(field == expStr)) errln(UnicodeString("FAIL: field #") + i + " " +
314 fieldNames[i] + " = \"" + escape(field) + "\", expected \"" + escape(expStr) + "\"");
315 ++exp;
316 }
317 }
318 for (j=0; j<dateFormats_length; ++j) delete dateFormats[j];
319 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
320}
321
322// -------------------------------------
323
324void
325DateFormatTest::getFieldText(DateFormat* df, int32_t field, UDate date, UnicodeString& str)
326{
327 UnicodeString formatResult;
328 // {sfb} added to convert Calendar Fields to DateFormat fields
329 FieldPosition pos(fgCalendarToDateFormatField[field]);
330 df->format(date, formatResult, pos);
331 //formatResult.extract(pos.getBeginIndex(), pos.getEndIndex(), str);
332 formatResult.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), str);
333}
334
335// -------------------------------------
336
337/**
338 * Verify that strings which contain incomplete specifications are parsed
339 * correctly. In some instances, this means not being parsed at all, and
340 * returning an appropriate error.
341 */
342void
343DateFormatTest::TestPartialParse994()
344{
345 UErrorCode status = U_ZERO_ERROR;
346 SimpleDateFormat* f = new SimpleDateFormat(status);
347 UDate null = 0;
348 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", date(97, 1 - 1, 17, 10, 11, 42));
349 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null);
350 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", null);
351 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", null);
352 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", null);
353 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
354 delete f;
355}
356
357// -------------------------------------
358
359void
360DateFormatTest::tryPat994(SimpleDateFormat* format, const char* pat, const char* str, UDate expected)
361{
362 UErrorCode status = U_ZERO_ERROR;
363 UDate null = 0;
364 logln(UnicodeString("Pattern \"") + pat + "\" String \"" + str + "\"");
365 //try {
366 format->applyPattern(pat);
367 UDate date = format->parse(str, status);
368 if (U_FAILURE(status) || date == null)
369 {
370 logln((UnicodeString)"ParseException: " + (int32_t)status);
371 if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
372 }
373 else
374 {
375 UnicodeString f;
376 ((DateFormat*)format)->format(date, f);
377 logln(UnicodeString(" parse(") + str + ") -> " + dateToString(date));
378 logln((UnicodeString)" format -> " + f);
379 if (expected == null ||
380 !(date == expected)) errln((UnicodeString)"FAIL: Expected null");//" + expected);
381 if (!(f == str)) errln(UnicodeString("FAIL: Expected ") + str);
382 }
383 //}
384 //catch(ParseException e) {
385 // logln((UnicodeString)"ParseException: " + e.getMessage());
386 // if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
387 //}
388 //catch(Exception e) {
389 // errln((UnicodeString)"*** Exception:");
390 // e.printStackTrace();
391 //}
392}
393
394// -------------------------------------
395
396/**
397 * Verify the behavior of patterns in which digits for different fields run together
398 * without intervening separators.
399 */
400void
401DateFormatTest::TestRunTogetherPattern985()
402{
403 UErrorCode status = U_ZERO_ERROR;
404 UnicodeString format("yyyyMMddHHmmssSSS");
405 UnicodeString now, then;
406 //UBool flag;
407 SimpleDateFormat *formatter = new SimpleDateFormat(format, status);
408 UDate date1 = Calendar::getNow();
409 ((DateFormat*)formatter)->format(date1, now);
410 logln(now);
411 ParsePosition pos(0);
412 UDate date2 = formatter->parse(now, pos);
413 if (date2 == 0) then = "Parse stopped at " + pos.getIndex();
414 else ((DateFormat*)formatter)->format(date2, then);
415 logln(then);
416 if (!(date2 == date1)) errln((UnicodeString)"FAIL");
417 delete formatter;
418 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
419}
420
421// -------------------------------------
422
423/**
424 * Verify the behavior of patterns in which digits for different fields run together
425 * without intervening separators.
426 */
427void
428DateFormatTest::TestRunTogetherPattern917()
429{
430 UErrorCode status = U_ZERO_ERROR;
431 SimpleDateFormat* fmt;
432 UnicodeString myDate;
433 fmt = new SimpleDateFormat((UnicodeString)"yyyy/MM/dd", status);
434 myDate = "1997/02/03";
435 testIt917(fmt, myDate, date(97, 2 - 1, 3));
436 delete fmt;
437 fmt = new SimpleDateFormat((UnicodeString)"yyyyMMdd", status);
438 myDate = "19970304";
439 testIt917(fmt, myDate, date(97, 3 - 1, 4));
440 delete fmt;
441 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
442}
443
444// -------------------------------------
445
446void
447DateFormatTest::testIt917(SimpleDateFormat* fmt, UnicodeString& str, UDate expected)
448{
449 UErrorCode status = U_ZERO_ERROR;
450 UnicodeString pattern;
451 logln((UnicodeString)"pattern=" + fmt->toPattern(pattern) + " string=" + str);
452 Formattable o;
453 //try {
454 ((Format*)fmt)->parseObject(str, o, status);
455 //}
456 if (U_FAILURE(status)) return;
457 //catch(ParseException e) {
458 // e.printStackTrace();
459 // return;
460 //}
461 logln((UnicodeString)"Parsed object: " + dateToString(o.getDate()));
462 if (!(o.getDate() == expected)) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
463 UnicodeString formatted; ((Format*)fmt)->format(o, formatted, status);
464 logln((UnicodeString)"Formatted string: " + formatted);
465 if (!(formatted == str)) errln((UnicodeString)"FAIL: Expected " + str);
466 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
467}
468
469// -------------------------------------
470
471/**
472 * Verify the handling of Czech June and July, which have the unique attribute that
473 * one is a proper prefix substring of the other.
474 */
475void
476DateFormatTest::TestCzechMonths459()
477{
478 UErrorCode status = U_ZERO_ERROR;
479 DateFormat* fmt = DateFormat::createDateInstance(DateFormat::FULL, Locale("cs", "", ""));
480 UnicodeString pattern;
481 logln((UnicodeString)"Pattern " + ((SimpleDateFormat*) fmt)->toPattern(pattern));
482 UDate june = date(97, UCAL_JUNE, 15);
483 UDate july = date(97, UCAL_JULY, 15);
484 UnicodeString juneStr; fmt->format(june, juneStr);
485 UnicodeString julyStr; fmt->format(july, julyStr);
486 //try {
487 logln((UnicodeString)"format(June 15 1997) = " + juneStr);
488 UDate d = fmt->parse(juneStr, status);
489 UnicodeString s; fmt->format(d, s);
490 int32_t month,yr,day,hr,min,sec; dateToFields(d,yr,month,day,hr,min,sec);
491 logln((UnicodeString)" -> parse -> " + s + " (month = " + month + ")");
492 if (month != UCAL_JUNE) errln((UnicodeString)"FAIL: Month should be June");
493 logln((UnicodeString)"format(July 15 1997) = " + julyStr);
494 d = fmt->parse(julyStr, status);
495 fmt->format(d, s);
496 dateToFields(d,yr,month,day,hr,min,sec);
497 logln((UnicodeString)" -> parse -> " + s + " (month = " + month + ")");
498 if (month != UCAL_JULY) errln((UnicodeString)"FAIL: Month should be July");
499 //}
500 //catch(ParseException e) {
501 if (U_FAILURE(status))
502 errln((UnicodeString)"Exception: " + (int32_t)status);
503 //}
504 delete fmt;
505}
506
507// -------------------------------------
508
509/**
510 * Test the handling of 'D' in patterns.
511 */
512void
513DateFormatTest::TestLetterDPattern212()
514{
515 UErrorCode status = U_ZERO_ERROR;
516 UnicodeString dateString("1995-040.05:01:29");
517 UnicodeString bigD("yyyy-DDD.hh:mm:ss");
518 UnicodeString littleD("yyyy-ddd.hh:mm:ss");
519 UDate expLittleD = date(95, 0, 1, 5, 1, 29);
520 UDate expBigD = expLittleD + 39 * 24 * 3600000.0;
521 expLittleD = expBigD; // Expect the same, with default lenient parsing
522 logln((UnicodeString)"dateString= " + dateString);
523 SimpleDateFormat *formatter = new SimpleDateFormat(bigD, status);
524 ParsePosition pos(0);
525 UDate myDate = formatter->parse(dateString, pos);
526 logln((UnicodeString)"Using " + bigD + " -> " + myDate);
527 if (myDate != expBigD) errln((UnicodeString)"FAIL: Expected " + dateToString(expBigD));
528 delete formatter;
529 formatter = new SimpleDateFormat(littleD, status);
530 pos = ParsePosition(0);
531 myDate = formatter->parse(dateString, pos);
532 logln((UnicodeString)"Using " + littleD + " -> " + dateToString(myDate));
533 if (myDate != expLittleD) errln((UnicodeString)"FAIL: Expected " + dateToString(expLittleD));
534 delete formatter;
535 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
536}
537
538// -------------------------------------
539
540/**
541 * Test the day of year pattern.
542 */
543void
544DateFormatTest::TestDayOfYearPattern195()
545{
546 UErrorCode status = U_ZERO_ERROR;
547 UDate today = Calendar::getNow();
548 int32_t year,month,day,hour,min,sec; dateToFields(today,year,month,day,hour,min,sec);
549 UDate expected = date(year, month, day);
550 logln((UnicodeString)"Test Date: " + dateToString(today));
551 SimpleDateFormat* sdf = (SimpleDateFormat*)DateFormat::createDateInstance();
552 tryPattern(*sdf, today, 0, expected);
553 tryPattern(*sdf, today, "G yyyy DDD", expected);
554 delete sdf;
555 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
556}
557
558// -------------------------------------
559
560void
561DateFormatTest::tryPattern(SimpleDateFormat& sdf, UDate d, const char* pattern, UDate expected)
562{
563 UErrorCode status = U_ZERO_ERROR;
564 if (pattern != 0) sdf.applyPattern(pattern);
565 UnicodeString thePat;
566 logln((UnicodeString)"pattern: " + sdf.toPattern(thePat));
567 UnicodeString formatResult; (*(DateFormat*)&sdf).format(d, formatResult);
568 logln((UnicodeString)" format -> " + formatResult);
569 // try {
570 UDate d2 = sdf.parse(formatResult, status);
571 logln((UnicodeString)" parse(" + formatResult + ") -> " + dateToString(d2));
572 if (d2 != expected) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
573 UnicodeString format2; (*(DateFormat*)&sdf).format(d2, format2);
574 logln((UnicodeString)" format -> " + format2);
575 if (!(formatResult == format2)) errln((UnicodeString)"FAIL: Round trip drift");
576 //}
577 //catch(Exception e) {
578 if (U_FAILURE(status))
579 errln((UnicodeString)"Error: " + (int32_t)status);
580 //}
581}
582
583// -------------------------------------
584
585/**
586 * Test the handling of single quotes in patterns.
587 */
588void
589DateFormatTest::TestQuotePattern161()
590{
591 UErrorCode status = U_ZERO_ERROR;
592 SimpleDateFormat* formatter = new SimpleDateFormat((UnicodeString)"MM/dd/yyyy 'at' hh:mm:ss a zzz", status);
593 UDate currentTime_1 = date(97, UCAL_AUGUST, 13, 10, 42, 28);
594 UnicodeString dateString; ((DateFormat*)formatter)->format(currentTime_1, dateString);
595 UnicodeString exp("08/13/1997 at 10:42:28 AM ");
596 logln((UnicodeString)"format(" + dateToString(currentTime_1) + ") = " + dateString);
597 if (0 != dateString.compareBetween(0, exp.length(), exp, 0, exp.length())) errln((UnicodeString)"FAIL: Expected " + exp);
598 delete formatter;
599 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
600}
601
602// -------------------------------------
603
604/**
605 * Verify the correct behavior when handling invalid input strings.
606 */
607void
608DateFormatTest::TestBadInput135()
609{
610 UErrorCode status = U_ZERO_ERROR;
611 DateFormat::EStyle looks[] = {
612 DateFormat::SHORT, DateFormat::MEDIUM, DateFormat::LONG, DateFormat::FULL
613 };
614 int32_t looks_length = (int32_t)(sizeof(looks) / sizeof(looks[0]));
615 const char* strings[] = {
616 "Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
617 };
618 int32_t strings_length = (int32_t)(sizeof(strings) / sizeof(strings[0]));
619 DateFormat *full = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
620 UnicodeString expected("March 1, 2000 1:23:45 AM ");
621 for (int32_t i = 0; i < strings_length;++i) {
622 const char* text = strings[i];
623 for (int32_t j = 0; j < looks_length;++j) {
624 DateFormat::EStyle dateLook = looks[j];
625 for (int32_t k = 0; k < looks_length;++k) {
626 DateFormat::EStyle timeLook = looks[k];
627 DateFormat *df = DateFormat::createDateTimeInstance(dateLook, timeLook);
628 UnicodeString prefix = UnicodeString(text) + ", " + dateLook + "/" + timeLook + ": ";
629 //try {
630 UDate when = df->parse(text, status);
631 if (when == 0 && U_SUCCESS(status)) {
632 errln(prefix + "SHOULD NOT HAPPEN: parse returned 0.");
633 continue;
634 }
635 if (U_SUCCESS(status))
636 {
637 UnicodeString format;
638 full->format(when, format);
639 logln(prefix + "OK: " + format);
640 if (0!=format.compareBetween(0, expected.length(), expected, 0, expected.length()))
641 errln((UnicodeString)"FAIL: Expected " + expected + " got " + format);
642 }
643 //}
644 //catch(ParseException e) {
645 else
646 status = U_ZERO_ERROR;
647 //}
648 //catch(StringIndexOutOfBoundsException e) {
649 // errln(prefix + "SHOULD NOT HAPPEN: " + (int)status);
650 //}
651 delete df;
652 }
653 }
654 }
655 delete full;
656 if (U_FAILURE(status))
657 errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
658}
659
660const char* DateFormatTest::parseFormats[] = {
661 "MMMM d, yyyy",
662 "MMMM d yyyy",
663 "M/d/yy",
664 "d MMMM, yyyy",
665 "d MMMM yyyy",
666 "d MMMM",
667 "MMMM d",
668 "yyyy",
669 "h:mm a MMMM d, yyyy"
670};
671
672const char* DateFormatTest::inputStrings[] = {
673 "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
674 "April 1, 1997", "April 1, 1997", 0, 0, 0, 0, 0, "April 1", 0, 0,
675 "Jan 1, 1970", "January 1, 1970", 0, 0, 0, 0, 0, "January 1", 0, 0,
676 "Jan 1 2037", 0, "January 1 2037", 0, 0, 0, 0, "January 1", 0, 0,
677 "1/1/70", 0, 0, "1/1/70", 0, 0, 0, 0, "0001", 0,
678 "5 May 1997", 0, 0, 0, 0, "5 May 1997", "5 May", 0, "0005", 0,
679 "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
680 "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
681 "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
682 "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
683 "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
684};
685
686// -------------------------------------
687
688/**
689 * Verify the correct behavior when parsing an array of inputs against an
690 * array of patterns, with known results. The results are encoded after
691 * the input strings in each row.
692 */
693void
694DateFormatTest::TestBadInput135a()
695{
696 UErrorCode status = U_ZERO_ERROR;
697 SimpleDateFormat* dateParse = new SimpleDateFormat(status);
698 if(U_FAILURE(status)) {
699 errln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
700 delete dateParse;
701 return;
702 }
703 const char* s;
704 UDate date;
705 const uint32_t PF_LENGTH = (int32_t)(sizeof(parseFormats)/sizeof(parseFormats[0]));
706 const uint32_t INPUT_LENGTH = (int32_t)(sizeof(inputStrings)/sizeof(inputStrings[0]));
707
708 dateParse->applyPattern("d MMMM, yyyy");
709 dateParse->adoptTimeZone(TimeZone::createDefault());
710 s = "not parseable";
711 UnicodeString thePat;
712 logln(UnicodeString("Trying to parse \"") + s + "\" with " + dateParse->toPattern(thePat));
713 //try {
714 date = dateParse->parse(s, status);
715 if (U_SUCCESS(status))
716 errln((UnicodeString)"FAIL: Expected exception during parse");
717 //}
718 //catch(Exception ex) {
719 else
720 logln((UnicodeString)"Exception during parse: " + (int32_t)status);
721 status = U_ZERO_ERROR;
722 //}
723 for (uint32_t i = 0; i < INPUT_LENGTH; i += (PF_LENGTH + 1)) {
724 ParsePosition parsePosition(0);
725 UnicodeString s( inputStrings[i]);
726 for (uint32_t index = 0; index < PF_LENGTH;++index) {
727 const char* expected = inputStrings[i + 1 + index];
728 dateParse->applyPattern(parseFormats[index]);
729 dateParse->adoptTimeZone(TimeZone::createDefault());
730 //try {
731 parsePosition.setIndex(0);
732 date = dateParse->parse(s, parsePosition);
733 if (parsePosition.getIndex() != 0) {
734 UnicodeString s1, s2;
735 s.extract(0, parsePosition.getIndex(), s1);
736 s.extract(parsePosition.getIndex(), s.length(), s2);
737 if (date == 0) {
738 errln((UnicodeString)"ERROR: null result fmt=\"" +
739 parseFormats[index] +
740 "\" pos=" + parsePosition.getIndex() + " " +
741 s1 + "|" + s2);
742 }
743 else {
744 UnicodeString result;
745 ((DateFormat*)dateParse)->format(date, result);
746 logln((UnicodeString)"Parsed \"" + s + "\" using \"" + dateParse->toPattern(thePat) + "\" to: " + result);
747 if (expected == 0)
748 errln((UnicodeString)"FAIL: Expected parse failure");
749 else if (!(result == expected))
750 errln(UnicodeString("FAIL: Expected ") + expected);
751 }
752 }
753 else if (expected != 0) {
754 errln(UnicodeString("FAIL: Expected ") + expected + " from \"" +
755 s + "\" with \"" + dateParse->toPattern(thePat) + "\"");
756 }
757 //}
758 //catch(Exception ex) {
759 if (U_FAILURE(status))
760 errln((UnicodeString)"An exception was thrown during parse: " + (int32_t)status);
761 //}
762 }
763 }
764 delete dateParse;
765 if (U_FAILURE(status))
766 errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
767}
768
769// -------------------------------------
770
771/**
772 * Test the parsing of two-digit years.
773 */
774void
775DateFormatTest::TestTwoDigitYear()
776{
777 UErrorCode ec = U_ZERO_ERROR;
778 SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);
779 if (U_FAILURE(ec)) {
780 errln("FAIL: SimpleDateFormat constructor");
781 return;
782 }
783 parse2DigitYear(fmt, "5/6/17", date(117, UCAL_JUNE, 5));
784 parse2DigitYear(fmt, "4/6/34", date(34, UCAL_JUNE, 4));
785}
786
787// -------------------------------------
788
789void
790DateFormatTest::parse2DigitYear(DateFormat& fmt, const char* str, UDate expected)
791{
792 UErrorCode status = U_ZERO_ERROR;
793 //try {
794 UDate d = fmt.parse(str, status);
795 UnicodeString thePat;
796 logln(UnicodeString("Parsing \"") + str + "\" with " + ((SimpleDateFormat*)&fmt)->toPattern(thePat) +
797 " => " + dateToString(d));
798 if (d != expected) errln((UnicodeString)"FAIL: Expected " + expected);
799 //}
800 //catch(ParseException e) {
801 if (U_FAILURE(status))
802 errln((UnicodeString)"FAIL: Got exception");
803 //}
804}
805
806// -------------------------------------
807
808/**
809 * Test the formatting of time zones.
810 */
811void
812DateFormatTest::TestDateFormatZone061()
813{
814 UErrorCode status = U_ZERO_ERROR;
815 UDate date;
816 DateFormat *formatter;
817 date= 859248000000.0;
818 logln((UnicodeString)"Date 1997/3/25 00:00 GMT: " + date);
819 formatter = new SimpleDateFormat((UnicodeString)"dd-MMM-yyyyy HH:mm", Locale::getUK(), status);
820 if(U_FAILURE(status)) {
821 errln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
822 delete formatter;
823 return;
824 }
825 formatter->adoptTimeZone(TimeZone::createTimeZone("GMT"));
826 UnicodeString temp; formatter->format(date, temp);
827 logln((UnicodeString)"Formatted in GMT to: " + temp);
828 //try {
829 UDate tempDate = formatter->parse(temp, status);
830 logln((UnicodeString)"Parsed to: " + dateToString(tempDate));
831 if (tempDate != date) errln((UnicodeString)"FAIL: Expected " + dateToString(date));
832 //}
833 //catch(Throwable t) {
834 if (U_FAILURE(status))
835 errln((UnicodeString)"Date Formatter throws: " + (int32_t)status);
836 //}
837 delete formatter;
838}
839
840// -------------------------------------
841
842/**
843 * Test the formatting of time zones.
844 */
845void
846DateFormatTest::TestDateFormatZone146()
847{
848 TimeZone *saveDefault = TimeZone::createDefault();
849
850 //try {
851 TimeZone *thedefault = TimeZone::createTimeZone("GMT");
852 TimeZone::setDefault(*thedefault);
853 // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
854
855 // check to be sure... its GMT all right
856 TimeZone *testdefault = TimeZone::createDefault();
857 UnicodeString testtimezone;
858 testdefault->getID(testtimezone);
859 if (testtimezone == "GMT")
860 logln("Test timezone = " + testtimezone);
861 else
862 errln("Test timezone should be GMT, not " + testtimezone);
863
864 UErrorCode status = U_ZERO_ERROR;
865 // now try to use the default GMT time zone
866 GregorianCalendar *greenwichcalendar =
867 new GregorianCalendar(1997, 3, 4, 23, 0, status);
868 failure(status, "new GregorianCalendar");
869 //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
870 //greenwichcalendar.set(1997, 3, 4, 23, 0);
871 // try anything to set hour to 23:00 !!!
872 greenwichcalendar->set(UCAL_HOUR_OF_DAY, 23);
873 // get time
874 UDate greenwichdate = greenwichcalendar->getTime(status);
875 // format every way
876 UnicodeString DATA [] = {
877 UnicodeString("simple format: "), UnicodeString("04/04/97 23:00 GMT"),
878 UnicodeString("MM/dd/yy HH:mm z"),
879 UnicodeString("full format: "), UnicodeString("Friday, April 4, 1997 11:00:00 o'clock PM GMT"),
880 UnicodeString("EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z"),
881 UnicodeString("long format: "), UnicodeString("April 4, 1997 11:00:00 PM GMT"),
882 UnicodeString("MMMM d, yyyy h:mm:ss a z"),
883 UnicodeString("default format: "), UnicodeString("04-Apr-97 11:00:00 PM"),
884 UnicodeString("dd-MMM-yy h:mm:ss a"),
885 UnicodeString("short format: "), UnicodeString("4/4/97 11:00 PM"),
886 UnicodeString("M/d/yy h:mm a")
887 };
888 int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
889
890 for (int32_t i=0; i<DATA_length; i+=3) {
891 DateFormat *fmt = new SimpleDateFormat(DATA[i+2], Locale::getEnglish(), status);
892 if(failure(status, "new SimpleDateFormat")) break;
893 fmt->setCalendar(*greenwichcalendar);
894 UnicodeString result;
895 result = fmt->format(greenwichdate, result);
896 logln(DATA[i] + result);
897 if (result != DATA[i+1])
898 errln("FAIL: Expected " + DATA[i+1] + ", got " + result);
899 delete fmt;
900 }
901 //}
902 //finally {
903 TimeZone::adoptDefault(saveDefault);
904 //}
905 delete testdefault;
906 delete greenwichcalendar;
907 delete thedefault;
908
909
910}
911
912// -------------------------------------
913
914/**
915 * Test the formatting of dates in different locales.
916 */
917void
918DateFormatTest::TestLocaleDateFormat() // Bug 495
919{
920 UDate testDate = date(97, UCAL_SEPTEMBER, 15);
921 DateFormat *dfFrench = DateFormat::createDateTimeInstance(DateFormat::FULL,
922 DateFormat::FULL, Locale::getFrench());
923 DateFormat *dfUS = DateFormat::createDateTimeInstance(DateFormat::FULL,
924 DateFormat::FULL, Locale::getUS());
925 UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 00 h 00 GMT-07:00" );
926 //UnicodeString expectedUS ( "Monday, September 15, 1997 12:00:00 o'clock AM PDT" );
927 UnicodeString expectedUS ( "Monday, September 15, 1997 12:00:00 AM PDT" );
928 logln((UnicodeString)"Date set to : " + dateToString(testDate));
929 UnicodeString out;
930 dfFrench->format(testDate, out);
931 logln((UnicodeString)"Date Formated with French Locale " + out);
932 if (!(out == expectedFRENCH))
933 errln((UnicodeString)"FAIL: Expected " + expectedFRENCH);
934 out.truncate(0);
935 dfUS->format(testDate, out);
936 logln((UnicodeString)"Date Formated with US Locale " + out);
937 if (!(out == expectedUS))
938 errln((UnicodeString)"FAIL: Expected " + expectedUS);
939 delete dfUS;
940 delete dfFrench;
941}
942
943/**
944 * Test DateFormat(Calendar) API
945 */
946void DateFormatTest::TestDateFormatCalendar() {
947 DateFormat *date=0, *time=0, *full=0;
948 Calendar *cal=0;
949 UnicodeString str;
950 ParsePosition pos;
951 UDate when;
952 UErrorCode ec = U_ZERO_ERROR;
953
954 /* Create a formatter for date fields. */
955 date = DateFormat::createDateInstance(DateFormat::kShort, Locale::getUS());
956 if (date == NULL) {
957 errln("FAIL: createDateInstance failed");
958 goto FAIL;
959 }
960
961 /* Create a formatter for time fields. */
962 time = DateFormat::createTimeInstance(DateFormat::kShort, Locale::getUS());
963 if (time == NULL) {
964 errln("FAIL: createTimeInstance failed");
965 goto FAIL;
966 }
967
968 /* Create a full format for output */
969 full = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
970 Locale::getUS());
971 if (full == NULL) {
972 errln("FAIL: createInstance failed");
973 goto FAIL;
974 }
975
976 /* Create a calendar */
977 cal = Calendar::createInstance(Locale::getUS(), ec);
978 if (cal == NULL || U_FAILURE(ec)) {
979 errln((UnicodeString)"FAIL: Calendar::createInstance failed with " +
980 u_errorName(ec));
981 goto FAIL;
982 }
983
984 /* Parse the date */
985 cal->clear();
986 str = UnicodeString("4/5/2001", "");
987 pos.setIndex(0);
988 date->parse(str, *cal, pos);
989 if (pos.getIndex() != str.length()) {
990 errln((UnicodeString)"FAIL: DateFormat::parse(4/5/2001) failed at " +
991 pos.getIndex());
992 goto FAIL;
993 }
994
995 /* Parse the time */
996 str = UnicodeString("5:45 PM", "");
997 pos.setIndex(0);
998 time->parse(str, *cal, pos);
999 if (pos.getIndex() != str.length()) {
1000 errln((UnicodeString)"FAIL: DateFormat::parse(17:45) failed at " +
1001 pos.getIndex());
1002 goto FAIL;
1003 }
1004
1005 /* Check result */
1006 when = cal->getTime(ec);
1007 if (U_FAILURE(ec)) {
1008 errln((UnicodeString)"FAIL: cal->getTime() failed with " + u_errorName(ec));
1009 goto FAIL;
1010 }
1011 str.truncate(0);
1012 full->format(when, str);
1013 // Thursday, April 5, 2001 5:45:00 PM PDT 986517900000
1014 if (when == 986517900000.0) {
1015 logln("Ok: Parsed result: " + str);
1016 } else {
1017 errln("FAIL: Parsed result: " + str + ", exp 4/5/2001 5:45 PM");
1018 }
1019
1020 FAIL:
1021 delete date;
1022 delete time;
1023 delete full;
1024 delete cal;
1025}
1026
1027/**
1028 * Test DateFormat's parsing of space characters. See jitterbug 1916.
1029 */
1030void DateFormatTest::TestSpaceParsing() {
1031 const char* DATA[] = {
1032 "yyyy MM dd HH:mm:ss",
1033
1034 // pattern, input, expected parse or NULL if expect parse failure
1035 "MMMM d yy", " 04 05 06", NULL, // MMMM wants Apr/April
1036 NULL, "04 05 06", NULL,
1037 "MM d yy", " 04 05 06", "2006 04 05 00:00:00",
1038 NULL, "04 05 06", "2006 04 05 00:00:00",
1039 "MMMM d yy", " Apr 05 06", "2006 04 05 00:00:00",
1040 NULL, "Apr 05 06", "2006 04 05 00:00:00",
1041 };
1042 const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1043
1044 expectParse(DATA, DATA_len, Locale("en"));
1045}
1046
1047/**
1048 * Test handling of "HHmmss" pattern.
1049 */
1050void DateFormatTest::TestExactCountFormat() {
1051 const char* DATA[] = {
1052 "yyyy MM dd HH:mm:ss",
1053
1054 // pattern, input, expected parse or NULL if expect parse failure
1055 "HHmmss", "123456", "1970 01 01 12:34:56",
1056 NULL, "12345", "1970 01 01 01:23:45",
1057 NULL, "1234", NULL,
1058 NULL, "00-05", NULL,
1059 NULL, "12-34", NULL,
1060 NULL, "00+05", NULL,
1061 "ahhmm", "PM730", "1970 01 01 19:30:00",
1062 };
1063 const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1064
1065 expectParse(DATA, DATA_len, Locale("en"));
1066}
1067
1068/**
1069 * Test handling of white space.
1070 */
1071void DateFormatTest::TestWhiteSpaceParsing() {
1072 const char* DATA[] = {
1073 "yyyy MM dd",
1074
1075 // pattern, input, expected parse or null if expect parse failure
1076
1077 // Pattern space run should parse input text space run
1078 "MM d yy", " 04 01 03", "2003 04 01",
1079 NULL, " 04 01 03 ", "2003 04 01",
1080 };
1081 const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1082
1083 expectParse(DATA, DATA_len, Locale("en"));
1084}
1085
1086/**
1087 * Test parsing. Input is an array that starts with the following
1088 * header:
1089 *
1090 * [0] = pattern string to parse [i+2] with
1091 *
1092 * followed by test cases, each of which is 3 array elements:
1093 *
1094 * [i] = pattern, or NULL to reuse prior pattern
1095 * [i+1] = input string
1096 * [i+2] = expected parse result (parsed with pattern [0])
1097 *
1098 * If expect parse failure, then [i+2] should be NULL.
1099 */
1100void DateFormatTest::expectParse(const char** data, int32_t data_length,
1101 const Locale& loc) {
1102 const UDate FAIL = (UDate) -1;
1103 const UnicodeString FAIL_STR("parse failure");
1104 int32_t i = 0;
1105
1106 UErrorCode ec = U_ZERO_ERROR;
1107 SimpleDateFormat fmt("", loc, ec);
1108 SimpleDateFormat ref(data[i++], loc, ec);
1109 SimpleDateFormat gotfmt("G yyyy MM dd HH:mm:ss z", loc, ec);
1110 if (U_FAILURE(ec)) {
1111 errln("FAIL: SimpleDateFormat constructor");
1112 return;
1113 }
1114
1115 const char* currentPat = NULL;
1116 while (i<data_length) {
1117 const char* pattern = data[i++];
1118 const char* input = data[i++];
1119 const char* expected = data[i++];
1120
1121 ec = U_ZERO_ERROR;
1122 if (pattern != NULL) {
1123 fmt.applyPattern(pattern);
1124 currentPat = pattern;
1125 }
1126 UDate got = fmt.parse(input, ec);
1127 UnicodeString gotstr(FAIL_STR);
1128 if (U_FAILURE(ec)) {
1129 got = FAIL;
1130 } else {
1131 gotstr.remove();
1132 gotfmt.format(got, gotstr);
1133 }
1134
1135 UErrorCode ec2 = U_ZERO_ERROR;
1136 UDate exp = FAIL;
1137 UnicodeString expstr(FAIL_STR);
1138 if (expected != NULL) {
1139 expstr = expected;
1140 exp = ref.parse(expstr, ec2);
1141 if (U_FAILURE(ec2)) {
1142 // This only happens if expected is in wrong format --
1143 // should never happen once test is debugged.
1144 errln("FAIL: Internal test error");
1145 return;
1146 }
1147 }
1148
1149 if (got == exp) {
1150 logln((UnicodeString)"Ok: " + input + " x " +
1151 currentPat + " => " + gotstr);
1152 } else {
1153 errln((UnicodeString)"FAIL: " + input + " x " +
1154 currentPat + " => " + gotstr + ", expected " +
1155 expstr);
1156 }
1157 }
1158}
1159
1160#endif /* #if !UCONFIG_NO_FORMATTING */
1161
1162//eof