]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/dtfmttst.cpp
ICU-8.11.4.tar.gz
[apple/icu.git] / icuSources / test / intltest / dtfmttst.cpp
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
73c04bcf 3 * Copyright (c) 1997-2006, International Business Machines Corporation and
b75a7d8f
A
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"
374ca955 18#include "unicode/dtfmtsym.h"
b75a7d8f 19#include "cmemory.h"
374ca955
A
20#include "cstring.h"
21#include "caltest.h" // for fieldName
73c04bcf
A
22
23#ifdef U_WINDOWS
24#include "windttst.h"
25#endif
26
27#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
28
29#define ASSERT_OK(status) if(U_FAILURE(status)) {errln(#status " = %s", u_errorName(status)); return; }
30
31//--------------------------------------------------------------------
32// Time bomb - allows temporary behavior that expires at a given
33// release
34//--------------------------------------------------------------------
35static const UVersionInfo ICU_37 = {3,7,0,0};
36
b75a7d8f
A
37// *****************************************************************************
38// class DateFormatTest
39// *****************************************************************************
40
41void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
42{
43 // if (exec) logln((UnicodeString)"TestSuite DateFormatTest");
44 switch (index) {
45 TESTCASE(0,TestEquals);
46 TESTCASE(1,TestTwoDigitYearDSTParse);
47 TESTCASE(2,TestFieldPosition);
48 TESTCASE(3,TestPartialParse994);
49 TESTCASE(4,TestRunTogetherPattern985);
50 TESTCASE(5,TestRunTogetherPattern917);
51 TESTCASE(6,TestCzechMonths459);
52 TESTCASE(7,TestLetterDPattern212);
53 TESTCASE(8,TestDayOfYearPattern195);
54 TESTCASE(9,TestQuotePattern161);
55 TESTCASE(10,TestBadInput135);
56 TESTCASE(11,TestBadInput135a);
57 TESTCASE(12,TestTwoDigitYear);
58 TESTCASE(13,TestDateFormatZone061);
59 TESTCASE(14,TestDateFormatZone146);
60 TESTCASE(15,TestLocaleDateFormat);
61 TESTCASE(16,TestWallyWedel);
62 TESTCASE(17,TestDateFormatCalendar);
63 TESTCASE(18,TestSpaceParsing);
64 TESTCASE(19,TestExactCountFormat);
65 TESTCASE(20,TestWhiteSpaceParsing);
374ca955
A
66 TESTCASE(21,TestInvalidPattern);
67 TESTCASE(22,TestGeneral);
68 TESTCASE(23,TestGreekMay);
73c04bcf
A
69 TESTCASE(24,TestGenericTime);
70 TESTCASE(25,TestGenericTimeZoneOrder);
71 TESTCASE(26,TestTimeZoneStringsAPI);
72 TESTCASE(27,TestHost);
73 TESTCASE(28,TestEras);
74 TESTCASE(29,TestNarrowNames);
75 TESTCASE(30,TestStandAloneDays);
76 TESTCASE(31,TestStandAloneMonths);
77 TESTCASE(32,TestQuarters);
b75a7d8f
A
78 default: name = ""; break;
79 }
80}
81
82// Test written by Wally Wedel and emailed to me.
83void DateFormatTest::TestWallyWedel()
84{
85 UErrorCode status = U_ZERO_ERROR;
86 /*
87 * Instantiate a TimeZone so we can get the ids.
88 */
89 TimeZone *tz = new SimpleTimeZone(7,"");
90 /*
91 * Computational variables.
92 */
93 int32_t offset, hours, minutes;
94 /*
95 * Instantiate a SimpleDateFormat set up to produce a full time
96 zone name.
97 */
98 SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)"zzzz", status);
99 /*
100 * A String array for the time zone ids.
101 */
102 int32_t ids_length;
103 StringEnumeration* ids = TimeZone::createEnumeration();
104 ids_length = ids->count(status);
105 /*
106 * How many ids do we have?
107 */
108 logln("Time Zone IDs size: %d", ids_length);
109 /*
110 * Column headings (sort of)
111 */
112 logln("Ordinal ID offset(h:m) name");
113 /*
114 * Loop through the tzs.
115 */
116 UDate today = Calendar::getNow();
117 Calendar *cal = Calendar::createInstance(status);
118 for (int32_t i = 0; i < ids_length; i++) {
119 // logln(i + " " + ids[i]);
120 const UnicodeString* id = ids->snext(status);
121 TimeZone *ttz = TimeZone::createTimeZone(*id);
122 // offset = ttz.getRawOffset();
123 cal->setTimeZone(*ttz);
124 cal->setTime(today, status);
125 offset = cal->get(UCAL_ZONE_OFFSET, status) + cal->get(UCAL_DST_OFFSET, status);
126 // logln(i + " " + ids[i] + " offset " + offset);
127 const char* sign = "+";
128 if (offset < 0) {
129 sign = "-";
130 offset = -offset;
131 }
132 hours = offset/3600000;
133 minutes = (offset%3600000)/60000;
134 UnicodeString dstOffset = (UnicodeString)"" + sign + (hours < 10 ? "0" : "") +
135 (int32_t)hours + ":" + (minutes < 10 ? "0" : "") + (int32_t)minutes;
136 /*
137 * Instantiate a date so we can display the time zone name.
138 */
139 sdf->setTimeZone(*ttz);
140 /*
141 * Format the output.
142 */
143 UnicodeString fmtOffset;
144 FieldPosition pos(0);
145 sdf->format(today,fmtOffset, pos);
146 // UnicodeString fmtOffset = tzS.toString();
147 UnicodeString *fmtDstOffset = 0;
148 if (fmtOffset.startsWith("GMT"))
149 {
150 //fmtDstOffset = fmtOffset->substring(3);
151 fmtDstOffset = new UnicodeString();
152 fmtOffset.extract(3, fmtOffset.length(), *fmtDstOffset);
153 }
154 /*
155 * Show our result.
156 */
157 UBool ok = fmtDstOffset == 0 || *fmtDstOffset == dstOffset;
158 if (ok)
159 {
160 logln(UnicodeString() + i + " " + *id + " " + dstOffset +
161 " " + fmtOffset +
162 (fmtDstOffset != 0 ? " ok" : " ?"));
163 }
164 else
165 {
166 errln(UnicodeString() + i + " " + *id + " " + dstOffset +
167 " " + fmtOffset + " *** FAIL ***");
168 }
169 delete ttz;
170 delete fmtDstOffset;
171 }
172 delete cal;
173 // delete ids; // TODO: BAD API
174 delete ids;
175 delete sdf;
176 delete tz;
177}
178
179// -------------------------------------
180
181/**
182 * Test operator==
183 */
184void
185DateFormatTest::TestEquals()
186{
187 DateFormat* fmtA = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
188 DateFormat* fmtB = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
73c04bcf
A
189 if ( fmtA == NULL || fmtB == NULL){
190 dataerrln("Error calling DateFormat::createDateTimeInstance");
191 delete fmtA;
192 delete fmtB;
193 return;
194 }
195
b75a7d8f
A
196 if (!(*fmtA == *fmtB)) errln((UnicodeString)"FAIL");
197 delete fmtA;
198 delete fmtB;
73c04bcf
A
199
200 TimeZone* test = TimeZone::createTimeZone("PDT");
201 delete test;
b75a7d8f
A
202}
203
204// -------------------------------------
205
206/**
207 * Test the parsing of 2-digit years.
208 */
209void
210DateFormatTest::TestTwoDigitYearDSTParse(void)
211{
212 UErrorCode status = U_ZERO_ERROR;
213 SimpleDateFormat* fullFmt = new SimpleDateFormat((UnicodeString)"EEE MMM dd HH:mm:ss.SSS zzz yyyy G", status);
214 SimpleDateFormat *fmt = new SimpleDateFormat((UnicodeString)"dd-MMM-yy h:mm:ss 'o''clock' a z", Locale::getEnglish(), status);
215 //DateFormat* fmt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, Locale::ENGLISH);
216 UnicodeString* s = new UnicodeString("03-Apr-04 2:20:47 o'clock AM PST", "");
73c04bcf
A
217 TimeZone* defaultTZ = TimeZone::createDefault();
218 TimeZone* PST = TimeZone::createTimeZone("PST");
219 int32_t defaultOffset = defaultTZ->getRawOffset();
220 int32_t PSTOffset = PST->getRawOffset();
221 int32_t hour = 2 + (defaultOffset - PSTOffset) / (60*60*1000);
222 // hour is the expected hour of day, in units of seconds
223 hour = ((hour < 0) ? hour + 24 : hour) * 60*60;
224
b75a7d8f 225 UnicodeString str;
73c04bcf
A
226
227 if(U_FAILURE(status)) {
228 errln("Could not set up test. exitting");
229 return;
230 }
231
b75a7d8f
A
232 UDate d = fmt->parse(*s, status);
233 logln(*s + " P> " + ((DateFormat*)fullFmt)->format(d, str));
234 int32_t y, m, day, hr, min, sec;
235 dateToFields(d, y, m, day, hr, min, sec);
73c04bcf
A
236 hour += defaultTZ->inDaylightTime(d, status) ? 1 : 0;
237 hr = hr*60*60;
b75a7d8f 238 if (hr != hour)
73c04bcf 239 errln((UnicodeString)"FAIL: Should parse to hour " + hour + " but got " + hr);
b75a7d8f
A
240
241 if (U_FAILURE(status))
242 errln((UnicodeString)"FAIL: " + (int32_t)status);
243
244 delete s;
245 delete fmt;
246 delete fullFmt;
73c04bcf
A
247 delete PST;
248 delete defaultTZ;
b75a7d8f
A
249}
250
251// -------------------------------------
252
253UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
254
255UnicodeString&
256DateFormatTest::escape(UnicodeString& s)
257{
258 UnicodeString buf;
259 for (int32_t i=0; i<s.length(); ++i)
260 {
261 UChar c = s[(int32_t)i];
262 if (c <= (UChar)0x7F) buf += c;
263 else {
264 buf += (UChar)0x5c; buf += (UChar)0x55;
265 buf += toHexString((c & 0xF000) >> 12);
266 buf += toHexString((c & 0x0F00) >> 8);
267 buf += toHexString((c & 0x00F0) >> 4);
268 buf += toHexString(c & 0x000F);
269 }
270 }
271 return (s = buf);
272}
273
b75a7d8f
A
274// -------------------------------------
275
374ca955
A
276/**
277 * This MUST be kept in sync with DateFormatSymbols.gPatternChars.
278 */
73c04bcf 279static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQq";
374ca955
A
280
281/**
282 * A list of the names of all the fields in DateFormat.
283 * This MUST be kept in sync with DateFormat.
284 */
285static const char* DATEFORMAT_FIELD_NAMES[] = {
286 "ERA_FIELD",
287 "YEAR_FIELD",
288 "MONTH_FIELD",
289 "DATE_FIELD",
290 "HOUR_OF_DAY1_FIELD",
291 "HOUR_OF_DAY0_FIELD",
292 "MINUTE_FIELD",
293 "SECOND_FIELD",
294 "MILLISECOND_FIELD",
295 "DAY_OF_WEEK_FIELD",
296 "DAY_OF_YEAR_FIELD",
297 "DAY_OF_WEEK_IN_MONTH_FIELD",
298 "WEEK_OF_YEAR_FIELD",
299 "WEEK_OF_MONTH_FIELD",
300 "AM_PM_FIELD",
301 "HOUR1_FIELD",
302 "HOUR0_FIELD",
303 "TIMEZONE_FIELD",
304 "YEAR_WOY_FIELD",
305 "DOW_LOCAL_FIELD",
306 "EXTENDED_YEAR_FIELD",
307 "JULIAN_DAY_FIELD",
308 "MILLISECONDS_IN_DAY_FIELD",
73c04bcf
A
309 "TIMEZONE_RFC_FIELD",
310 "GENERIC_TIMEZONE_FIELD",
311 "STAND_ALONE_DAY_FIELD",
312 "STAND_ALONE_MONTH_FIELD",
313 "QUARTER_FIELD",
314 "STAND_ALONE_QUARTER_FIELD"
b75a7d8f
A
315};
316
374ca955
A
317static const int32_t DATEFORMAT_FIELD_NAMES_LENGTH =
318 sizeof(DATEFORMAT_FIELD_NAMES) / sizeof(DATEFORMAT_FIELD_NAMES[0]);
319
b75a7d8f
A
320/**
321 * Verify that returned field position indices are correct.
322 */
374ca955
A
323void DateFormatTest::TestFieldPosition() {
324 UErrorCode ec = U_ZERO_ERROR;
325 int32_t i, j, exp;
326 UnicodeString buf;
327
328 // Verify data
329 DateFormatSymbols rootSyms(Locale(""), ec);
330 assertSuccess("DateFormatSymbols", ec);
73c04bcf
A
331
332 // local pattern chars not accurate when CLDR 1.4 data
333 // first introduced...
334 if(isICUVersionAtLeast(ICU_37)) {
335 assertEquals("patternChars", PATTERN_CHARS, rootSyms.getLocalPatternChars(buf));
336 }
337
374ca955
A
338 assertEquals("patternChars", PATTERN_CHARS, DateFormatSymbols::getPatternUChars());
339 assertTrue("DATEFORMAT_FIELD_NAMES", DATEFORMAT_FIELD_NAMES_LENGTH == UDAT_FIELD_COUNT);
340 assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS));
341
342 // Create test formatters
343 const int32_t COUNT = 4;
344 DateFormat* dateFormats[COUNT];
345 dateFormats[0] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getUS());
346 dateFormats[1] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getFrance());
347 // Make the pattern "G y M d..."
348 buf.remove().append(PATTERN_CHARS);
349 for (j=buf.length()-1; j>=0; --j) buf.insert(j, (UChar)32/*' '*/);
350 dateFormats[2] = new SimpleDateFormat(buf, Locale::getUS(), ec);
351 // Make the pattern "GGGG yyyy MMMM dddd..."
352 for (j=buf.length()-1; j>=0; j-=2) {
353 for (i=0; i<3; ++i) {
354 buf.insert(j, buf.charAt(j));
355 }
356 }
357 dateFormats[3] = new SimpleDateFormat(buf, Locale::getUS(), ec);
73c04bcf
A
358 if(U_FAILURE(ec)){
359 errln(UnicodeString("Could not create SimpleDateFormat object for locale en_US. Error: " )+ UnicodeString(u_errorName(ec)));
360 return;
361 }
374ca955
A
362 UDate aug13 = 871508052513.0;
363
364 // Expected output field values for above DateFormats on aug13
365 // Fields are given in order of DateFormat field number
366 const char* EXPECTED[] = {
367 "", "1997", "August", "13", "", "", "34", "12", "",
73c04bcf 368 "Wednesday", "", "", "", "", "PM", "2", "", "", "", "", "", "", "", "", "PT", "", "", "", "",
374ca955
A
369
370 "", "1997", "ao\\u00FBt", "13", "", "14", "34", "", "",
73c04bcf 371 "mercredi", "", "", "", "", "", "", "", "HAP (\\u00C9UA)", "", "", "", "", "", "", "", "", "", "", "",
374ca955
A
372
373 "AD", "1997", "8", "13", "14", "14", "34", "12", "5",
73c04bcf 374 "Wed", "225", "2", "33", "3", "PM", "2", "2", "PDT", "1997", "4", "1997", "2450674", "52452513", "-0700", "PT", "4", "8", "3", "3",
b75a7d8f 375
73c04bcf 376 "Anno Domini", "1997", "August", "0013", "0014", "0014", "0034", "0012", "5130",
374ca955 377 "Wednesday", "0225", "0002", "0033", "0003", "PM", "0002", "0002", "Pacific Daylight Time", "1997", "0004", "1997", "2450674", "52452513", "-0700",
73c04bcf 378 "Pacific Time", "Wednesday", "August", "3rd quarter", "3rd quarter"
b75a7d8f
A
379 };
380
374ca955 381 const int32_t EXPECTED_LENGTH = sizeof(EXPECTED)/sizeof(EXPECTED[0]);
b75a7d8f 382
374ca955
A
383 assertTrue("data size", EXPECTED_LENGTH == COUNT * UDAT_FIELD_COUNT);
384
385 TimeZone* PT = TimeZone::createTimeZone("America/Los_Angeles");
386 for (j = 0, exp = 0; j < COUNT; ++j) {
387 // String str;
b75a7d8f 388 DateFormat* df = dateFormats[j];
374ca955
A
389 df->setTimeZone(*PT);
390 if (df->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
391 logln(" Pattern = " + ((SimpleDateFormat*) df)->toPattern(buf.remove()));
392 } else {
393 logln(" Pattern = ? (not a SimpleDateFormat)");
394 }
395 logln((UnicodeString)" Result = " + df->format(aug13, buf.remove()));
396
397 for (i = 0; i < UDAT_FIELD_COUNT; ++i, ++exp) {
398 FieldPosition pos(i);
73c04bcf
A
399 buf.remove();
400 df->format(aug13, buf, pos);
b75a7d8f 401 UnicodeString field;
374ca955
A
402 buf.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), field);
403 assertEquals((UnicodeString)"field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
404 ctou(EXPECTED[exp]), field);
b75a7d8f
A
405 }
406 }
374ca955
A
407
408 for (i=0; i<COUNT; ++i) {
409 delete dateFormats[i];
410 }
411 delete PT;
b75a7d8f 412}
374ca955 413
b75a7d8f 414// -------------------------------------
374ca955
A
415
416/**
417 * General parse/format tests. Add test cases as needed.
418 */
419void DateFormatTest::TestGeneral() {
420 const char* DATA[] = {
421 "yyyy MM dd HH:mm:ss.SSS",
422
423 // Milliseconds are left-justified, since they format as fractions of a second
424 "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",
425 "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",
426 "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567",
427 "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",
428 };
73c04bcf 429 expect(DATA, ARRAY_SIZE(DATA), Locale("en", "", ""));
b75a7d8f
A
430}
431
432// -------------------------------------
433
434/**
435 * Verify that strings which contain incomplete specifications are parsed
436 * correctly. In some instances, this means not being parsed at all, and
437 * returning an appropriate error.
438 */
439void
440DateFormatTest::TestPartialParse994()
441{
442 UErrorCode status = U_ZERO_ERROR;
443 SimpleDateFormat* f = new SimpleDateFormat(status);
73c04bcf 444 ASSERT_OK(status);
b75a7d8f
A
445 UDate null = 0;
446 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", date(97, 1 - 1, 17, 10, 11, 42));
447 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null);
448 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", null);
449 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", null);
450 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", null);
451 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
452 delete f;
453}
454
455// -------------------------------------
456
457void
458DateFormatTest::tryPat994(SimpleDateFormat* format, const char* pat, const char* str, UDate expected)
459{
460 UErrorCode status = U_ZERO_ERROR;
461 UDate null = 0;
462 logln(UnicodeString("Pattern \"") + pat + "\" String \"" + str + "\"");
463 //try {
464 format->applyPattern(pat);
465 UDate date = format->parse(str, status);
466 if (U_FAILURE(status) || date == null)
467 {
468 logln((UnicodeString)"ParseException: " + (int32_t)status);
469 if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
470 }
471 else
472 {
473 UnicodeString f;
474 ((DateFormat*)format)->format(date, f);
475 logln(UnicodeString(" parse(") + str + ") -> " + dateToString(date));
476 logln((UnicodeString)" format -> " + f);
477 if (expected == null ||
478 !(date == expected)) errln((UnicodeString)"FAIL: Expected null");//" + expected);
479 if (!(f == str)) errln(UnicodeString("FAIL: Expected ") + str);
480 }
481 //}
482 //catch(ParseException e) {
483 // logln((UnicodeString)"ParseException: " + e.getMessage());
484 // if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
485 //}
486 //catch(Exception e) {
487 // errln((UnicodeString)"*** Exception:");
488 // e.printStackTrace();
489 //}
490}
491
492// -------------------------------------
493
494/**
495 * Verify the behavior of patterns in which digits for different fields run together
496 * without intervening separators.
497 */
498void
499DateFormatTest::TestRunTogetherPattern985()
500{
501 UErrorCode status = U_ZERO_ERROR;
502 UnicodeString format("yyyyMMddHHmmssSSS");
503 UnicodeString now, then;
504 //UBool flag;
505 SimpleDateFormat *formatter = new SimpleDateFormat(format, status);
73c04bcf 506 ASSERT_OK(status);
b75a7d8f
A
507 UDate date1 = Calendar::getNow();
508 ((DateFormat*)formatter)->format(date1, now);
509 logln(now);
510 ParsePosition pos(0);
511 UDate date2 = formatter->parse(now, pos);
512 if (date2 == 0) then = "Parse stopped at " + pos.getIndex();
513 else ((DateFormat*)formatter)->format(date2, then);
514 logln(then);
515 if (!(date2 == date1)) errln((UnicodeString)"FAIL");
516 delete formatter;
517 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
518}
519
520// -------------------------------------
521
522/**
523 * Verify the behavior of patterns in which digits for different fields run together
524 * without intervening separators.
525 */
526void
527DateFormatTest::TestRunTogetherPattern917()
528{
529 UErrorCode status = U_ZERO_ERROR;
530 SimpleDateFormat* fmt;
531 UnicodeString myDate;
532 fmt = new SimpleDateFormat((UnicodeString)"yyyy/MM/dd", status);
73c04bcf 533 ASSERT_OK(status);
b75a7d8f
A
534 myDate = "1997/02/03";
535 testIt917(fmt, myDate, date(97, 2 - 1, 3));
536 delete fmt;
537 fmt = new SimpleDateFormat((UnicodeString)"yyyyMMdd", status);
538 myDate = "19970304";
539 testIt917(fmt, myDate, date(97, 3 - 1, 4));
540 delete fmt;
541 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
542}
543
544// -------------------------------------
545
546void
547DateFormatTest::testIt917(SimpleDateFormat* fmt, UnicodeString& str, UDate expected)
548{
549 UErrorCode status = U_ZERO_ERROR;
550 UnicodeString pattern;
551 logln((UnicodeString)"pattern=" + fmt->toPattern(pattern) + " string=" + str);
552 Formattable o;
553 //try {
554 ((Format*)fmt)->parseObject(str, o, status);
555 //}
556 if (U_FAILURE(status)) return;
557 //catch(ParseException e) {
558 // e.printStackTrace();
559 // return;
560 //}
561 logln((UnicodeString)"Parsed object: " + dateToString(o.getDate()));
562 if (!(o.getDate() == expected)) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
563 UnicodeString formatted; ((Format*)fmt)->format(o, formatted, status);
564 logln((UnicodeString)"Formatted string: " + formatted);
565 if (!(formatted == str)) errln((UnicodeString)"FAIL: Expected " + str);
566 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
567}
568
569// -------------------------------------
570
571/**
572 * Verify the handling of Czech June and July, which have the unique attribute that
573 * one is a proper prefix substring of the other.
574 */
575void
576DateFormatTest::TestCzechMonths459()
577{
578 UErrorCode status = U_ZERO_ERROR;
579 DateFormat* fmt = DateFormat::createDateInstance(DateFormat::FULL, Locale("cs", "", ""));
73c04bcf
A
580 if (fmt == NULL){
581 dataerrln("Error calling DateFormat::createDateInstance()");
582 return;
583 }
584
b75a7d8f
A
585 UnicodeString pattern;
586 logln((UnicodeString)"Pattern " + ((SimpleDateFormat*) fmt)->toPattern(pattern));
587 UDate june = date(97, UCAL_JUNE, 15);
588 UDate july = date(97, UCAL_JULY, 15);
589 UnicodeString juneStr; fmt->format(june, juneStr);
590 UnicodeString julyStr; fmt->format(july, julyStr);
591 //try {
592 logln((UnicodeString)"format(June 15 1997) = " + juneStr);
593 UDate d = fmt->parse(juneStr, status);
594 UnicodeString s; fmt->format(d, s);
595 int32_t month,yr,day,hr,min,sec; dateToFields(d,yr,month,day,hr,min,sec);
596 logln((UnicodeString)" -> parse -> " + s + " (month = " + month + ")");
597 if (month != UCAL_JUNE) errln((UnicodeString)"FAIL: Month should be June");
598 logln((UnicodeString)"format(July 15 1997) = " + julyStr);
599 d = fmt->parse(julyStr, status);
600 fmt->format(d, s);
601 dateToFields(d,yr,month,day,hr,min,sec);
602 logln((UnicodeString)" -> parse -> " + s + " (month = " + month + ")");
603 if (month != UCAL_JULY) errln((UnicodeString)"FAIL: Month should be July");
604 //}
605 //catch(ParseException e) {
606 if (U_FAILURE(status))
607 errln((UnicodeString)"Exception: " + (int32_t)status);
608 //}
609 delete fmt;
610}
611
612// -------------------------------------
613
614/**
615 * Test the handling of 'D' in patterns.
616 */
617void
618DateFormatTest::TestLetterDPattern212()
619{
620 UErrorCode status = U_ZERO_ERROR;
621 UnicodeString dateString("1995-040.05:01:29");
622 UnicodeString bigD("yyyy-DDD.hh:mm:ss");
623 UnicodeString littleD("yyyy-ddd.hh:mm:ss");
624 UDate expLittleD = date(95, 0, 1, 5, 1, 29);
625 UDate expBigD = expLittleD + 39 * 24 * 3600000.0;
626 expLittleD = expBigD; // Expect the same, with default lenient parsing
627 logln((UnicodeString)"dateString= " + dateString);
628 SimpleDateFormat *formatter = new SimpleDateFormat(bigD, status);
73c04bcf 629 ASSERT_OK(status);
b75a7d8f
A
630 ParsePosition pos(0);
631 UDate myDate = formatter->parse(dateString, pos);
632 logln((UnicodeString)"Using " + bigD + " -> " + myDate);
633 if (myDate != expBigD) errln((UnicodeString)"FAIL: Expected " + dateToString(expBigD));
634 delete formatter;
635 formatter = new SimpleDateFormat(littleD, status);
73c04bcf 636 ASSERT_OK(status);
b75a7d8f
A
637 pos = ParsePosition(0);
638 myDate = formatter->parse(dateString, pos);
639 logln((UnicodeString)"Using " + littleD + " -> " + dateToString(myDate));
640 if (myDate != expLittleD) errln((UnicodeString)"FAIL: Expected " + dateToString(expLittleD));
641 delete formatter;
642 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
643}
644
645// -------------------------------------
646
647/**
648 * Test the day of year pattern.
649 */
650void
651DateFormatTest::TestDayOfYearPattern195()
652{
653 UErrorCode status = U_ZERO_ERROR;
654 UDate today = Calendar::getNow();
655 int32_t year,month,day,hour,min,sec; dateToFields(today,year,month,day,hour,min,sec);
656 UDate expected = date(year, month, day);
657 logln((UnicodeString)"Test Date: " + dateToString(today));
658 SimpleDateFormat* sdf = (SimpleDateFormat*)DateFormat::createDateInstance();
73c04bcf
A
659 if (sdf == NULL){
660 dataerrln("Error calling DateFormat::createDateInstance()");
661 return;
662 }
b75a7d8f
A
663 tryPattern(*sdf, today, 0, expected);
664 tryPattern(*sdf, today, "G yyyy DDD", expected);
665 delete sdf;
666 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
667}
668
669// -------------------------------------
670
671void
672DateFormatTest::tryPattern(SimpleDateFormat& sdf, UDate d, const char* pattern, UDate expected)
673{
674 UErrorCode status = U_ZERO_ERROR;
675 if (pattern != 0) sdf.applyPattern(pattern);
676 UnicodeString thePat;
677 logln((UnicodeString)"pattern: " + sdf.toPattern(thePat));
678 UnicodeString formatResult; (*(DateFormat*)&sdf).format(d, formatResult);
679 logln((UnicodeString)" format -> " + formatResult);
680 // try {
681 UDate d2 = sdf.parse(formatResult, status);
682 logln((UnicodeString)" parse(" + formatResult + ") -> " + dateToString(d2));
683 if (d2 != expected) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
684 UnicodeString format2; (*(DateFormat*)&sdf).format(d2, format2);
685 logln((UnicodeString)" format -> " + format2);
686 if (!(formatResult == format2)) errln((UnicodeString)"FAIL: Round trip drift");
687 //}
688 //catch(Exception e) {
689 if (U_FAILURE(status))
690 errln((UnicodeString)"Error: " + (int32_t)status);
691 //}
692}
693
694// -------------------------------------
695
696/**
697 * Test the handling of single quotes in patterns.
698 */
699void
700DateFormatTest::TestQuotePattern161()
701{
702 UErrorCode status = U_ZERO_ERROR;
703 SimpleDateFormat* formatter = new SimpleDateFormat((UnicodeString)"MM/dd/yyyy 'at' hh:mm:ss a zzz", status);
73c04bcf 704 ASSERT_OK(status);
b75a7d8f
A
705 UDate currentTime_1 = date(97, UCAL_AUGUST, 13, 10, 42, 28);
706 UnicodeString dateString; ((DateFormat*)formatter)->format(currentTime_1, dateString);
707 UnicodeString exp("08/13/1997 at 10:42:28 AM ");
708 logln((UnicodeString)"format(" + dateToString(currentTime_1) + ") = " + dateString);
709 if (0 != dateString.compareBetween(0, exp.length(), exp, 0, exp.length())) errln((UnicodeString)"FAIL: Expected " + exp);
710 delete formatter;
711 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
712}
713
714// -------------------------------------
715
716/**
717 * Verify the correct behavior when handling invalid input strings.
718 */
719void
720DateFormatTest::TestBadInput135()
721{
722 UErrorCode status = U_ZERO_ERROR;
723 DateFormat::EStyle looks[] = {
724 DateFormat::SHORT, DateFormat::MEDIUM, DateFormat::LONG, DateFormat::FULL
725 };
726 int32_t looks_length = (int32_t)(sizeof(looks) / sizeof(looks[0]));
727 const char* strings[] = {
728 "Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
729 };
730 int32_t strings_length = (int32_t)(sizeof(strings) / sizeof(strings[0]));
731 DateFormat *full = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
73c04bcf
A
732 if(full==NULL) {
733 errln("could not create date time instance");
734 return;
735 }
b75a7d8f
A
736 UnicodeString expected("March 1, 2000 1:23:45 AM ");
737 for (int32_t i = 0; i < strings_length;++i) {
738 const char* text = strings[i];
739 for (int32_t j = 0; j < looks_length;++j) {
740 DateFormat::EStyle dateLook = looks[j];
741 for (int32_t k = 0; k < looks_length;++k) {
742 DateFormat::EStyle timeLook = looks[k];
743 DateFormat *df = DateFormat::createDateTimeInstance(dateLook, timeLook);
73c04bcf
A
744 if (df == NULL){
745 dataerrln("Error calling DateFormat::createDateTimeInstance()");
746 continue;
747 }
b75a7d8f
A
748 UnicodeString prefix = UnicodeString(text) + ", " + dateLook + "/" + timeLook + ": ";
749 //try {
750 UDate when = df->parse(text, status);
751 if (when == 0 && U_SUCCESS(status)) {
752 errln(prefix + "SHOULD NOT HAPPEN: parse returned 0.");
753 continue;
754 }
755 if (U_SUCCESS(status))
756 {
757 UnicodeString format;
758 full->format(when, format);
759 logln(prefix + "OK: " + format);
760 if (0!=format.compareBetween(0, expected.length(), expected, 0, expected.length()))
761 errln((UnicodeString)"FAIL: Expected " + expected + " got " + format);
762 }
763 //}
764 //catch(ParseException e) {
765 else
766 status = U_ZERO_ERROR;
767 //}
768 //catch(StringIndexOutOfBoundsException e) {
769 // errln(prefix + "SHOULD NOT HAPPEN: " + (int)status);
770 //}
771 delete df;
772 }
773 }
774 }
775 delete full;
776 if (U_FAILURE(status))
777 errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
778}
779
780const char* DateFormatTest::parseFormats[] = {
781 "MMMM d, yyyy",
782 "MMMM d yyyy",
783 "M/d/yy",
784 "d MMMM, yyyy",
785 "d MMMM yyyy",
786 "d MMMM",
787 "MMMM d",
788 "yyyy",
789 "h:mm a MMMM d, yyyy"
790};
791
792const char* DateFormatTest::inputStrings[] = {
793 "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
794 "April 1, 1997", "April 1, 1997", 0, 0, 0, 0, 0, "April 1", 0, 0,
795 "Jan 1, 1970", "January 1, 1970", 0, 0, 0, 0, 0, "January 1", 0, 0,
796 "Jan 1 2037", 0, "January 1 2037", 0, 0, 0, 0, "January 1", 0, 0,
797 "1/1/70", 0, 0, "1/1/70", 0, 0, 0, 0, "0001", 0,
798 "5 May 1997", 0, 0, 0, 0, "5 May 1997", "5 May", 0, "0005", 0,
799 "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
800 "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
801 "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
802 "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
803 "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
804};
805
806// -------------------------------------
807
808/**
809 * Verify the correct behavior when parsing an array of inputs against an
810 * array of patterns, with known results. The results are encoded after
811 * the input strings in each row.
812 */
813void
814DateFormatTest::TestBadInput135a()
815{
816 UErrorCode status = U_ZERO_ERROR;
817 SimpleDateFormat* dateParse = new SimpleDateFormat(status);
818 if(U_FAILURE(status)) {
819 errln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
820 delete dateParse;
821 return;
822 }
823 const char* s;
824 UDate date;
825 const uint32_t PF_LENGTH = (int32_t)(sizeof(parseFormats)/sizeof(parseFormats[0]));
826 const uint32_t INPUT_LENGTH = (int32_t)(sizeof(inputStrings)/sizeof(inputStrings[0]));
827
828 dateParse->applyPattern("d MMMM, yyyy");
829 dateParse->adoptTimeZone(TimeZone::createDefault());
830 s = "not parseable";
831 UnicodeString thePat;
832 logln(UnicodeString("Trying to parse \"") + s + "\" with " + dateParse->toPattern(thePat));
833 //try {
834 date = dateParse->parse(s, status);
835 if (U_SUCCESS(status))
836 errln((UnicodeString)"FAIL: Expected exception during parse");
837 //}
838 //catch(Exception ex) {
839 else
840 logln((UnicodeString)"Exception during parse: " + (int32_t)status);
841 status = U_ZERO_ERROR;
842 //}
843 for (uint32_t i = 0; i < INPUT_LENGTH; i += (PF_LENGTH + 1)) {
844 ParsePosition parsePosition(0);
845 UnicodeString s( inputStrings[i]);
846 for (uint32_t index = 0; index < PF_LENGTH;++index) {
847 const char* expected = inputStrings[i + 1 + index];
848 dateParse->applyPattern(parseFormats[index]);
849 dateParse->adoptTimeZone(TimeZone::createDefault());
850 //try {
851 parsePosition.setIndex(0);
852 date = dateParse->parse(s, parsePosition);
853 if (parsePosition.getIndex() != 0) {
854 UnicodeString s1, s2;
855 s.extract(0, parsePosition.getIndex(), s1);
856 s.extract(parsePosition.getIndex(), s.length(), s2);
857 if (date == 0) {
858 errln((UnicodeString)"ERROR: null result fmt=\"" +
859 parseFormats[index] +
860 "\" pos=" + parsePosition.getIndex() + " " +
861 s1 + "|" + s2);
862 }
863 else {
864 UnicodeString result;
865 ((DateFormat*)dateParse)->format(date, result);
866 logln((UnicodeString)"Parsed \"" + s + "\" using \"" + dateParse->toPattern(thePat) + "\" to: " + result);
867 if (expected == 0)
868 errln((UnicodeString)"FAIL: Expected parse failure");
869 else if (!(result == expected))
870 errln(UnicodeString("FAIL: Expected ") + expected);
871 }
872 }
873 else if (expected != 0) {
874 errln(UnicodeString("FAIL: Expected ") + expected + " from \"" +
875 s + "\" with \"" + dateParse->toPattern(thePat) + "\"");
876 }
877 //}
878 //catch(Exception ex) {
879 if (U_FAILURE(status))
880 errln((UnicodeString)"An exception was thrown during parse: " + (int32_t)status);
881 //}
882 }
883 }
884 delete dateParse;
885 if (U_FAILURE(status))
886 errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
887}
888
889// -------------------------------------
890
891/**
892 * Test the parsing of two-digit years.
893 */
894void
895DateFormatTest::TestTwoDigitYear()
896{
897 UErrorCode ec = U_ZERO_ERROR;
898 SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);
899 if (U_FAILURE(ec)) {
900 errln("FAIL: SimpleDateFormat constructor");
901 return;
902 }
903 parse2DigitYear(fmt, "5/6/17", date(117, UCAL_JUNE, 5));
904 parse2DigitYear(fmt, "4/6/34", date(34, UCAL_JUNE, 4));
905}
906
907// -------------------------------------
908
909void
910DateFormatTest::parse2DigitYear(DateFormat& fmt, const char* str, UDate expected)
911{
912 UErrorCode status = U_ZERO_ERROR;
913 //try {
914 UDate d = fmt.parse(str, status);
915 UnicodeString thePat;
916 logln(UnicodeString("Parsing \"") + str + "\" with " + ((SimpleDateFormat*)&fmt)->toPattern(thePat) +
917 " => " + dateToString(d));
918 if (d != expected) errln((UnicodeString)"FAIL: Expected " + expected);
919 //}
920 //catch(ParseException e) {
921 if (U_FAILURE(status))
922 errln((UnicodeString)"FAIL: Got exception");
923 //}
924}
925
926// -------------------------------------
927
928/**
929 * Test the formatting of time zones.
930 */
931void
932DateFormatTest::TestDateFormatZone061()
933{
934 UErrorCode status = U_ZERO_ERROR;
935 UDate date;
936 DateFormat *formatter;
937 date= 859248000000.0;
938 logln((UnicodeString)"Date 1997/3/25 00:00 GMT: " + date);
939 formatter = new SimpleDateFormat((UnicodeString)"dd-MMM-yyyyy HH:mm", Locale::getUK(), status);
940 if(U_FAILURE(status)) {
941 errln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
942 delete formatter;
943 return;
944 }
945 formatter->adoptTimeZone(TimeZone::createTimeZone("GMT"));
946 UnicodeString temp; formatter->format(date, temp);
947 logln((UnicodeString)"Formatted in GMT to: " + temp);
948 //try {
949 UDate tempDate = formatter->parse(temp, status);
950 logln((UnicodeString)"Parsed to: " + dateToString(tempDate));
951 if (tempDate != date) errln((UnicodeString)"FAIL: Expected " + dateToString(date));
952 //}
953 //catch(Throwable t) {
954 if (U_FAILURE(status))
955 errln((UnicodeString)"Date Formatter throws: " + (int32_t)status);
956 //}
957 delete formatter;
958}
959
960// -------------------------------------
961
962/**
963 * Test the formatting of time zones.
964 */
965void
966DateFormatTest::TestDateFormatZone146()
967{
968 TimeZone *saveDefault = TimeZone::createDefault();
969
970 //try {
971 TimeZone *thedefault = TimeZone::createTimeZone("GMT");
972 TimeZone::setDefault(*thedefault);
973 // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
974
975 // check to be sure... its GMT all right
976 TimeZone *testdefault = TimeZone::createDefault();
977 UnicodeString testtimezone;
978 testdefault->getID(testtimezone);
979 if (testtimezone == "GMT")
980 logln("Test timezone = " + testtimezone);
981 else
982 errln("Test timezone should be GMT, not " + testtimezone);
983
984 UErrorCode status = U_ZERO_ERROR;
985 // now try to use the default GMT time zone
986 GregorianCalendar *greenwichcalendar =
987 new GregorianCalendar(1997, 3, 4, 23, 0, status);
988 failure(status, "new GregorianCalendar");
989 //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
990 //greenwichcalendar.set(1997, 3, 4, 23, 0);
991 // try anything to set hour to 23:00 !!!
992 greenwichcalendar->set(UCAL_HOUR_OF_DAY, 23);
993 // get time
994 UDate greenwichdate = greenwichcalendar->getTime(status);
995 // format every way
996 UnicodeString DATA [] = {
73c04bcf 997 UnicodeString("simple format: "), UnicodeString("04/04/97 23:00 GMT+00:00"),
b75a7d8f 998 UnicodeString("MM/dd/yy HH:mm z"),
73c04bcf 999 UnicodeString("full format: "), UnicodeString("Friday, April 4, 1997 11:00:00 o'clock PM GMT+00:00"),
b75a7d8f 1000 UnicodeString("EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z"),
73c04bcf 1001 UnicodeString("long format: "), UnicodeString("April 4, 1997 11:00:00 PM GMT+00:00"),
b75a7d8f
A
1002 UnicodeString("MMMM d, yyyy h:mm:ss a z"),
1003 UnicodeString("default format: "), UnicodeString("04-Apr-97 11:00:00 PM"),
1004 UnicodeString("dd-MMM-yy h:mm:ss a"),
1005 UnicodeString("short format: "), UnicodeString("4/4/97 11:00 PM"),
1006 UnicodeString("M/d/yy h:mm a")
1007 };
1008 int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
1009
1010 for (int32_t i=0; i<DATA_length; i+=3) {
1011 DateFormat *fmt = new SimpleDateFormat(DATA[i+2], Locale::getEnglish(), status);
1012 if(failure(status, "new SimpleDateFormat")) break;
1013 fmt->setCalendar(*greenwichcalendar);
1014 UnicodeString result;
1015 result = fmt->format(greenwichdate, result);
1016 logln(DATA[i] + result);
1017 if (result != DATA[i+1])
1018 errln("FAIL: Expected " + DATA[i+1] + ", got " + result);
1019 delete fmt;
1020 }
1021 //}
1022 //finally {
1023 TimeZone::adoptDefault(saveDefault);
1024 //}
1025 delete testdefault;
1026 delete greenwichcalendar;
1027 delete thedefault;
1028
1029
1030}
1031
1032// -------------------------------------
1033
1034/**
1035 * Test the formatting of dates in different locales.
1036 */
1037void
1038DateFormatTest::TestLocaleDateFormat() // Bug 495
1039{
1040 UDate testDate = date(97, UCAL_SEPTEMBER, 15);
1041 DateFormat *dfFrench = DateFormat::createDateTimeInstance(DateFormat::FULL,
1042 DateFormat::FULL, Locale::getFrench());
1043 DateFormat *dfUS = DateFormat::createDateTimeInstance(DateFormat::FULL,
1044 DateFormat::FULL, Locale::getUS());
374ca955
A
1045 UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 00 h 00 HAP (\\u00C9UA)" );
1046 expectedFRENCH = expectedFRENCH.unescape();
b75a7d8f 1047 //UnicodeString expectedUS ( "Monday, September 15, 1997 12:00:00 o'clock AM PDT" );
73c04bcf 1048 UnicodeString expectedUS ( "Monday, September 15, 1997 12:00:00 AM PT" );
b75a7d8f
A
1049 logln((UnicodeString)"Date set to : " + dateToString(testDate));
1050 UnicodeString out;
73c04bcf
A
1051 if (dfUS == NULL || dfFrench == NULL){
1052 dataerrln("Error calling DateFormat::createDateTimeInstance)");
1053 delete dfUS;
1054 delete dfFrench;
1055 return;
1056 }
1057
b75a7d8f
A
1058 dfFrench->format(testDate, out);
1059 logln((UnicodeString)"Date Formated with French Locale " + out);
1060 if (!(out == expectedFRENCH))
1061 errln((UnicodeString)"FAIL: Expected " + expectedFRENCH);
1062 out.truncate(0);
1063 dfUS->format(testDate, out);
1064 logln((UnicodeString)"Date Formated with US Locale " + out);
1065 if (!(out == expectedUS))
1066 errln((UnicodeString)"FAIL: Expected " + expectedUS);
1067 delete dfUS;
1068 delete dfFrench;
1069}
1070
1071/**
1072 * Test DateFormat(Calendar) API
1073 */
1074void DateFormatTest::TestDateFormatCalendar() {
1075 DateFormat *date=0, *time=0, *full=0;
1076 Calendar *cal=0;
1077 UnicodeString str;
1078 ParsePosition pos;
1079 UDate when;
1080 UErrorCode ec = U_ZERO_ERROR;
1081
1082 /* Create a formatter for date fields. */
1083 date = DateFormat::createDateInstance(DateFormat::kShort, Locale::getUS());
1084 if (date == NULL) {
1085 errln("FAIL: createDateInstance failed");
1086 goto FAIL;
1087 }
1088
1089 /* Create a formatter for time fields. */
1090 time = DateFormat::createTimeInstance(DateFormat::kShort, Locale::getUS());
1091 if (time == NULL) {
1092 errln("FAIL: createTimeInstance failed");
1093 goto FAIL;
1094 }
1095
1096 /* Create a full format for output */
1097 full = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
1098 Locale::getUS());
1099 if (full == NULL) {
1100 errln("FAIL: createInstance failed");
1101 goto FAIL;
1102 }
1103
1104 /* Create a calendar */
1105 cal = Calendar::createInstance(Locale::getUS(), ec);
1106 if (cal == NULL || U_FAILURE(ec)) {
1107 errln((UnicodeString)"FAIL: Calendar::createInstance failed with " +
1108 u_errorName(ec));
1109 goto FAIL;
1110 }
1111
1112 /* Parse the date */
1113 cal->clear();
1114 str = UnicodeString("4/5/2001", "");
1115 pos.setIndex(0);
1116 date->parse(str, *cal, pos);
1117 if (pos.getIndex() != str.length()) {
1118 errln((UnicodeString)"FAIL: DateFormat::parse(4/5/2001) failed at " +
1119 pos.getIndex());
1120 goto FAIL;
1121 }
1122
1123 /* Parse the time */
1124 str = UnicodeString("5:45 PM", "");
1125 pos.setIndex(0);
1126 time->parse(str, *cal, pos);
1127 if (pos.getIndex() != str.length()) {
1128 errln((UnicodeString)"FAIL: DateFormat::parse(17:45) failed at " +
1129 pos.getIndex());
1130 goto FAIL;
1131 }
1132
1133 /* Check result */
1134 when = cal->getTime(ec);
1135 if (U_FAILURE(ec)) {
1136 errln((UnicodeString)"FAIL: cal->getTime() failed with " + u_errorName(ec));
1137 goto FAIL;
1138 }
1139 str.truncate(0);
1140 full->format(when, str);
1141 // Thursday, April 5, 2001 5:45:00 PM PDT 986517900000
1142 if (when == 986517900000.0) {
1143 logln("Ok: Parsed result: " + str);
1144 } else {
1145 errln("FAIL: Parsed result: " + str + ", exp 4/5/2001 5:45 PM");
1146 }
1147
1148 FAIL:
1149 delete date;
1150 delete time;
1151 delete full;
1152 delete cal;
1153}
1154
1155/**
1156 * Test DateFormat's parsing of space characters. See jitterbug 1916.
1157 */
1158void DateFormatTest::TestSpaceParsing() {
1159 const char* DATA[] = {
1160 "yyyy MM dd HH:mm:ss",
1161
1162 // pattern, input, expected parse or NULL if expect parse failure
1163 "MMMM d yy", " 04 05 06", NULL, // MMMM wants Apr/April
1164 NULL, "04 05 06", NULL,
1165 "MM d yy", " 04 05 06", "2006 04 05 00:00:00",
1166 NULL, "04 05 06", "2006 04 05 00:00:00",
1167 "MMMM d yy", " Apr 05 06", "2006 04 05 00:00:00",
1168 NULL, "Apr 05 06", "2006 04 05 00:00:00",
1169 };
1170 const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1171
1172 expectParse(DATA, DATA_len, Locale("en"));
1173}
1174
1175/**
1176 * Test handling of "HHmmss" pattern.
1177 */
1178void DateFormatTest::TestExactCountFormat() {
1179 const char* DATA[] = {
1180 "yyyy MM dd HH:mm:ss",
1181
1182 // pattern, input, expected parse or NULL if expect parse failure
1183 "HHmmss", "123456", "1970 01 01 12:34:56",
1184 NULL, "12345", "1970 01 01 01:23:45",
1185 NULL, "1234", NULL,
1186 NULL, "00-05", NULL,
1187 NULL, "12-34", NULL,
1188 NULL, "00+05", NULL,
1189 "ahhmm", "PM730", "1970 01 01 19:30:00",
1190 };
1191 const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1192
1193 expectParse(DATA, DATA_len, Locale("en"));
1194}
1195
1196/**
1197 * Test handling of white space.
1198 */
1199void DateFormatTest::TestWhiteSpaceParsing() {
1200 const char* DATA[] = {
1201 "yyyy MM dd",
1202
1203 // pattern, input, expected parse or null if expect parse failure
1204
1205 // Pattern space run should parse input text space run
1206 "MM d yy", " 04 01 03", "2003 04 01",
1207 NULL, " 04 01 03 ", "2003 04 01",
1208 };
1209 const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1210
1211 expectParse(DATA, DATA_len, Locale("en"));
1212}
1213
374ca955
A
1214
1215void DateFormatTest::TestInvalidPattern() {
1216 UErrorCode ec = U_ZERO_ERROR;
1217 SimpleDateFormat f(UnicodeString("Yesterday"), ec);
73c04bcf 1218 ASSERT_OK(ec);
374ca955
A
1219 UnicodeString out;
1220 FieldPosition pos;
1221 f.format((UDate)0, out, pos);
1222 logln(out);
1223 // The bug is that the call to format() will crash. By not
1224 // crashing, the test passes.
1225}
1226
1227void DateFormatTest::TestGreekMay() {
1228 UErrorCode ec = U_ZERO_ERROR;
1229 UDate date = -9896080848000.0;
1230 SimpleDateFormat fmt("EEEE, dd MMMM yyyy h:mm:ss a", Locale("el", "", ""), ec);
1231 if (!assertSuccess("SimpleDateFormat::ct", ec)) return;
1232 UnicodeString str;
1233 fmt.format(date, str);
1234 ParsePosition pos(0);
1235 UDate d2 = fmt.parse(str, pos);
1236 if (date != d2) {
1237 errln("FAIL: unable to parse strings where case-folding changes length");
1238 }
1239}
1240
73c04bcf
A
1241void DateFormatTest::TestStandAloneMonths()
1242{
1243 const char *EN_DATA[] = {
1244 "yyyy MM dd HH:mm:ss",
1245
1246 "yyyy LLLL dd H:mm:ss", "fp", "2004 03 10 16:36:31", "2004 March 10 16:36:31", "2004 03 10 16:36:31",
1247 "yyyy LLL dd H:mm:ss", "fp", "2004 03 10 16:36:31", "2004 Mar 10 16:36:31", "2004 03 10 16:36:31",
1248 "yyyy LLLL dd H:mm:ss", "F", "2004 03 10 16:36:31", "2004 March 10 16:36:31",
1249 "yyyy LLL dd H:mm:ss", "pf", "2004 Mar 10 16:36:31", "2004 03 10 16:36:31", "2004 Mar 10 16:36:31",
1250
1251 "LLLL", "fp", "1970 01 01 0:00:00", "January", "1970 01 01 0:00:00",
1252 "LLLL", "fp", "1970 02 01 0:00:00", "February", "1970 02 01 0:00:00",
1253 "LLLL", "fp", "1970 03 01 0:00:00", "March", "1970 03 01 0:00:00",
1254 "LLLL", "fp", "1970 04 01 0:00:00", "April", "1970 04 01 0:00:00",
1255 "LLLL", "fp", "1970 05 01 0:00:00", "May", "1970 05 01 0:00:00",
1256 "LLLL", "fp", "1970 06 01 0:00:00", "June", "1970 06 01 0:00:00",
1257 "LLLL", "fp", "1970 07 01 0:00:00", "July", "1970 07 01 0:00:00",
1258 "LLLL", "fp", "1970 08 01 0:00:00", "August", "1970 08 01 0:00:00",
1259 "LLLL", "fp", "1970 09 01 0:00:00", "September", "1970 09 01 0:00:00",
1260 "LLLL", "fp", "1970 10 01 0:00:00", "October", "1970 10 01 0:00:00",
1261 "LLLL", "fp", "1970 11 01 0:00:00", "November", "1970 11 01 0:00:00",
1262 "LLLL", "fp", "1970 12 01 0:00:00", "December", "1970 12 01 0:00:00",
1263
1264 "LLL", "fp", "1970 01 01 0:00:00", "Jan", "1970 01 01 0:00:00",
1265 "LLL", "fp", "1970 02 01 0:00:00", "Feb", "1970 02 01 0:00:00",
1266 "LLL", "fp", "1970 03 01 0:00:00", "Mar", "1970 03 01 0:00:00",
1267 "LLL", "fp", "1970 04 01 0:00:00", "Apr", "1970 04 01 0:00:00",
1268 "LLL", "fp", "1970 05 01 0:00:00", "May", "1970 05 01 0:00:00",
1269 "LLL", "fp", "1970 06 01 0:00:00", "Jun", "1970 06 01 0:00:00",
1270 "LLL", "fp", "1970 07 01 0:00:00", "Jul", "1970 07 01 0:00:00",
1271 "LLL", "fp", "1970 08 01 0:00:00", "Aug", "1970 08 01 0:00:00",
1272 "LLL", "fp", "1970 09 01 0:00:00", "Sep", "1970 09 01 0:00:00",
1273 "LLL", "fp", "1970 10 01 0:00:00", "Oct", "1970 10 01 0:00:00",
1274 "LLL", "fp", "1970 11 01 0:00:00", "Nov", "1970 11 01 0:00:00",
1275 "LLL", "fp", "1970 12 01 0:00:00", "Dec", "1970 12 01 0:00:00",
1276 };
1277
1278 const char *CS_DATA[] = {
1279 "yyyy MM dd HH:mm:ss",
1280
1281 "yyyy LLLL dd H:mm:ss", "fp", "2004 04 10 16:36:31", "2004 duben 10 16:36:31", "2004 04 10 16:36:31",
1282 "yyyy MMMM dd H:mm:ss", "fp", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31", "2004 04 10 16:36:31",
1283 "yyyy LLL dd H:mm:ss", "fp", "2004 04 10 16:36:31", "2004 4. 10 16:36:31", "2004 04 10 16:36:31",
1284 "yyyy LLLL dd H:mm:ss", "F", "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
1285 "yyyy MMMM dd H:mm:ss", "F", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
1286 "yyyy LLLL dd H:mm:ss", "pf", "2004 duben 10 16:36:31", "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
1287 "yyyy MMMM dd H:mm:ss", "pf", "2004 dubna 10 16:36:31", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
1288
1289 "LLLL", "fp", "1970 01 01 0:00:00", "leden", "1970 01 01 0:00:00",
1290 "LLLL", "fp", "1970 02 01 0:00:00", "\\u00FAnor", "1970 02 01 0:00:00",
1291 "LLLL", "fp", "1970 03 01 0:00:00", "b\\u0159ezen", "1970 03 01 0:00:00",
1292 "LLLL", "fp", "1970 04 01 0:00:00", "duben", "1970 04 01 0:00:00",
1293 "LLLL", "fp", "1970 05 01 0:00:00", "kv\\u011Bten", "1970 05 01 0:00:00",
1294 "LLLL", "fp", "1970 06 01 0:00:00", "\\u010Derven", "1970 06 01 0:00:00",
1295 "LLLL", "fp", "1970 07 01 0:00:00", "\\u010Dervenec", "1970 07 01 0:00:00",
1296 "LLLL", "fp", "1970 08 01 0:00:00", "srpen", "1970 08 01 0:00:00",
1297 "LLLL", "fp", "1970 09 01 0:00:00", "z\\u00E1\\u0159\\u00ED", "1970 09 01 0:00:00",
1298 "LLLL", "fp", "1970 10 01 0:00:00", "\\u0159\\u00EDjen", "1970 10 01 0:00:00",
1299 "LLLL", "fp", "1970 11 01 0:00:00", "listopad", "1970 11 01 0:00:00",
1300 "LLLL", "fp", "1970 12 01 0:00:00", "prosinec", "1970 12 01 0:00:00",
1301
1302 "LLL", "fp", "1970 01 01 0:00:00", "1.", "1970 01 01 0:00:00",
1303 "LLL", "fp", "1970 02 01 0:00:00", "2.", "1970 02 01 0:00:00",
1304 "LLL", "fp", "1970 03 01 0:00:00", "3.", "1970 03 01 0:00:00",
1305 "LLL", "fp", "1970 04 01 0:00:00", "4.", "1970 04 01 0:00:00",
1306 "LLL", "fp", "1970 05 01 0:00:00", "5.", "1970 05 01 0:00:00",
1307 "LLL", "fp", "1970 06 01 0:00:00", "6.", "1970 06 01 0:00:00",
1308 "LLL", "fp", "1970 07 01 0:00:00", "7.", "1970 07 01 0:00:00",
1309 "LLL", "fp", "1970 08 01 0:00:00", "8.", "1970 08 01 0:00:00",
1310 "LLL", "fp", "1970 09 01 0:00:00", "9.", "1970 09 01 0:00:00",
1311 "LLL", "fp", "1970 10 01 0:00:00", "10.", "1970 10 01 0:00:00",
1312 "LLL", "fp", "1970 11 01 0:00:00", "11.", "1970 11 01 0:00:00",
1313 "LLL", "fp", "1970 12 01 0:00:00", "12.", "1970 12 01 0:00:00",
1314 };
1315
1316 expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1317 expect(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
1318}
1319
1320void DateFormatTest::TestStandAloneDays()
1321{
1322 const char *EN_DATA[] = {
1323 "yyyy MM dd HH:mm:ss",
1324
1325 "cccc", "fp", "1970 01 04 0:00:00", "Sunday", "1970 01 04 0:00:00",
1326 "cccc", "fp", "1970 01 05 0:00:00", "Monday", "1970 01 05 0:00:00",
1327 "cccc", "fp", "1970 01 06 0:00:00", "Tuesday", "1970 01 06 0:00:00",
1328 "cccc", "fp", "1970 01 07 0:00:00", "Wednesday", "1970 01 07 0:00:00",
1329 "cccc", "fp", "1970 01 01 0:00:00", "Thursday", "1970 01 01 0:00:00",
1330 "cccc", "fp", "1970 01 02 0:00:00", "Friday", "1970 01 02 0:00:00",
1331 "cccc", "fp", "1970 01 03 0:00:00", "Saturday", "1970 01 03 0:00:00",
1332
1333 "ccc", "fp", "1970 01 04 0:00:00", "Sun", "1970 01 04 0:00:00",
1334 "ccc", "fp", "1970 01 05 0:00:00", "Mon", "1970 01 05 0:00:00",
1335 "ccc", "fp", "1970 01 06 0:00:00", "Tue", "1970 01 06 0:00:00",
1336 "ccc", "fp", "1970 01 07 0:00:00", "Wed", "1970 01 07 0:00:00",
1337 "ccc", "fp", "1970 01 01 0:00:00", "Thu", "1970 01 01 0:00:00",
1338 "ccc", "fp", "1970 01 02 0:00:00", "Fri", "1970 01 02 0:00:00",
1339 "ccc", "fp", "1970 01 03 0:00:00", "Sat", "1970 01 03 0:00:00",
1340 };
1341
1342 const char *CS_DATA[] = {
1343 "yyyy MM dd HH:mm:ss",
1344
1345 "cccc", "fp", "1970 01 04 0:00:00", "ned\\u011Ble", "1970 01 04 0:00:00",
1346 "cccc", "fp", "1970 01 05 0:00:00", "pond\\u011Bl\\u00ED", "1970 01 05 0:00:00",
1347 "cccc", "fp", "1970 01 06 0:00:00", "\\u00FAter\\u00FD", "1970 01 06 0:00:00",
1348 "cccc", "fp", "1970 01 07 0:00:00", "st\\u0159eda", "1970 01 07 0:00:00",
1349 "cccc", "fp", "1970 01 01 0:00:00", "\\u010Dtvrtek", "1970 01 01 0:00:00",
1350 "cccc", "fp", "1970 01 02 0:00:00", "p\\u00E1tek", "1970 01 02 0:00:00",
1351 "cccc", "fp", "1970 01 03 0:00:00", "sobota", "1970 01 03 0:00:00",
1352
1353 "ccc", "fp", "1970 01 04 0:00:00", "ne", "1970 01 04 0:00:00",
1354 "ccc", "fp", "1970 01 05 0:00:00", "po", "1970 01 05 0:00:00",
1355 "ccc", "fp", "1970 01 06 0:00:00", "\\u00FAt", "1970 01 06 0:00:00",
1356 "ccc", "fp", "1970 01 07 0:00:00", "st", "1970 01 07 0:00:00",
1357 "ccc", "fp", "1970 01 01 0:00:00", "\\u010Dt", "1970 01 01 0:00:00",
1358 "ccc", "fp", "1970 01 02 0:00:00", "p\\u00E1", "1970 01 02 0:00:00",
1359 "ccc", "fp", "1970 01 03 0:00:00", "so", "1970 01 03 0:00:00",
1360 };
1361
1362 expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1363 expect(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
1364}
1365
1366void DateFormatTest::TestNarrowNames()
1367{
1368 const char *EN_DATA[] = {
1369 "yyyy MM dd HH:mm:ss",
1370
1371 "yyyy MMMMM dd H:mm:ss", "2004 03 10 16:36:31", "2004 M 10 16:36:31",
1372 "yyyy LLLLL dd H:mm:ss", "2004 03 10 16:36:31", "2004 M 10 16:36:31",
1373
1374 "MMMMM", "1970 01 01 0:00:00", "J",
1375 "MMMMM", "1970 02 01 0:00:00", "F",
1376 "MMMMM", "1970 03 01 0:00:00", "M",
1377 "MMMMM", "1970 04 01 0:00:00", "A",
1378 "MMMMM", "1970 05 01 0:00:00", "M",
1379 "MMMMM", "1970 06 01 0:00:00", "J",
1380 "MMMMM", "1970 07 01 0:00:00", "J",
1381 "MMMMM", "1970 08 01 0:00:00", "A",
1382 "MMMMM", "1970 09 01 0:00:00", "S",
1383 "MMMMM", "1970 10 01 0:00:00", "O",
1384 "MMMMM", "1970 11 01 0:00:00", "N",
1385 "MMMMM", "1970 12 01 0:00:00", "D",
1386
1387 "LLLLL", "1970 01 01 0:00:00", "J",
1388 "LLLLL", "1970 02 01 0:00:00", "F",
1389 "LLLLL", "1970 03 01 0:00:00", "M",
1390 "LLLLL", "1970 04 01 0:00:00", "A",
1391 "LLLLL", "1970 05 01 0:00:00", "M",
1392 "LLLLL", "1970 06 01 0:00:00", "J",
1393 "LLLLL", "1970 07 01 0:00:00", "J",
1394 "LLLLL", "1970 08 01 0:00:00", "A",
1395 "LLLLL", "1970 09 01 0:00:00", "S",
1396 "LLLLL", "1970 10 01 0:00:00", "O",
1397 "LLLLL", "1970 11 01 0:00:00", "N",
1398 "LLLLL", "1970 12 01 0:00:00", "D",
1399
1400 "EEEEE", "1970 01 04 0:00:00", "S",
1401 "EEEEE", "1970 01 05 0:00:00", "M",
1402 "EEEEE", "1970 01 06 0:00:00", "T",
1403 "EEEEE", "1970 01 07 0:00:00", "W",
1404 "EEEEE", "1970 01 01 0:00:00", "T",
1405 "EEEEE", "1970 01 02 0:00:00", "F",
1406 "EEEEE", "1970 01 03 0:00:00", "S",
1407
1408 "ccccc", "1970 01 04 0:00:00", "S",
1409 "ccccc", "1970 01 05 0:00:00", "M",
1410 "ccccc", "1970 01 06 0:00:00", "T",
1411 "ccccc", "1970 01 07 0:00:00", "W",
1412 "ccccc", "1970 01 01 0:00:00", "T",
1413 "ccccc", "1970 01 02 0:00:00", "F",
1414 "ccccc", "1970 01 03 0:00:00", "S",
1415 };
1416
1417 const char *CS_DATA[] = {
1418 "yyyy MM dd HH:mm:ss",
1419
1420 "yyyy LLLLL dd H:mm:ss", "2004 04 10 16:36:31", "2004 d 10 16:36:31",
1421 "yyyy MMMMM dd H:mm:ss", "2004 04 10 16:36:31", "2004 d 10 16:36:31",
1422
1423 "MMMMM", "1970 01 01 0:00:00", "l",
1424 "MMMMM", "1970 02 01 0:00:00", "\\u00FA",
1425 "MMMMM", "1970 03 01 0:00:00", "b",
1426 "MMMMM", "1970 04 01 0:00:00", "d",
1427 "MMMMM", "1970 05 01 0:00:00", "k",
1428 "MMMMM", "1970 06 01 0:00:00", "\\u010D",
1429 "MMMMM", "1970 07 01 0:00:00", "\\u010D",
1430 "MMMMM", "1970 08 01 0:00:00", "s",
1431 "MMMMM", "1970 09 01 0:00:00", "z",
1432 "MMMMM", "1970 10 01 0:00:00", "\\u0159",
1433 "MMMMM", "1970 11 01 0:00:00", "l",
1434 "MMMMM", "1970 12 01 0:00:00", "p",
1435
1436 "LLLLL", "1970 01 01 0:00:00", "l",
1437 "LLLLL", "1970 02 01 0:00:00", "\\u00FA",
1438 "LLLLL", "1970 03 01 0:00:00", "b",
1439 "LLLLL", "1970 04 01 0:00:00", "d",
1440 "LLLLL", "1970 05 01 0:00:00", "k",
1441 "LLLLL", "1970 06 01 0:00:00", "\\u010D",
1442 "LLLLL", "1970 07 01 0:00:00", "\\u010D",
1443 "LLLLL", "1970 08 01 0:00:00", "s",
1444 "LLLLL", "1970 09 01 0:00:00", "z",
1445 "LLLLL", "1970 10 01 0:00:00", "\\u0159",
1446 "LLLLL", "1970 11 01 0:00:00", "l",
1447 "LLLLL", "1970 12 01 0:00:00", "p",
1448
1449 "EEEEE", "1970 01 04 0:00:00", "N",
1450 "EEEEE", "1970 01 05 0:00:00", "P",
1451 "EEEEE", "1970 01 06 0:00:00", "\\u00DA",
1452 "EEEEE", "1970 01 07 0:00:00", "S",
1453 "EEEEE", "1970 01 01 0:00:00", "\\u010C",
1454 "EEEEE", "1970 01 02 0:00:00", "P",
1455 "EEEEE", "1970 01 03 0:00:00", "S",
1456
1457 "ccccc", "1970 01 04 0:00:00", "N",
1458 "ccccc", "1970 01 05 0:00:00", "P",
1459 "ccccc", "1970 01 06 0:00:00", "\\u00DA",
1460 "ccccc", "1970 01 07 0:00:00", "S",
1461 "ccccc", "1970 01 01 0:00:00", "\\u010C",
1462 "ccccc", "1970 01 02 0:00:00", "P",
1463 "ccccc", "1970 01 03 0:00:00", "S",
1464 };
1465
1466 expectFormat(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1467 expectFormat(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
1468}
1469
1470void DateFormatTest::TestEras()
1471{
1472 const char *EN_DATA[] = {
1473 "yyyy MM dd",
1474
1475 "MMMM dd yyyy G", "fp", "1951 07 17", "July 17 1951 AD", "1951 07 17",
1476 "MMMM dd yyyy GG", "fp", "1951 07 17", "July 17 1951 AD", "1951 07 17",
1477 "MMMM dd yyyy GGG", "fp", "1951 07 17", "July 17 1951 AD", "1951 07 17",
1478 "MMMM dd yyyy GGGG", "fp", "1951 07 17", "July 17 1951 Anno Domini", "1951 07 17",
1479
1480 "MMMM dd yyyy G", "fp", "-438 07 17", "July 17 0439 BC", "-438 07 17",
1481 "MMMM dd yyyy GG", "fp", "-438 07 17", "July 17 0439 BC", "-438 07 17",
1482 "MMMM dd yyyy GGG", "fp", "-438 07 17", "July 17 0439 BC", "-438 07 17",
1483 "MMMM dd yyyy GGGG", "fp", "-438 07 17", "July 17 0439 Before Christ", "-438 07 17",
1484 };
1485
1486 expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1487}
1488
1489void DateFormatTest::TestQuarters()
1490{
1491 const char *EN_DATA[] = {
1492 "yyyy MM dd",
1493
1494 "Q", "fp", "1970 01 01", "1", "1970 01 01",
1495 "QQ", "fp", "1970 04 01", "02", "1970 04 01",
1496 "QQQ", "fp", "1970 07 01", "Q3", "1970 07 01",
1497 "QQQQ", "fp", "1970 10 01", "4th quarter", "1970 10 01",
1498
1499 "q", "fp", "1970 01 01", "1", "1970 01 01",
1500 "qq", "fp", "1970 04 01", "02", "1970 04 01",
1501 "qqq", "fp", "1970 07 01", "Q3", "1970 07 01",
1502 "qqqq", "fp", "1970 10 01", "4th quarter", "1970 10 01",
1503 };
1504
1505 expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1506}
1507
b75a7d8f
A
1508/**
1509 * Test parsing. Input is an array that starts with the following
1510 * header:
1511 *
1512 * [0] = pattern string to parse [i+2] with
1513 *
1514 * followed by test cases, each of which is 3 array elements:
1515 *
1516 * [i] = pattern, or NULL to reuse prior pattern
1517 * [i+1] = input string
1518 * [i+2] = expected parse result (parsed with pattern [0])
1519 *
1520 * If expect parse failure, then [i+2] should be NULL.
1521 */
1522void DateFormatTest::expectParse(const char** data, int32_t data_length,
1523 const Locale& loc) {
1524 const UDate FAIL = (UDate) -1;
1525 const UnicodeString FAIL_STR("parse failure");
1526 int32_t i = 0;
1527
1528 UErrorCode ec = U_ZERO_ERROR;
1529 SimpleDateFormat fmt("", loc, ec);
1530 SimpleDateFormat ref(data[i++], loc, ec);
1531 SimpleDateFormat gotfmt("G yyyy MM dd HH:mm:ss z", loc, ec);
1532 if (U_FAILURE(ec)) {
1533 errln("FAIL: SimpleDateFormat constructor");
1534 return;
1535 }
1536
1537 const char* currentPat = NULL;
1538 while (i<data_length) {
1539 const char* pattern = data[i++];
1540 const char* input = data[i++];
1541 const char* expected = data[i++];
1542
1543 ec = U_ZERO_ERROR;
1544 if (pattern != NULL) {
1545 fmt.applyPattern(pattern);
1546 currentPat = pattern;
1547 }
1548 UDate got = fmt.parse(input, ec);
1549 UnicodeString gotstr(FAIL_STR);
1550 if (U_FAILURE(ec)) {
1551 got = FAIL;
1552 } else {
1553 gotstr.remove();
1554 gotfmt.format(got, gotstr);
1555 }
1556
1557 UErrorCode ec2 = U_ZERO_ERROR;
1558 UDate exp = FAIL;
1559 UnicodeString expstr(FAIL_STR);
1560 if (expected != NULL) {
1561 expstr = expected;
1562 exp = ref.parse(expstr, ec2);
1563 if (U_FAILURE(ec2)) {
1564 // This only happens if expected is in wrong format --
1565 // should never happen once test is debugged.
1566 errln("FAIL: Internal test error");
1567 return;
1568 }
1569 }
1570
1571 if (got == exp) {
1572 logln((UnicodeString)"Ok: " + input + " x " +
1573 currentPat + " => " + gotstr);
1574 } else {
1575 errln((UnicodeString)"FAIL: " + input + " x " +
1576 currentPat + " => " + gotstr + ", expected " +
1577 expstr);
1578 }
1579 }
1580}
1581
374ca955
A
1582/**
1583 * Test formatting and parsing. Input is an array that starts
1584 * with the following header:
1585 *
1586 * [0] = pattern string to parse [i+2] with
1587 *
1588 * followed by test cases, each of which is 3 array elements:
1589 *
1590 * [i] = pattern, or null to reuse prior pattern
1591 * [i+1] = control string, either "fp", "pf", or "F".
1592 * [i+2..] = data strings
1593 *
1594 * The number of data strings depends on the control string.
1595 * Examples:
1596 * 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",
1597 * 'f': Format date [i+2] (as parsed using pattern [0]) and expect string [i+3].
1598 * 'p': Parse string [i+3] and expect date [i+4].
1599 *
1600 * 2. "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567"
1601 * 'F': Format date [i+2] and expect string [i+3],
1602 * then parse string [i+3] and expect date [i+2].
1603 *
1604 * 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",
1605 * 'p': Parse string [i+2] and expect date [i+3].
1606 * 'f': Format date [i+3] and expect string [i+4].
1607 */
1608void DateFormatTest::expect(const char** data, int32_t data_length,
1609 const Locale& loc) {
1610 int32_t i = 0;
1611 UErrorCode ec = U_ZERO_ERROR;
1612 UnicodeString str, str2;
1613 SimpleDateFormat fmt("", loc, ec);
1614 SimpleDateFormat ref(data[i++], loc, ec);
1615 SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
1616 if (!assertSuccess("construct SimpleDateFormat", ec)) return;
1617
1618 UnicodeString currentPat;
1619 while (i<data_length) {
1620 const char* pattern = data[i++];
1621 if (pattern != NULL) {
1622 fmt.applyPattern(pattern);
1623 currentPat = pattern;
1624 }
1625
1626 const char* control = data[i++];
1627
1628 if (uprv_strcmp(control, "fp") == 0) {
1629 // 'f'
1630 const char* datestr = data[i++];
1631 const char* string = data[i++];
73c04bcf 1632 UDate date = ref.parse(ctou(datestr), ec);
374ca955
A
1633 if (!assertSuccess("parse", ec)) return;
1634 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
73c04bcf 1635 ctou(string),
374ca955
A
1636 fmt.format(date, str.remove()));
1637 // 'p'
1638 datestr = data[i++];
73c04bcf 1639 date = ref.parse(ctou(datestr), ec);
374ca955 1640 if (!assertSuccess("parse", ec)) return;
73c04bcf 1641 UDate parsedate = fmt.parse(ctou(string), ec);
374ca955
A
1642 if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
1643 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
1644 univ.format(date, str.remove()),
1645 univ.format(parsedate, str2.remove()));
1646 }
1647 }
1648
1649 else if (uprv_strcmp(control, "pf") == 0) {
1650 // 'p'
1651 const char* string = data[i++];
1652 const char* datestr = data[i++];
73c04bcf 1653 UDate date = ref.parse(ctou(datestr), ec);
374ca955 1654 if (!assertSuccess("parse", ec)) return;
73c04bcf 1655 UDate parsedate = fmt.parse(ctou(string), ec);
374ca955
A
1656 if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
1657 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
1658 univ.format(date, str.remove()),
1659 univ.format(parsedate, str2.remove()));
1660 }
1661 // 'f'
1662 string = data[i++];
1663 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
73c04bcf 1664 ctou(string),
374ca955
A
1665 fmt.format(date, str.remove()));
1666 }
1667
1668 else if (uprv_strcmp(control, "F") == 0) {
1669 const char* datestr = data[i++];
1670 const char* string = data[i++];
73c04bcf 1671 UDate date = ref.parse(ctou(datestr), ec);
374ca955
A
1672 if (!assertSuccess("parse", ec)) return;
1673 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
73c04bcf 1674 ctou(string),
374ca955
A
1675 fmt.format(date, str.remove()));
1676
1677 UDate parsedate = fmt.parse(string, ec);
1678 if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
1679 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
1680 univ.format(date, str.remove()),
1681 univ.format(parsedate, str2.remove()));
1682 }
1683 }
1684
1685 else {
1686 errln((UnicodeString)"FAIL: Invalid control string " + control);
1687 return;
1688 }
1689 }
1690}
1691
73c04bcf
A
1692/**
1693 * Test formatting. Input is an array that starts
1694 * with the following header:
1695 *
1696 * [0] = pattern string to parse [i+2] with
1697 *
1698 * followed by test cases, each of which is 3 array elements:
1699 *
1700 * [i] = pattern, or null to reuse prior pattern
1701 * [i+1] = data string a
1702 * [i+2] = data string b
1703 *
1704 * Examples:
1705 * Format date [i+1] and expect string [i+2].
1706 *
1707 * "y/M/d H:mm:ss.SSSS", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567"
1708 */
1709void DateFormatTest::expectFormat(const char** data, int32_t data_length,
1710 const Locale& loc) {
1711 int32_t i = 0;
1712 UErrorCode ec = U_ZERO_ERROR;
1713 UnicodeString str, str2;
1714 SimpleDateFormat fmt("", loc, ec);
1715 SimpleDateFormat ref(data[i++], loc, ec);
1716 SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
1717 if (!assertSuccess("construct SimpleDateFormat", ec)) return;
1718
1719 UnicodeString currentPat;
1720
1721 while (i<data_length) {
1722 const char* pattern = data[i++];
1723 if (pattern != NULL) {
1724 fmt.applyPattern(pattern);
1725 currentPat = pattern;
1726 }
1727
1728 const char* datestr = data[i++];
1729 const char* string = data[i++];
1730 UDate date = ref.parse(ctou(datestr), ec);
1731 if (!assertSuccess("parse", ec)) return;
1732 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
1733 ctou(string),
1734 fmt.format(date, str.remove()));
1735 }
1736}
1737
1738void DateFormatTest::TestGenericTime() {
1739 // any zone pattern should parse any zone
1740 const Locale en("en");
1741 const char* ZDATA[] = {
1742 "yyyy MM dd HH:mm zzz",
1743 // round trip
1744 "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
1745 "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
1746 "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
1747 "y/M/d H:mm vvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
1748 // non-generic timezone string influences dst offset even if wrong for date/time
1749 "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PDT", "2004 01 01 01:00 PDT", "2004/1/1 0:00 PST",
1750 "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PDT", "2004 01 01 01:00 PDT", "2004/1/1 0:00 Pacific Time",
1751 "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PST", "2004 07 01 02:00 PDT", "2004/7/1 2:00 PDT",
1752 "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PST", "2004 07 01 02:00 PDT", "2004/7/1 2:00 Pacific Time",
1753 // generic timezone generates dst offset appropriate for local time
1754 "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
1755 "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
1756 "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
1757 "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 Pacific Time",
1758 // daylight savings time transition edge cases.
1759 // time to parse does not really exist, PT interpreted as earlier time
1760 "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PST", // adjust earlier
1761 "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PST", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PDT",
1762 "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PDT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PST",
1763 "y/M/d H:mm vvv", "pf", "2005/4/3 2:30 PT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PT", // adjust earlier
1764 "y/M/d H:mm vvv", "pf", "2005/4/3 2:30 PST", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PT",
1765 "y/M/d H:mm vvv", "pf", "2005/4/3 2:30 PDT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PT",
1766 "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 01:30 PST", "2005/4/3 1:30",
1767 // time to parse is ambiguous, PT interpreted as LATER time (?)
1768 "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PT", "2004 10 31 01:30 PST", "2004/10/31 1:30 PST", // 1:30a PT -> 1:30a PST (later)
1769 "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PST", "2004 10 31 01:30 PST", "2004/10/31 1:30 PST",
1770 "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PDT", "2004 10 31 01:30 PDT", "2004/10/31 1:30 PDT",
1771 "y/M/d H:mm vvv", "pf", "2004/10/31 1:30 PT", "2004 10 31 01:30 PST", "2004/10/31 1:30 PT", // 1:30a PT -> 1:30a PST (later)
1772 "y/M/d H:mm vvv", "pf", "2004/10/31 1:30 PST", "2004 10 31 01:30 PST", "2004/10/31 1:30 PT",
1773 "y/M/d H:mm vvv", "pf", "2004/10/31 1:30 PDT", "2004 10 31 01:30 PDT", "2004/10/31 1:30 PT",
1774 "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30", // 1:30a PT -> 1:30a PST (later)
1775 };
1776 const int32_t ZDATA_length = sizeof(ZDATA)/ sizeof(ZDATA[0]);
1777 expect(ZDATA, ZDATA_length, en);
1778
1779 UErrorCode status = U_ZERO_ERROR;
1780
1781 logln("cross format/parse tests");
1782 UnicodeString basepat("yy/MM/dd H:mm ");
1783 SimpleDateFormat formats[] = {
1784 SimpleDateFormat(basepat + "vvv", en, status),
1785 SimpleDateFormat(basepat + "vvvv", en, status),
1786 SimpleDateFormat(basepat + "zzz", en, status),
1787 SimpleDateFormat(basepat + "zzzz", en, status)
1788 };
1789 ASSERT_OK(status);
1790 const int32_t formats_length = sizeof(formats)/sizeof(formats[0]);
1791
1792 UnicodeString test;
1793 SimpleDateFormat univ("yyyy MM dd HH:mm zzz", en, status);
1794 ASSERT_OK(status);
1795 const UnicodeString times[] = {
1796 "2004 01 02 03:04 PST",
1797 "2004 07 08 09:10 PDT"
1798 };
1799 int32_t times_length = sizeof(times)/sizeof(times[0]);
1800 for (int i = 0; i < times_length; ++i) {
1801 UDate d = univ.parse(times[i], status);
1802 logln(UnicodeString("\ntime: ") + d);
1803 for (int j = 0; j < formats_length; ++j) {
1804 test.remove();
1805 formats[j].format(d, test);
1806 logln("\ntest: '" + test + "'");
1807 for (int k = 0; k < formats_length; ++k) {
1808 UDate t = formats[k].parse(test, status);
1809 if (U_SUCCESS(status)) {
1810 if (d != t) {
1811 errln((UnicodeString)"FAIL: format " + k +
1812 " incorrectly parsed output of format " + j +
1813 " (" + test + "), returned " +
1814 dateToString(t) + " instead of " + dateToString(d));
1815 } else {
1816 logln((UnicodeString)"OK: format " + k + " parsed ok");
1817 }
1818 } else if (status == U_PARSE_ERROR) {
1819 errln((UnicodeString)"FAIL: format " + k +
1820 " could not parse output of format " + j +
1821 " (" + test + ")");
1822 }
1823 }
1824 }
1825 }
1826}
1827
1828void DateFormatTest::TestGenericTimeZoneOrder() {
1829 // generic times should parse the same no matter what the placement of the time zone string
1830 // should work for standard and daylight times
1831
1832 const char* XDATA[] = {
1833 "yyyy MM dd HH:mm zzz",
1834 // standard time, explicit daylight/standard
1835 "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
1836 "y/M/d zzz H:mm", "pf", "2004/1/1 PT 1:00", "2004 01 01 01:00 PST", "2004/1/1 PST 1:00",
1837 "zzz y/M/d H:mm", "pf", "PT 2004/1/1 1:00", "2004 01 01 01:00 PST", "PST 2004/1/1 1:00",
1838
1839 // standard time, generic
1840 "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
1841 "y/M/d vvvv H:mm", "pf", "2004/1/1 PT 1:00", "2004 01 01 01:00 PST", "2004/1/1 Pacific Time 1:00",
1842 "vvvv y/M/d H:mm", "pf", "PT 2004/1/1 1:00", "2004 01 01 01:00 PST", "Pacific Time 2004/1/1 1:00",
1843
1844 // dahylight time, explicit daylight/standard
1845 "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
1846 "y/M/d zzz H:mm", "pf", "2004/7/1 PT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 PDT 1:00",
1847 "zzz y/M/d H:mm", "pf", "PT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "PDT 2004/7/1 1:00",
1848
1849 // daylight time, generic
1850 "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 Pacific Time",
1851 "y/M/d vvvv H:mm", "pf", "2004/7/1 PT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 Pacific Time 1:00",
1852 "vvvv y/M/d H:mm", "pf", "PT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "Pacific Time 2004/7/1 1:00",
1853 };
1854 const int32_t XDATA_length = sizeof(XDATA)/sizeof(XDATA[0]);
1855 Locale en("en");
1856 expect(XDATA, XDATA_length, en);
1857}
1858
1859void DateFormatTest::TestTimeZoneStringsAPI() {
1860 // Verify data
1861 UErrorCode status = U_ZERO_ERROR;
1862 DateFormatSymbols symbols(Locale::getUS(), status);
1863 StringEnumeration* keys = symbols.createZoneStringIDs(status);
1864 if(U_FAILURE(status)){
1865 errln("Could not create the StringEnumeration for Locale::getUS(). Error: %s", u_errorName(status));
1866 return;
1867 }
1868
1869 StringEnumeration* keys2 = symbols.createZoneStringIDs(status);
1870 ASSERT_OK(status);
1871 if(*keys2!=*keys){
1872 errln("operator!= failed for TimeZoneStringsEnum");
1873 }
1874 const UnicodeString* key = NULL;
1875
1876 while( (key = keys->snext(status))!=NULL){
1877 logln(prettify(*key));
1878 }
1879 if(U_FAILURE(status)){
1880 errln("Could not iterate over the StringEnumeration. Error: %s", u_errorName(status));
1881 return;
1882 }
1883 UnicodeString expectedKey("America/Los_Angeles");
1884 UnicodeString expectedStrs[DateFormatSymbols::TIMEZONE_COUNT];
1885 expectedStrs[DateFormatSymbols::TIMEZONE_SHORT_GENERIC].setTo("PT");
1886 expectedStrs[DateFormatSymbols::TIMEZONE_SHORT_STANDARD].setTo("PST");
1887 expectedStrs[DateFormatSymbols::TIMEZONE_SHORT_DAYLIGHT].setTo("PDT");
1888 expectedStrs[DateFormatSymbols::TIMEZONE_LONG_GENERIC].setTo("Pacific Time");
1889 expectedStrs[DateFormatSymbols::TIMEZONE_LONG_STANDARD].setTo("Pacific Standard Time");
1890 expectedStrs[DateFormatSymbols::TIMEZONE_LONG_DAYLIGHT].setTo("Pacific Daylight Time");
1891 expectedStrs[DateFormatSymbols::TIMEZONE_EXEMPLAR_CITY].setTo("Los Angeles");
1892 for(int32_t i=0; i<DateFormatSymbols::TIMEZONE_COUNT; i++){
1893 UnicodeString result;
1894 result = symbols.getZoneString(expectedKey, (DateFormatSymbols::TimeZoneTranslationType)i, result,status);
1895 if(U_FAILURE(status)){
1896 errln("Could not retrieve display name. Error: %s", u_errorName(status));
1897 return;
1898 }
1899 if(expectedStrs[i] != result){
1900 errln("Did not get the expected string. Expected: "+expectedStrs[i]+ UnicodeString(" Got: ") + result );
1901 }
1902 }
1903 expectedKey.setTo("America/Los_Angeles",0);
1904 UnicodeString exemplarCity("Phoenix");
1905 UnicodeString result;
1906 symbols.setZoneString(expectedKey,DateFormatSymbols::TIMEZONE_EXEMPLAR_CITY, exemplarCity, status);
1907 if(U_FAILURE(status)){
1908 errln("setZoneString() did not succeed. Error: %s", u_errorName(status));
1909 return;
1910 }
1911 result = symbols.getZoneString(expectedKey, DateFormatSymbols::TIMEZONE_EXEMPLAR_CITY, result,status);
1912 if(result != exemplarCity){
1913 errln("setZoneString() did not succeed. Expected: " + exemplarCity + " Got: " + result);
1914 }
1915 delete keys;
1916 delete keys2;
1917}
1918
1919void DateFormatTest::TestHost(void)
1920{
1921#ifdef U_WINDOWS
1922 Win32DateTimeTest::testLocales(this);
1923#endif
1924}
1925
b75a7d8f
A
1926#endif /* #if !UCONFIG_NO_FORMATTING */
1927
1928//eof