1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2011, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ********************************************************************/
6
7 #include "unicode/utypes.h"
8
9 #if !UCONFIG_NO_FORMATTING
10
11 #include "calregts.h"
12
13 #include "unicode/gregocal.h"
14 #include "unicode/simpletz.h"
15 #include "unicode/smpdtfmt.h"
16 #include "unicode/strenum.h"
17 #include "cmemory.h"
18 #include "caltest.h"
19
20 #include <float.h>
21
22 // *****************************************************************************
23 // class CalendarRegressionTest
24 // *****************************************************************************
25
26 // these numbers correspond to using LONG_MIN and LONG_MAX in Java
27 // this is 2^52 - 1, the largest allowable mantissa with a 0 exponent in a 64-bit double
28 const UDate CalendarRegressionTest::EARLIEST_SUPPORTED_MILLIS = - 4503599627370495.0;
29 const UDate CalendarRegressionTest::LATEST_SUPPORTED_MILLIS = 4503599627370495.0;
30
31 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
32
33 void
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)34 CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
35 {
36 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
37 switch (index) {
38 CASE(0,test4100311);
39 CASE(1,test4074758);
40 CASE(2,test4028518);
41 CASE(3,test4031502);
42 CASE(4,test4035301);
43 CASE(5,test4040996);
44 CASE(6,test4051765);
45 CASE(7,test4061476);
46 CASE(8,test4070502);
47 CASE(9,test4071197);
48 CASE(10,test4071385);
49 CASE(11,test4073929);
50 CASE(12,test4083167);
51 CASE(13,test4086724);
52 CASE(14,test4095407);
53 CASE(15,test4096231);
54 CASE(16,test4096539);
55 CASE(17,test41003112);
56 CASE(18,test4103271);
57 CASE(19,test4106136);
58 CASE(20,test4108764);
59 CASE(21,test4114578);
60 CASE(22,test4118384);
61 CASE(23,test4125881);
62 CASE(24,test4125892);
63 CASE(25,test4141665);
64 CASE(26,test4142933);
65 CASE(27,test4145158);
66 CASE(28,test4145983);
67 CASE(29,test4147269);
68
69 CASE(30,Test4149677);
70 CASE(31,Test4162587);
71 CASE(32,Test4165343);
72 CASE(33,Test4166109);
73 CASE(34,Test4167060);
74 CASE(35,Test4197699);
75 CASE(36,TestJ81);
76 CASE(37,TestJ438);
77 CASE(38,TestLeapFieldDifference);
78 CASE(39,TestMalaysianInstance);
79 CASE(40,test4059654);
80 CASE(41,test4092362);
81 CASE(42,TestWeekShift);
82 CASE(43,TestTimeZoneTransitionAdd);
83 CASE(44,TestDeprecates);
84 CASE(45,TestT5555);
85 CASE(46,TestT6745);
86 CASE(47,TestT8057);
87 default: name = ""; break;
88 }
89 }
90
91 const char* CalendarRegressionTest::FIELD_NAME [] = {
92 "ERA",
93 "YEAR",
94 "MONTH",
95 "WEEK_OF_YEAR",
96 "WEEK_OF_MONTH",
97 "DAY_OF_MONTH",
98 "DAY_OF_YEAR",
99 "DAY_OF_WEEK",
100 "DAY_OF_WEEK_IN_MONTH",
101 "AM_PM",
102 "HOUR",
103 "HOUR_OF_DAY",
104 "MINUTE",
105 "SECOND",
106 "MILLISECOND",
107 "ZONE_OFFSET",
108 "DST_OFFSET",
109 "YEAR_WOY",
110 "DOW_LOCAL"
111 };
112
113 UBool
failure(UErrorCode status,const char * msg)114 CalendarRegressionTest::failure(UErrorCode status, const char* msg)
115 {
116 if(U_FAILURE(status)) {
117 errcheckln(status, UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status));
118 return TRUE;
119 }
120
121 return FALSE;
122 }
123
124 /*
125 * bug 4100311
126 */
127 void
test4100311()128 CalendarRegressionTest::test4100311()
129 {
130 UErrorCode status = U_ZERO_ERROR;
131 GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status);
132 if(U_FAILURE(status)) {
133 dataerrln("Error creating Calendar: %s", u_errorName(status));
134 delete cal;
135 return;
136 }
137 failure(status, "Calendar::createInstance(status)");
138 cal->set(UCAL_YEAR, 1997);
139 cal->set(UCAL_DAY_OF_YEAR, 1);
140 UDate d = cal->getTime(status); // Should be Jan 1
141 failure(status, "cal->getTime");
142 logln(UnicodeString("") + d);
143 delete cal;
144 }
145
146
147 /**
148 * @bug 4074758
149 */
150 void
test4074758()151 CalendarRegressionTest::test4074758()
152 { //Set system time to between 12-1 (am or pm) and then run
153 UErrorCode status = U_ZERO_ERROR;
154 GregorianCalendar *cal = new GregorianCalendar(status);
155 if(U_FAILURE(status)) {
156 dataerrln("Error creating Calendar: %s", u_errorName(status));
157 delete cal;
158 return;
159 }
160 failure(status, "new GregorianCalendar");
161 for (int32_t h=0; h<25; ++h) {
162 cal->set(97, UCAL_JANUARY, 1, h, 34);
163 //System.out.print(d);
164 logln(UnicodeString("HOUR=") + cal->get(UCAL_HOUR, status)); //prints 0
165 failure(status, "cal->get");
166 logln(UnicodeString("HOUR_OF_DAY=") + cal->get(UCAL_HOUR_OF_DAY, status));
167 failure(status, "cal->get");
168 }
169
170 delete cal;
171 }
172
173 void
test4028518()174 CalendarRegressionTest::test4028518()
175 {
176 UErrorCode status = U_ZERO_ERROR;
177 GregorianCalendar *cal1 = new GregorianCalendar(status) ;
178 if(U_FAILURE(status)) {
179 dataerrln("Error creating Calendar: %s", u_errorName(status));
180 delete cal1;
181 return;
182 }
183 failure(status, "new GregorianCalendar");
184 GregorianCalendar *cal2 = (GregorianCalendar*) cal1->clone() ;
185
186 printdate(cal1, "cal1: ") ;
187 printdate(cal2, "cal2 - cloned(): ") ;
188 cal1->add(UCAL_DATE, 1, status) ;
189 failure(status, "cal1->add");
190 printdate(cal1, "cal1 after adding 1 day:") ;
191 printdate(cal2, "cal2 should be unmodified:") ;
192 delete cal1;
193 delete cal2;
194 }
195
196 void
printdate(GregorianCalendar * cal,const char * string)197 CalendarRegressionTest::printdate(GregorianCalendar *cal, const char *string)
198 {
199 UErrorCode status = U_ZERO_ERROR;
200 logln(UnicodeString(string, ""));
201 log(UnicodeString("") + cal->get(UCAL_MONTH, status)) ;
202 failure(status, "cal->get");
203 int32_t date = cal->get(UCAL_DATE, status) + 1 ;
204 failure(status, "cal->get");
205 log(UnicodeString("/") + date) ;
206 logln(UnicodeString("/") + cal->get(UCAL_YEAR, status)) ;
207 failure(status, "cal->get");
208 }
209
210 /**
211 * @bug 4031502
212 */
213 void
test4031502()214 CalendarRegressionTest::test4031502()
215 {
216 // This bug actually occurs on Windows NT as well, and doesn't
217 // require the host zone to be set; it can be set in Java.
218 UErrorCode status = U_ZERO_ERROR;
219 StringEnumeration* ids = TimeZone::createEnumeration();
220 if (ids == NULL) {
221 dataerrln("Unable to create TimeZone Enumeration.");
222 return;
223 }
224 UBool bad = FALSE;
225 TimeZone* tz =TimeZone::createTimeZone("Asia/Riyadh87");
226 failure(status, "new TimeZone");
227 GregorianCalendar *cl = new GregorianCalendar(tz, status);
228 if (U_FAILURE(status)) {
229 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
230 delete tz;
231 return;
232 }
233 cl->clear();
234 cl->set(1900, 15, 5, 5, 8, 13);
235 cl->get(UCAL_HOUR, status);
236 failure(status, "cl->get(UCAL_HOUR, status)");
237 status = U_ZERO_ERROR;
238 delete cl;
239 for (int32_t i=0; i<ids->count(status); ++i) {
240 TimeZone *zone = TimeZone::createTimeZone(*ids->snext(status));
241 GregorianCalendar *cal = new GregorianCalendar(zone, status);
242 failure(status, "new GregorianCalendar");
243 cal->clear();
244 cal->set(1900, 15, 5, 5, 8, 13);
245 if (cal->get(UCAL_HOUR, status) != 5 || U_FAILURE(status)) {
246 UnicodeString temp;
247 logln(zone->getID(temp) + " " +
248 //zone.useDaylightTime() + " " +
249 cal->get(UCAL_DST_OFFSET,status) / (60*60*1000) + " " +
250 zone->getRawOffset() / (60*60*1000) +
251 ": HOUR = " + cal->get(UCAL_HOUR,status));
252 bad = TRUE;
253 }
254 delete cal;
255 }
256 if (bad)
257 errln("TimeZone problems with GC");
258 // delete [] ids; // TODO: bad APIs
259 delete ids;
260 }
261
262 /**
263 * @bug 4035301
264 */
test4035301()265 void CalendarRegressionTest::test4035301()
266 {
267 UErrorCode status = U_ZERO_ERROR;
268 GregorianCalendar *c = new GregorianCalendar(98, 8, 7,status);
269 GregorianCalendar *d = new GregorianCalendar(98, 8, 7,status);
270 if (c->after(*d,status) ||
271 c->after(*c,status) ||
272 c->before(*d,status) ||
273 c->before(*c,status) ||
274 *c != *c ||
275 *c != *d)
276 dataerrln("Fail");
277 delete c;
278 delete d;
279 }
280
281 /**
282 * @bug 4040996
283 */
test4040996()284 void CalendarRegressionTest::test4040996()
285 {
286 int32_t count = 0;
287 StringEnumeration* ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000);
288 if (ids == NULL) {
289 dataerrln("Unable to create TimeZone enumeration.");
290 return;
291 }
292 UErrorCode status = U_ZERO_ERROR;
293 count = ids->count(status);
294 SimpleTimeZone *pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids->snext(status));
295 pdt->setStartRule(UCAL_APRIL, 1, UCAL_SUNDAY, 2 * 60 * 60 * 1000, status);
296 pdt->setEndRule(UCAL_OCTOBER, -1, UCAL_SUNDAY, 2 * 60 * 60 * 1000, status);
297 Calendar *calendar = new GregorianCalendar(pdt, status);
298 if (U_FAILURE(status)) {
299 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
300 return;
301 }
302 calendar->set(UCAL_MONTH,3);
303 calendar->set(UCAL_DATE,18);
304 calendar->set(UCAL_SECOND, 30);
305
306 logln(UnicodeString("MONTH: ") + calendar->get(UCAL_MONTH, status));
307 logln(UnicodeString("DAY_OF_MONTH: ") +
308 calendar->get(UCAL_DATE, status));
309 logln(UnicodeString("MINUTE: ") + calendar->get(UCAL_MINUTE, status));
310 logln(UnicodeString("SECOND: ") + calendar->get(UCAL_SECOND, status));
311
312 calendar->add(UCAL_SECOND,6, status);
313 //This will print out todays date for MONTH and DAY_OF_MONTH
314 //instead of the date it was set to.
315 //This happens when adding MILLISECOND or MINUTE also
316 logln(UnicodeString("MONTH: ") + calendar->get(UCAL_MONTH, status));
317 logln(UnicodeString("DAY_OF_MONTH: ") +
318 calendar->get(UCAL_DATE, status));
319 logln(UnicodeString("MINUTE: ") + calendar->get(UCAL_MINUTE, status));
320 logln(UnicodeString("SECOND: ") + calendar->get(UCAL_SECOND, status));
321 if (calendar->get(UCAL_MONTH, status) != 3 ||
322 calendar->get(UCAL_DATE, status) != 18 ||
323 calendar->get(UCAL_SECOND, status) != 36)
324 errln(UnicodeString("Fail: Calendar::add misbehaves"));
325
326 delete calendar;
327 delete ids;
328 // delete ids; // TODO: BAD API
329 }
330
331 /**
332 * @bug 4051765
333 */
test4051765()334 void CalendarRegressionTest::test4051765()
335 {
336 UErrorCode status = U_ZERO_ERROR;
337 Calendar *cal = Calendar::createInstance(status);
338 if(U_FAILURE(status)) {
339 dataerrln("Error creating Calendar: %s", u_errorName(status));
340 delete cal;
341 return;
342 }
343 cal->setLenient(FALSE);
344 cal->set(UCAL_DAY_OF_WEEK, 0);
345 //try {
346 cal->getTime(status);
347 if( ! U_FAILURE(status))
348 errln("Fail: DAY_OF_WEEK 0 should be disallowed");
349 /*}
350 catch (IllegalArgumentException e) {
351 return;
352 }*/
353
354 delete cal;
355 }
356
357 /* User error - no bug here
358 void CalendarRegressionTest::test4059524() {
359 // Create calendar for April 10, 1997
360 GregorianCalendar calendar = new GregorianCalendar(status);
361 // print out a bunch of interesting things
362 logln("ERA: " + Calendar::get(Calendar::ERA));
363 logln("YEAR: " + Calendar::get(Calendar::YEAR));
364 logln("MONTH: " + Calendar::get(Calendar::MONTH));
365 logln("WEEK_OF_YEAR: " +
366 Calendar::get(Calendar::WEEK_OF_YEAR));
367 logln("WEEK_OF_MONTH: " +
368 Calendar::get(Calendar::WEEK_OF_MONTH));
369 logln("DATE: " + Calendar::get(Calendar::DATE));
370 logln("DAY_OF_MONTH: " +
371 Calendar::get(Calendar::DAY_OF_MONTH));
372 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
373 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
374 logln("DAY_OF_WEEK_IN_MONTH: " +
375 Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
376 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
377 logln("HOUR: " + Calendar::get(Calendar::HOUR));
378 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
379 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
380 logln("SECOND: " + Calendar::get(Calendar::SECOND));
381 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
382 logln("ZONE_OFFSET: "
383 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000)));
384 logln("DST_OFFSET: "
385 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000)));
386 calendar = new GregorianCalendar(1997,3,10);
387 Calendar::getTime();
388 logln("April 10, 1997");
389 logln("ERA: " + Calendar::get(Calendar::ERA));
390 logln("YEAR: " + Calendar::get(Calendar::YEAR));
391 logln("MONTH: " + Calendar::get(Calendar::MONTH));
392 logln("WEEK_OF_YEAR: " +
393 Calendar::get(Calendar::WEEK_OF_YEAR));
394 logln("WEEK_OF_MONTH: " +
395 Calendar::get(Calendar::WEEK_OF_MONTH));
396 logln("DATE: " + Calendar::get(Calendar::DATE));
397 logln("DAY_OF_MONTH: " +
398 Calendar::get(Calendar::DAY_OF_MONTH));
399 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
400 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
401 logln("DAY_OF_WEEK_IN_MONTH: " + Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
402 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
403 logln("HOUR: " + Calendar::get(Calendar::HOUR));
404 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
405 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
406 logln("SECOND: " + Calendar::get(Calendar::SECOND));
407 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
408 logln("ZONE_OFFSET: "
409 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); // in hours
410 logln("DST_OFFSET: "
411 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours
412 }
413 */
414
415 /**
416 * @bug 4059654
417 */
test4059654()418 void CalendarRegressionTest::test4059654() {
419 UErrorCode status = U_ZERO_ERROR;
420 GregorianCalendar *gc = new GregorianCalendar(status);
421 if(U_FAILURE(status)) {
422 dataerrln("Error creating Calendar: %s", u_errorName(status));
423 delete gc;
424 return;
425 }
426
427 gc->set(1997, 3, 1, 15, 16, 17); // April 1, 1997
428
429 gc->set(UCAL_HOUR, 0);
430 gc->set(UCAL_AM_PM, UCAL_AM);
431 gc->set(UCAL_MINUTE, 0);
432 gc->set(UCAL_SECOND, 0);
433 gc->set(UCAL_MILLISECOND, 0);
434
435 UDate cd = gc->getTime(status);
436 GregorianCalendar *exp = new GregorianCalendar(1997, 3, 1, 0, 0, 0, status);
437 if (cd != exp->getTime(status))
438 errln(UnicodeString("Fail: Calendar::set broken. Got ") + cd + " Want " + exp->getTime(status));
439
440 delete gc;
441 delete exp;
442 }
443
444 /**
445 * @bug 4061476
446 */
test4061476()447 void CalendarRegressionTest::test4061476()
448 {
449 UErrorCode status = U_ZERO_ERROR;
450 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("ddMMMyy"), Locale::getUK(),status);
451 Calendar *cal = Calendar::createInstance(TimeZone::createTimeZone("GMT"),
452 Locale::getUK(),status);
453 if(U_FAILURE(status)) {
454 dataerrln("Error creating Calendar: %s", u_errorName(status));
455 delete cal;
456 delete fmt;
457 return;
458 }
459 fmt->adoptCalendar(cal);
460 // try {
461 UDate date = fmt->parse("29MAY97", status);
462 failure(status, "fmt->parse");
463 cal->setTime(date, status);
464 failure(status, "cal->setTime");
465 // }
466 //catch (Exception e) {;}
467 cal->set(UCAL_HOUR_OF_DAY, 13);
468 logln(UnicodeString("Hour: ")+cal->get(UCAL_HOUR_OF_DAY, status));
469 cal->add(UCAL_HOUR_OF_DAY, 6,status);
470 logln(UnicodeString("Hour: ")+cal->get(UCAL_HOUR_OF_DAY, status));
471 if (cal->get(UCAL_HOUR_OF_DAY, status) != 19)
472 errln(UnicodeString("Fail: Want 19 Got ") + cal->get(UCAL_HOUR_OF_DAY, status));
473
474 delete fmt;
475 }
476
477 /**
478 * @bug 4070502
479 */
test4070502()480 void CalendarRegressionTest::test4070502()
481 {
482 UErrorCode status = U_ZERO_ERROR;
483 Calendar *cal = new GregorianCalendar(status);
484 if(status == U_USING_FALLBACK_WARNING || U_FAILURE(status)) {
485 dataerrln("Error creating Calendar: %s", u_errorName(status));
486 delete cal;
487 return;
488 }
489 UDate d = getAssociatedDate(makeDate(1998,0,30), status);
490 cal->setTime(d,status);
491 if (cal->get(UCAL_DAY_OF_WEEK,status) == UCAL_SATURDAY ||
492 cal->get(UCAL_DAY_OF_WEEK,status) == UCAL_SUNDAY)
493 errln(UnicodeString("Fail: Want weekday Got ") + d);
494
495 delete cal;
496 }
497
498 /**
499 * Get the associated date starting from a specified date
500 * NOTE: the unnecessary "getTime()'s" below are a work-around for a
501 * bug in jdk 1.1.3 (and probably earlier versions also)
502 * <p>
503 * @param date The date to start from
504 */
505 UDate
getAssociatedDate(UDate d,UErrorCode & status)506 CalendarRegressionTest::getAssociatedDate(UDate d, UErrorCode& status)
507 {
508 GregorianCalendar *cal = new GregorianCalendar(status);
509 cal->setTime(d,status);
510 //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
511 // cal.getTime(); // <--- REMOVE THIS TO SEE BUG
512 for (;;) {
513 int32_t wd = cal->get(UCAL_DAY_OF_WEEK, status);
514 if (wd == UCAL_SATURDAY || wd == UCAL_SUNDAY) {
515 cal->add(UCAL_DATE, 1, status);
516 // cal.getTime();
517 }
518 else
519 break;
520 }
521
522 UDate dd = cal->getTime(status);
523 delete cal;
524 return dd;
525 }
526
527 /**
528 * @bug 4071197
529 */
test4071197()530 void CalendarRegressionTest::test4071197()
531 {
532 dowTest(FALSE);
533 dowTest(TRUE);
534 }
535
dowTest(UBool lenient)536 void CalendarRegressionTest::dowTest(UBool lenient)
537 {
538 UErrorCode status = U_ZERO_ERROR;
539 GregorianCalendar *cal = new GregorianCalendar(status);
540 if(U_FAILURE(status)) {
541 dataerrln("Error creating Calendar: %s", u_errorName(status));
542 delete cal;
543 return;
544 }
545 cal->set(1997, UCAL_AUGUST, 12); // Wednesday
546 // cal.getTime(); // Force update
547 cal->setLenient(lenient);
548 cal->set(1996, UCAL_DECEMBER, 1); // Set the date to be December 1, 1996
549 int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status);
550 int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK);
551 int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK);
552 //logln(cal.getTime().toString());
553 if (min != UCAL_SUNDAY || max != UCAL_SATURDAY)
554 errln("FAIL: Min/max bad");
555 if (dow < min || dow > max)
556 errln("FAIL: Day of week %d out of range [%d,%d]\n", dow, min, max);
557 if (dow != UCAL_SUNDAY)
558 errln("FAIL: Day of week should be SUNDAY Got " + dow);
559
560 if(U_FAILURE(status)) {
561 errln("Error checking Calendar: %s", u_errorName(status));
562 delete cal;
563 return;
564 }
565
566 if(cal->getActualMinimum(UCAL_DAY_OF_WEEK, status) != min) {
567 errln("FAIL: actual minimum differs from minimum");
568 }
569 if(cal->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) {
570 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
571 }
572 if(cal->getActualMinimum(Calendar::DAY_OF_WEEK) != min) {
573 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK) differs from minimum");
574 }
575 if(((Calendar*)cal)->getActualMinimum(UCAL_DAY_OF_WEEK, status) != min) {
576 errln("FAIL: actual minimum (UCAL_DAY_OF_WEEK, status) differs from minimum");
577 }
578 // NOTE: This function does not exist! jitterbug #3016
579 // if(((Calendar*)cal)->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) {
580 // errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
581 // }
582 if(U_FAILURE(status)) {
583 errln("Error getting actual minimum: %s", u_errorName(status));
584 return;
585 }
586
587 delete cal;
588 }
589
590 /**
591 * @bug 4071385
592 */
test4071385()593 void CalendarRegressionTest::test4071385()
594 {
595 UErrorCode status = U_ZERO_ERROR;
596 Calendar *cal = Calendar::createInstance(status);
597 if(U_FAILURE(status)) {
598 dataerrln("Error creating Calendar: %s", u_errorName(status));
599 delete cal;
600 return;
601 }
602 cal->setTime(makeDate(1998, UCAL_JUNE, 24),status);
603 cal->set(UCAL_MONTH, UCAL_NOVEMBER); // change a field
604 //logln(cal.getTime().toString());
605 if (cal->getTime(status) != makeDate(1998, UCAL_NOVEMBER, 24))
606 errln("Fail");
607
608 delete cal;
609 }
610
611 /**
612 * @bug 4073929
613 */
test4073929()614 void CalendarRegressionTest::test4073929()
615 {
616 UErrorCode status = U_ZERO_ERROR;
617 GregorianCalendar *foo1 = new GregorianCalendar(1997, 8, 27,status);
618 if(U_FAILURE(status)) {
619 dataerrln("Error creating Calendar: %s", u_errorName(status));
620 delete foo1;
621 return;
622 }
623 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds\n", foo1->getTime(status),
624 foo1->get(UCAL_YEAR, status),
625 foo1->get(UCAL_MONTH, status),
626 foo1->get(UCAL_DATE, status),
627 foo1->get(UCAL_HOUR, status),
628 foo1->get(UCAL_MINUTE, status),
629 foo1->get(UCAL_SECOND, status),
630 foo1->get(UCAL_MILLISECOND,status));
631 foo1->add(UCAL_DATE, + 1, status);
632 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after +\n", foo1->getTime(status),
633 foo1->get(UCAL_YEAR, status),
634 foo1->get(UCAL_MONTH, status),
635 foo1->get(UCAL_DATE, status),
636 foo1->get(UCAL_HOUR, status),
637 foo1->get(UCAL_MINUTE, status),
638 foo1->get(UCAL_SECOND, status),
639 foo1->get(UCAL_MILLISECOND ,status));
640 foo1->add(UCAL_DATE, - 1, status);
641 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after -\n", foo1->getTime(status),
642 foo1->get(UCAL_YEAR, status),
643 foo1->get(UCAL_MONTH, status),
644 foo1->get(UCAL_DATE, status),
645 foo1->get(UCAL_HOUR, status),
646 foo1->get(UCAL_MINUTE, status),
647 foo1->get(UCAL_SECOND, status),
648 foo1->get(UCAL_MILLISECOND, status));
649
650 foo1->add(UCAL_DATE, + 1, status);
651 int32_t testyear = foo1->get(UCAL_YEAR, status);
652 int32_t testmonth = foo1->get(UCAL_MONTH, status);
653 int32_t testday = foo1->get(UCAL_DATE, status);
654 if (testyear != 1997 ||
655 testmonth != 8 ||
656 testday != 28)
657 errln("Fail: Calendar not initialized");
658
659 delete foo1;
660 }
661
662 /**
663 * @bug 4083167
664 */
test4083167()665 void CalendarRegressionTest::test4083167()
666 {
667 UErrorCode status = U_ZERO_ERROR;
668 TimeZone *saveZone = TimeZone::createDefault();
669 //try {
670 TimeZone *newZone = TimeZone::createTimeZone("UTC");
671 TimeZone::setDefault(*newZone);
672 UDate firstDate = Calendar::getNow();
673 Calendar *cal = new GregorianCalendar(status);
674 if(U_FAILURE(status)) {
675 dataerrln("Error creating Calendar: %s", u_errorName(status));
676 delete cal;
677 return;
678 }
679 cal->setTime(firstDate,status);
680 int32_t hr = cal->get(UCAL_HOUR_OF_DAY, status);
681 int32_t min = cal->get(UCAL_MINUTE, status);
682 int32_t sec = cal->get(UCAL_SECOND, status);
683 int32_t msec = cal->get(UCAL_MILLISECOND, status);
684 double firstMillisInDay = hr * 3600000 + min * 60000 + sec * 1000 + msec;
685
686 //logln("Current time: " + firstDate.toString());
687
688 for (int32_t validity=0; validity<30; validity++) {
689 UDate lastDate = firstDate + validity*1000*24*60*60.0;
690 cal->setTime(lastDate, status);
691 hr = cal->get(UCAL_HOUR_OF_DAY, status);
692 min = cal->get(UCAL_MINUTE, status);
693 sec = cal->get(UCAL_SECOND, status);
694 msec = cal->get(UCAL_MILLISECOND, status);
695 double millisInDay = hr * 3600000.0 + min * 60000.0 + sec * 1000.0 + msec;
696 if (firstMillisInDay != millisInDay)
697 errln(UnicodeString("Day has shifted ") + lastDate);
698 }
699 //}
700 //finally {
701 TimeZone::setDefault(*saveZone);
702 //}
703
704 delete saveZone;
705 delete newZone;
706 delete cal;
707 }
708
709 /**
710 * @bug 4086724
711 */
test4086724()712 void CalendarRegressionTest::test4086724()
713 {
714 UErrorCode status = U_ZERO_ERROR;
715 SimpleDateFormat *date;
716 TimeZone *saveZone = TimeZone::createDefault();
717 Locale saveLocale = Locale::getDefault();
718 //try {
719 Locale::setDefault(Locale::getUK(),status);
720 TimeZone *newZone = TimeZone::createTimeZone("GMT");
721 TimeZone::setDefault(*newZone);
722 date = new SimpleDateFormat(UnicodeString("dd MMM yyy (zzzz) 'is in week' ww"),status);
723 Calendar *cal = Calendar::createInstance(status);
724 if(U_FAILURE(status)) {
725 dataerrln("Error creating Calendar: %s", u_errorName(status));
726 delete cal;
727 delete newZone;
728 delete date;
729 return;
730 }
731 cal->set(1997,UCAL_SEPTEMBER,30);
732 UDate now = cal->getTime(status);
733 UnicodeString temp;
734 FieldPosition pos(FieldPosition::DONT_CARE);
735 logln(date->format(now, temp, pos));
736 cal->set(1997,UCAL_JANUARY,1);
737 now=cal->getTime(status);
738 logln(date->format(now,temp, pos));
739 cal->set(1997,UCAL_JANUARY,8);
740 now=cal->getTime(status);
741 logln(date->format(now,temp, pos));
742 cal->set(1996,UCAL_DECEMBER,31);
743 now=cal->getTime(status);
744 logln(date->format(now,temp, pos));
745 //}
746 //finally {
747 Locale::setDefault(saveLocale,status);
748 TimeZone::setDefault(*saveZone);
749 //}
750 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
751
752 delete newZone;
753 delete cal;
754 delete date;
755 delete saveZone;
756 }
757
758 /**
759 * @bug 4092362
760 */
test4092362()761 void CalendarRegressionTest::test4092362() {
762 UErrorCode status = U_ZERO_ERROR;
763 GregorianCalendar *cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40,status);
764 if (U_FAILURE(status)) {
765 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
766 delete cal1;
767 return;
768 }
769 /*cal1.set( Calendar::YEAR, 1997 );
770 cal1.set( Calendar::MONTH, 10 );
771 cal1.set( Calendar::DATE, 11 );
772 cal1.set( Calendar::HOUR, 10 );
773 cal1.set( Calendar::MINUTE, 20 );
774 cal1.set( Calendar::SECOND, 40 ); */
775
776 logln( UnicodeString(" Cal1 = ") + cal1->getTime(status) );
777 logln( UnicodeString(" Cal1 time in ms = ") + cal1->get(UCAL_MILLISECOND,status) );
778 for (int32_t k = 0; k < 100 ; k++)
779 ;
780
781 GregorianCalendar *cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40,status);
782 /*cal2.set( Calendar::YEAR, 1997 );
783 cal2.set( Calendar::MONTH, 10 );
784 cal2.set( Calendar::DATE, 11 );
785 cal2.set( Calendar::HOUR, 10 );
786 cal2.set( Calendar::MINUTE, 20 );
787 cal2.set( Calendar::SECOND, 40 ); */
788
789 logln( UnicodeString(" Cal2 = ") + cal2->getTime(status) );
790 logln( UnicodeString(" Cal2 time in ms = ") + cal2->get(UCAL_MILLISECOND,status) );
791 if( *cal1 != *cal2 )
792 errln("Fail: Milliseconds randomized");
793
794 delete cal1;
795 delete cal2;
796 }
797
798 /**
799 * @bug 4095407
800 */
test4095407()801 void CalendarRegressionTest::test4095407()
802 {
803 UErrorCode status = U_ZERO_ERROR;
804 GregorianCalendar *a = new GregorianCalendar(1997,UCAL_NOVEMBER, 13,status);
805 if (U_FAILURE(status)) {
806 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
807 delete a;
808 return;
809 }
810 int32_t dow = a->get(UCAL_DAY_OF_WEEK, status);
811 if (dow != UCAL_THURSDAY)
812 errln("Fail: Want THURSDAY Got " + dow);
813
814 delete a;
815 }
816
817 /**
818 * @bug 4096231
819 */
test4096231()820 void CalendarRegressionTest::test4096231()
821 {
822 UErrorCode status = U_ZERO_ERROR;
823 TimeZone *GMT = TimeZone::createTimeZone("GMT");
824 TimeZone *PST = TimeZone::createTimeZone("PST");
825 int32_t sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997;
826
827 Calendar *cal1 = new GregorianCalendar(*PST,status);
828 if (U_FAILURE(status)) {
829 dataerrln("Failure new GregorianCalendar: %s", u_errorName(status));
830 delete GMT;
831 delete PST;
832 delete cal1;
833 return;
834 }
835 cal1->setTime(880698639000.0,status);
836 // Issue 1: Changing the timezone doesn't change the
837 // represented time. The old API, pre 1.2.2a requires
838 // setTime to be called in order to update the time fields after the time
839 // zone has been set.
840 int32_t h1,h2;
841 logln(UnicodeString("PST 1 is: ") + (h1=cal1->get(UCAL_HOUR_OF_DAY, status)));
842 cal1->setTimeZone(*GMT);
843 logln(UnicodeString("GMT 2 is: ") + (h2=cal1->get(UCAL_HOUR_OF_DAY, status)));
844 if ((*GMT != *PST) && (h1 == h2))
845 errln("Fail: Hour same in different zones");
846
847 Calendar *cal2 = new GregorianCalendar(*GMT,status);
848 Calendar *cal3 = new GregorianCalendar(*PST,status);
849 cal2->set(UCAL_MILLISECOND, 0);
850 cal3->set(UCAL_MILLISECOND, 0);
851
852 cal2->set(cal1->get(UCAL_YEAR,status),
853 cal1->get(UCAL_MONTH,status),
854 cal1->get(UCAL_DATE,status),
855 cal1->get(UCAL_HOUR_OF_DAY,status),
856 cal1->get(UCAL_MINUTE,status),
857 cal1->get(UCAL_SECOND,status));
858
859 double t1,t2,t3,t4;
860 logln(UnicodeString("RGMT 1 is: ") + (t1=cal2->getTime(status)));
861 cal3->set(year, month, day, hr, min, sec);
862 logln(UnicodeString("RPST 1 is: ") + (t2=cal3->getTime(status)));
863 cal3->setTimeZone(*GMT);
864 logln(UnicodeString("RGMT 2 is: ") + (t3=cal3->getTime(status)));
865 cal3->set(cal1->get(UCAL_YEAR,status),
866 cal1->get(UCAL_MONTH,status),
867 cal1->get(UCAL_DATE,status),
868 cal1->get(UCAL_HOUR_OF_DAY,status),
869 cal1->get(UCAL_MINUTE,status),
870 cal1->get(UCAL_SECOND,status));
871 // Issue 2: Calendar continues to use the timezone in its
872 // constructor for set() conversions, regardless
873 // of calls to setTimeZone()
874 logln(UnicodeString("RGMT 3 is: ") + (t4=cal3->getTime(status)));
875 if (t1 == t2 ||
876 t1 != t4 ||
877 t2 != t3)
878 errln("Fail: Calendar zone behavior faulty");
879
880 delete cal1;
881 delete cal2;
882 delete cal3;
883 delete GMT;
884 delete PST;
885 }
886
887 /**
888 * @bug 4096539
889 */
test4096539()890 void CalendarRegressionTest::test4096539()
891 {
892 UErrorCode status = U_ZERO_ERROR;
893 int32_t y [] = {31,28,31,30,31,30,31,31,30,31,30,31};
894
895 for (int32_t x=0;x<12;x++) {
896 GregorianCalendar *gc = new
897 GregorianCalendar(1997,x,y[x], status);
898 if (U_FAILURE(status)) {
899 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
900 delete gc;
901 return;
902 }
903 int32_t m1,m2;
904 log(UnicodeString("") + (m1=gc->get(UCAL_MONTH,status)+1)+UnicodeString("/")+
905 gc->get(UCAL_DATE,status)+"/"+gc->get(UCAL_YEAR,status)+
906 " + 1mo = ");
907
908 gc->add(UCAL_MONTH, 1,status);
909 logln(UnicodeString("") + (m2=gc->get(UCAL_MONTH,status)+1)+UnicodeString("/")+
910 gc->get(UCAL_DATE,status)+"/"+gc->get(UCAL_YEAR,status)
911 );
912 int32_t m = (m1 % 12) + 1;
913 if (m2 != m)
914 errln(UnicodeString("Fail: Want ") + m + " Got " + m2);
915 delete gc;
916 }
917
918 }
919
920 /**
921 * @bug 4100311
922 */
test41003112()923 void CalendarRegressionTest::test41003112()
924 {
925 UErrorCode status = U_ZERO_ERROR;
926 GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status);
927 if(U_FAILURE(status)) {
928 dataerrln("Error creating calendar: %s", u_errorName(status));
929 delete cal;
930 return;
931 }
932 cal->set(UCAL_YEAR, 1997);
933 cal->set(UCAL_DAY_OF_YEAR, 1);
934 //UDate d = cal->getTime(status); // Should be Jan 1
935 //logln(d.toString());
936 if (cal->get(UCAL_DAY_OF_YEAR, status) != 1)
937 errln("Fail: DAY_OF_YEAR not set");
938 delete cal;
939 }
940
941 /**
942 * @bug 4103271
943 */
test4103271()944 void CalendarRegressionTest::test4103271()
945 {
946 UErrorCode status = U_ZERO_ERROR;
947 SimpleDateFormat sdf(status);
948 int32_t numYears=40, startYear=1997, numDays=15;
949 UnicodeString output, testDesc, str, str2;
950 GregorianCalendar *testCal = (GregorianCalendar*)Calendar::createInstance(status);
951 if(U_FAILURE(status)) {
952 dataerrln("Error creating calendar: %s", u_errorName(status));
953 delete testCal;
954 return;
955 }
956 testCal->clear();
957 sdf.adoptCalendar(testCal);
958 sdf.applyPattern("EEE dd MMM yyyy 'WOY'ww'-'YYYY 'DOY'DDD");
959 UBool fail = FALSE;
960 for (int32_t firstDay=1; firstDay<=2; firstDay++) {
961 for (int32_t minDays=1; minDays<=7; minDays++) {
962 testCal->setMinimalDaysInFirstWeek((uint8_t)minDays);
963 testCal->setFirstDayOfWeek((UCalendarDaysOfWeek)firstDay);
964 testDesc = (UnicodeString("Test") + firstDay + minDays);
965 logln(testDesc + " => 1st day of week=" +
966 firstDay +
967 ", minimum days in first week=" +
968 minDays);
969 for (int32_t j=startYear; j<=startYear+numYears; j++) {
970 testCal->set(j,11,25);
971 for(int32_t i=0; i<numDays; i++) {
972 testCal->add(UCAL_DATE,1,status);
973 UnicodeString calWOY;
974 int32_t actWOY = testCal->get(UCAL_WEEK_OF_YEAR,status);
975 if (actWOY < 1 || actWOY > 53) {
976 UDate d = testCal->getTime(status);
977 //calWOY = String.valueOf(actWOY);
978 UnicodeString temp;
979 FieldPosition pos(FieldPosition::DONT_CARE);
980 output = testDesc + " - " + sdf.format(d,temp,pos) + "\t";
981 output = output + "\t" + actWOY;
982 logln(output);
983 fail = TRUE;
984 }
985 }
986 }
987 }
988 }
989
990 int32_t DATA [] = {
991 3, 52, 52, 52, 52, 52, 52, 52,
992 1, 1, 1, 1, 1, 1, 1,
993 2, 2, 2, 2, 2, 2, 2,
994 4, 52, 52, 52, 52, 52, 52, 52,
995 53, 53, 53, 53, 53, 53, 53,
996 1, 1, 1, 1, 1, 1, 1,
997 };
998 testCal->setFirstDayOfWeek(UCAL_SUNDAY);
999 for (int32_t j=0; j<44; j+=22) {
1000 logln(UnicodeString("Minimal days in first week = ") + DATA[j] +
1001 " Week starts on Sunday");
1002 testCal->setMinimalDaysInFirstWeek((uint8_t)DATA[j]);
1003 testCal->set(1997, UCAL_DECEMBER, 21);
1004 for (int32_t i=0; i<21; ++i) {
1005 int32_t woy = testCal->get(UCAL_WEEK_OF_YEAR,status);
1006 str.remove();
1007 log(UnicodeString("") + sdf.format(testCal->getTime(status), str) +
1008 UnicodeString(" ") + woy);
1009 if (woy != DATA[j + 1 + i]) {
1010 log(" ERROR");
1011 fail = TRUE;
1012 }
1013 logln("");
1014
1015 // Now compute the time from the fields, and make sure we
1016 // get the same answer back. This is a round-trip test.
1017 UDate save = testCal->getTime(status);
1018 testCal->clear();
1019 testCal->set(UCAL_YEAR_WOY, DATA[j+1+i] < 25 ? 1998 : 1997);
1020 testCal->set(UCAL_WEEK_OF_YEAR, DATA[j+1+i]);
1021 testCal->set(UCAL_DAY_OF_WEEK, (i%7) + UCAL_SUNDAY);
1022 if (testCal->getTime(status) != save) {
1023 str.remove();
1024 logln(UnicodeString(" Parse failed: ") +
1025 sdf.format(testCal->getTime(status), str));
1026 fail= TRUE;
1027 }
1028
1029 testCal->setTime(save,status);
1030 testCal->add(UCAL_DATE, 1,status);
1031 }
1032 }
1033 // Test field disambiguation with a few special hard-coded cases.
1034 // This shouldn't fail if the above cases aren't failing.
1035 int32_t DISAM_int [] = {
1036 // y y_woy woy dow
1037 1997, 1998, 1, UCAL_SUNDAY,
1038 (1998), (1998), (2), (UCAL_SATURDAY),
1039 (1998), (1998), (53), (UCAL_THURSDAY),
1040 (1999), (1998), (53), (UCAL_FRIDAY)
1041 };
1042
1043 UDate DISAM_date [] = {
1044 makeDate(1997, UCAL_DECEMBER, 28),
1045 makeDate(1998, UCAL_JANUARY, 10),
1046 makeDate(1998, UCAL_DECEMBER, 31),
1047 makeDate(1999, UCAL_JANUARY, 1)
1048 };
1049
1050 testCal->setMinimalDaysInFirstWeek(3);
1051 testCal->setFirstDayOfWeek(UCAL_SUNDAY);
1052 int32_t i = 0;
1053
1054 /* Enable this code to display various WOY values
1055 testCal->clear();
1056 for (i=25; i<38; ++i) {
1057 testCal->set(1996, Calendar::DECEMBER, i);
1058 UDate got = testCal->getTime(status);
1059 str.remove();
1060 logln(UnicodeString("") + sdf.format(got, str));
1061 }
1062 for (i=25; i<38; ++i) {
1063 testCal->set(1997, Calendar::DECEMBER, i);
1064 UDate got = testCal->getTime(status);
1065 str.remove();
1066 logln(UnicodeString("") + sdf.format(got, str));
1067 }
1068 for (i=25; i<38; ++i) {
1069 testCal->set(1998, UCAL_DECEMBER, i);
1070 UDate got = testCal->getTime(status);
1071 str.remove();
1072 logln(UnicodeString("") + sdf.format(got, str));
1073 }
1074 */
1075
1076 for (i=0; i < 16; i += 4) {
1077 int32_t y = DISAM_int[i];
1078 int32_t ywoy = DISAM_int[i+1];
1079 int32_t woy = DISAM_int[i+2];
1080 int32_t dow = DISAM_int[i+3];
1081 UDate exp = DISAM_date[i/4];
1082 testCal->clear();
1083 testCal->set(UCAL_YEAR, y);
1084 testCal->set(UCAL_WEEK_OF_YEAR, woy);
1085 testCal->set(UCAL_DAY_OF_WEEK, dow);
1086 UDate got = testCal->getTime(status);
1087 str.remove();
1088 str2.remove();
1089 log(UnicodeString("Y") + y + "-W" + woy +
1090 "-DOW" + dow + " expect:" + sdf.format(exp, str) +
1091 " got:" + sdf.format(got, str2));
1092 if (got != exp) {
1093 log(" FAIL (%s:%d, i=%d)", __FILE__, __LINE__, i);
1094 logln(CalendarTest::calToStr(*testCal));
1095 testCal->setTime(exp, status);
1096 logln(CalendarTest::calToStr(*testCal) + UnicodeString( " <<< expected "));
1097 fail = TRUE;
1098 }
1099 logln("");
1100
1101 testCal->clear();
1102 testCal->set(UCAL_YEAR_WOY, ywoy);
1103 testCal->set(UCAL_WEEK_OF_YEAR, woy);
1104 testCal->set(UCAL_DAY_OF_WEEK, dow);
1105 got = testCal->getTime(status);
1106 str.remove();
1107 str2.remove();
1108 log(UnicodeString("YWOY") + ywoy + "-W" + woy +
1109 "-DOW" + dow + " expect:" + sdf.format(exp, str) +
1110 " got:" + sdf.format(got, str2));
1111 if (got != exp) {
1112 log(" FAIL");
1113 fail = TRUE;
1114 }
1115 logln("");
1116 }
1117 // Now try adding and rolling
1118 UDate ADDROLL_date [] = {
1119 makeDate(1998, UCAL_DECEMBER, 25), makeDate(1999, UCAL_JANUARY, 1),
1120 makeDate(1997, UCAL_DECEMBER, 28), makeDate(1998, UCAL_JANUARY, 4),
1121 makeDate(1998, UCAL_DECEMBER, 27), makeDate(1997, UCAL_DECEMBER, 28),
1122 makeDate(1999, UCAL_JANUARY, 2), makeDate(1998, UCAL_JANUARY, 3),
1123 };
1124
1125 int32_t ADDROLL_int []= {
1126 (1),
1127 (1),
1128 (1),
1129 (1)
1130 };
1131
1132
1133 UBool ADDROLL_bool [] = {
1134 TRUE,//ADD,
1135 TRUE,
1136 FALSE,
1137 FALSE
1138 };
1139
1140 testCal->setMinimalDaysInFirstWeek(3);
1141 testCal->setFirstDayOfWeek(UCAL_SUNDAY);
1142 for (i=0; i<8; i += 2) {
1143 int32_t amount = ADDROLL_int[i/2];
1144 UDate before = ADDROLL_date[i];
1145 UDate after = ADDROLL_date[i+1];
1146
1147 testCal->setTime(before,status);
1148 if (ADDROLL_bool[i/2])
1149 testCal->add(UCAL_WEEK_OF_YEAR, amount,status);
1150 else
1151 testCal->roll(UCAL_WEEK_OF_YEAR, amount,status);
1152 UDate got = testCal->getTime(status);
1153 str.remove();
1154 str2.remove();
1155 UnicodeString opTypeStr;
1156 if (ADDROLL_bool[i/2]) {
1157 opTypeStr = UnicodeString("add(WOY,", "");
1158 } else {
1159 opTypeStr = UnicodeString("roll(WOY,", "");
1160 }
1161 log(opTypeStr + amount + ") " + sdf.format(before, str) + " => " +
1162 sdf.format(got, str2));
1163 if (after != got) {
1164 str.remove();
1165 logln(UnicodeString(" exp:") + sdf.format(after, str) + " FAIL");
1166 fail = TRUE;
1167 }
1168 else logln(" ok");
1169
1170 testCal->setTime(after,status);
1171 if (ADDROLL_bool[i/2])
1172 testCal->add(UCAL_WEEK_OF_YEAR, -amount,status);
1173 else
1174 testCal->roll(UCAL_WEEK_OF_YEAR, -amount,status);
1175 got = testCal->getTime(status);
1176 str.remove();
1177 str2.remove();
1178 log(opTypeStr + (-amount) + ") " + sdf.format(after, str) + " => " +
1179 sdf.format(got, str2));
1180 if (before != got) {
1181 str.remove();
1182 logln(UnicodeString(" exp:") + sdf.format(before, str) + " FAIL");
1183 fail = TRUE;
1184 }
1185 else logln(" ok");
1186 }
1187 if (fail)
1188 errln("Fail: Week of year misbehaving");
1189 }
1190
1191 /**
1192 * @bug 4106136
1193 */
test4106136()1194 void CalendarRegressionTest::test4106136()
1195 {
1196 UErrorCode status = U_ZERO_ERROR;
1197 Locale saveLocale = Locale::getDefault();
1198 //try {
1199 Locale locales [] = { Locale::getChinese(), Locale::getChina() };
1200 for (int32_t i=0; i<2; ++i) {
1201 Locale::setDefault(locales[i], status);
1202 failure(status, "Locale::setDefault");
1203 int32_t count1, count2, count3;
1204 Calendar::getAvailableLocales(count1);
1205 DateFormat::getAvailableLocales(count2);
1206 NumberFormat::getAvailableLocales(count3);
1207 int32_t n [] = {
1208 count1, count2, count3
1209 };
1210 for (int32_t j=0; j<3; ++j) {
1211 UnicodeString temp;
1212 if (n[j] == 0)
1213 dataerrln(UnicodeString("Fail: No locales for ") + locales[i].getName());
1214 }
1215 }
1216 //}
1217 //finally {
1218 Locale::setDefault(saveLocale,status);
1219 //}
1220 }
1221
1222 /**
1223 * @bug 4108764
1224 */
test4108764()1225 void CalendarRegressionTest::test4108764()
1226 {
1227 UErrorCode status = U_ZERO_ERROR;
1228 Calendar *cal = Calendar::createInstance(status);
1229 if(U_FAILURE(status)) {
1230 dataerrln("Error creating calendar %s", u_errorName(status));
1231 delete cal;
1232 return;
1233 }
1234 UDate d00 = makeDate(1997, UCAL_MARCH, 15, 12, 00, 00);
1235 UDate d01 = makeDate(1997, UCAL_MARCH, 15, 12, 00, 56);
1236 UDate d10 = makeDate(1997, UCAL_MARCH, 15, 12, 34, 00);
1237 UDate d11 = makeDate(1997, UCAL_MARCH, 15, 12, 34, 56);
1238 UDate epoch = makeDate(1970, UCAL_JANUARY, 1);
1239
1240 cal->setTime(d11,status);
1241
1242 cal->clear( UCAL_MINUTE );
1243 logln(UnicodeString("") + cal->getTime(status));
1244 if (cal->getTime(status) != d01)
1245 errln("Fail: clear(MINUTE) broken");
1246
1247 cal->set( UCAL_SECOND, 0 );
1248 logln(UnicodeString("") + cal->getTime(status));
1249 if (cal->getTime(status) != d00)
1250 errln("Fail: set(SECOND, 0) broken");
1251
1252 cal->setTime(d11,status);
1253 cal->set( UCAL_SECOND, 0 );
1254 logln(UnicodeString("") + cal->getTime(status));
1255 if (cal->getTime(status) != d10)
1256 errln("Fail: set(SECOND, 0) broken #2");
1257
1258 cal->clear( UCAL_MINUTE );
1259 logln(UnicodeString("") + cal->getTime(status));
1260 if (cal->getTime(status) != d00)
1261 errln("Fail: clear(MINUTE) broken #2");
1262
1263 cal->clear();
1264 logln(UnicodeString("") + cal->getTime(status));
1265 if (cal->getTime(status) != epoch)
1266 errln(UnicodeString("Fail: clear() broken Want ") + epoch);
1267
1268 delete cal;
1269 }
1270
1271 /**
1272 * @bug 4114578
1273 */
test4114578()1274 void CalendarRegressionTest::test4114578()
1275 {
1276 UErrorCode status = U_ZERO_ERROR;
1277 double ONE_HOUR = 60*60*1000;
1278 Calendar *cal = Calendar::createInstance(status);
1279 if(U_FAILURE(status)) {
1280 dataerrln("Error creating calendar %s", u_errorName(status));
1281 delete cal;
1282 return;
1283 }
1284 cal->adoptTimeZone(TimeZone::createTimeZone("PST"));
1285 UDate onset = makeDate(1998, UCAL_APRIL, 5, 1, 0) + ONE_HOUR;
1286 UDate cease = makeDate(1998, UCAL_OCTOBER, 25, 0, 0) + 2*ONE_HOUR;
1287
1288 UBool fail = FALSE;
1289
1290 const int32_t ADD = 1;
1291 const int32_t ROLL = 2;
1292
1293 double DATA []= {
1294 // Start Action Amt Expected_change
1295 onset - ONE_HOUR, ADD, 1, ONE_HOUR,
1296 onset, ADD, -1, -ONE_HOUR,
1297 onset - ONE_HOUR, ROLL, 1, ONE_HOUR,
1298 onset, ROLL, -1, -ONE_HOUR,
1299 cease - ONE_HOUR, ADD, 1, ONE_HOUR,
1300 cease, ADD, -1, -ONE_HOUR,
1301 cease - ONE_HOUR, ROLL, 1, ONE_HOUR,
1302 cease, ROLL, -1, -ONE_HOUR,
1303 };
1304
1305 for (int32_t i=0; i<32; i+=4) {
1306 UDate date = DATA[i];
1307 int32_t amt = (int32_t) DATA[i+2];
1308 double expectedChange = DATA[i+3];
1309
1310 log(UnicodeString("") + date);
1311 cal->setTime(date,status);
1312
1313 switch ((int32_t) DATA[i+1]) {
1314 case ADD:
1315 log(UnicodeString(" add (HOUR,") + (amt<0?"":"+")+amt + ")= ");
1316 cal->add(UCAL_HOUR, amt,status);
1317 break;
1318 case ROLL:
1319 log(UnicodeString(" roll(HOUR,") + (amt<0?"":"+")+amt + ")= ");
1320 cal->roll(UCAL_HOUR, amt,status);
1321 break;
1322 }
1323
1324 log(UnicodeString("") + cal->getTime(status));
1325
1326 double change = cal->getTime(status) - date;
1327 if (change != expectedChange) {
1328 fail = TRUE;
1329 logln(" FAIL");
1330 }
1331 else logln(" OK");
1332 }
1333
1334 if (fail) errln("Fail: roll/add misbehaves around DST onset/cease");
1335
1336 delete cal;
1337 }
1338
1339 /**
1340 * @bug 4118384
1341 * Make sure maximum for HOUR field is 11, not 12.
1342 */
test4118384()1343 void CalendarRegressionTest::test4118384()
1344 {
1345 UErrorCode status = U_ZERO_ERROR;
1346 Calendar *cal = Calendar::createInstance(status);
1347 if(U_FAILURE(status)) {
1348 dataerrln("Error creating calendar %s", u_errorName(status));
1349 delete cal;
1350 return;
1351 }
1352 if (cal->getMaximum(UCAL_HOUR) != 11 ||
1353 cal->getLeastMaximum(UCAL_HOUR) != 11 ||
1354 cal->getActualMaximum(UCAL_HOUR,status) != 11)
1355 errln("Fail: maximum of HOUR field should be 11");
1356
1357 // test deprecated functions
1358 if (cal->getLeastMaximum(Calendar::HOUR) != 11 ||
1359 cal->getMaximum(Calendar::HOUR) != 11) {
1360 errln("Fail: [deprecated functions] maximum of HOUR field should be 11\n");
1361 }
1362
1363 if (cal->getGreatestMinimum(Calendar::HOUR) != 0 ||
1364 cal->getMinimum(Calendar::HOUR) != 0) {
1365 errln("Fail: [deprecated functions] minimum of HOUR field should be 1\n");
1366 }
1367
1368 delete cal;
1369 cal = Calendar::createInstance(Locale("th_TH@calendar=buddhist"),status);
1370 // test deprecated functions
1371 if (cal->getLeastMaximum(Calendar::HOUR) != 11 ||
1372 cal->getMaximum(Calendar::HOUR) != 11) {
1373 errln("Fail: Buddhist:[deprecated functions] maximum of HOUR field should be 11\n");
1374 }
1375
1376 if (cal->getGreatestMinimum(Calendar::HOUR) != 0 ||
1377 cal->getMinimum(Calendar::HOUR) != 0) {
1378 errln("Fail: Buddhist:[deprecated functions] minimum of HOUR field should be 1\n");
1379 }
1380
1381 delete cal;
1382 // test deprecated functions
1383 cal = Calendar::createInstance(Locale("ja_JP@calendar=japanese"),status);
1384 if (cal->getLeastMaximum(Calendar::HOUR) != 11 ||
1385 cal->getMaximum(Calendar::HOUR) != 11) {
1386 errln("Fail: Japanese:[deprecated functions] maximum of HOUR field should be 11\n");
1387 }
1388
1389 if (cal->getGreatestMinimum(Calendar::HOUR) != 0 ||
1390 cal->getMinimum(Calendar::HOUR) != 0) {
1391 errln("Fail: Japanese:[deprecated functions] minimum of HOUR field should be 1\n");
1392 }
1393
1394 delete cal;
1395 }
1396
1397 /**
1398 * @bug 4125881
1399 * Check isLeapYear for BC years.
1400 */
test4125881()1401 void CalendarRegressionTest::test4125881()
1402 {
1403 UErrorCode status = U_ZERO_ERROR;
1404 GregorianCalendar *cal = (GregorianCalendar*) Calendar::createInstance(status);
1405 if(U_FAILURE(status)) {
1406 dataerrln("Error creating calendar %s", u_errorName(status));
1407 delete cal;
1408 return;
1409 }
1410 DateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status);
1411 if(!assertSuccess("trying to construct", status))return;
1412 cal->clear();
1413 for (int32_t y=-20; y<=10; ++y) {
1414 cal->set(UCAL_ERA, y < 1 ? GregorianCalendar::BC : GregorianCalendar::AD);
1415 cal->set(UCAL_YEAR, y < 1 ? 1 - y : y);
1416 UnicodeString temp;
1417 logln(UnicodeString("") + y + UnicodeString(" = ") + fmt->format(cal->getTime(status), temp) + " " +
1418 cal->isLeapYear(y));
1419 if (cal->isLeapYear(y) != ((y+40)%4 == 0))
1420 errln("Leap years broken");
1421 }
1422
1423 delete cal;
1424 delete fmt;
1425 }
1426
1427 /**
1428 * @bug 4125892
1429 * Prove that GregorianCalendar is proleptic (it used to cut off
1430 * at 45 BC, and not have leap years before then).
1431 */
test4125892()1432 void CalendarRegressionTest::test4125892() {
1433 UErrorCode status = U_ZERO_ERROR;
1434 GregorianCalendar *cal = (GregorianCalendar*) Calendar::createInstance(status);
1435 if(U_FAILURE(status)) {
1436 dataerrln("Error creating calendar %s", u_errorName(status));
1437 delete cal;
1438 return;
1439 }
1440 DateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status);
1441 if(!assertSuccess("trying to construct", status))return;
1442 cal->clear();
1443 cal->set(UCAL_ERA, GregorianCalendar::BC);
1444 cal->set(UCAL_YEAR, 81); // 81 BC is a leap year (proleptically)
1445 cal->set(UCAL_MONTH, UCAL_FEBRUARY);
1446 cal->set(UCAL_DATE, 28);
1447 cal->add(UCAL_DATE, 1,status);
1448 if(U_FAILURE(status))
1449 errln("add(DATE,1) failed");
1450 if (cal->get(UCAL_DATE,status) != 29 ||
1451 !cal->isLeapYear(-80)) // -80 == 81 BC
1452 errln("Calendar not proleptic");
1453
1454 delete cal;
1455 delete fmt;
1456 }
1457
1458 /**
1459 * @bug 4141665
1460 * GregorianCalendar::equals() ignores cutover date
1461 */
test4141665()1462 void CalendarRegressionTest::test4141665()
1463 {
1464 UErrorCode status = U_ZERO_ERROR;
1465 GregorianCalendar *cal = new GregorianCalendar(status);
1466 if(U_FAILURE(status)) {
1467 dataerrln("Error creating calendar %s", u_errorName(status));
1468 delete cal;
1469 return;
1470 }
1471 GregorianCalendar *cal2 = (GregorianCalendar*)cal->clone();
1472 UDate cut = cal->getGregorianChange();
1473 UDate cut2 = cut + 100*24*60*60*1000.0; // 100 days later
1474 if (*cal != *cal2) {
1475 errln("Cloned GregorianCalendars not equal");
1476 }
1477 cal2->setGregorianChange(cut2,status);
1478 if ( *cal == *cal2) {
1479 errln("GregorianCalendar::equals() ignores cutover");
1480 }
1481
1482 delete cal;
1483 delete cal2;
1484 }
1485
1486 /**
1487 * @bug 4142933
1488 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll()
1489 * when IllegalArgumentException should be.
1490 */
test4142933()1491 void CalendarRegressionTest::test4142933()
1492 {
1493 UErrorCode status = U_ZERO_ERROR;
1494 GregorianCalendar *calendar = new GregorianCalendar(status);
1495 if(U_FAILURE(status)) {
1496 dataerrln("Error creating calendar %s", u_errorName(status));
1497 delete calendar;
1498 return;
1499 }
1500 //try {
1501 calendar->roll((UCalendarDateFields)-1, TRUE, status);
1502 if(U_SUCCESS(status))
1503 errln("Test failed, no exception thrown");
1504 //}
1505 //catch (IllegalArgumentException e) {
1506 // OK: Do nothing
1507 // logln("Test passed");
1508 //}
1509 //catch (Exception e) {
1510 //errln("Test failed. Unexpected exception is thrown: " + e);
1511 //e.printStackTrace();
1512 //}
1513
1514 delete calendar;
1515 }
1516
1517 /**
1518 * @bug 4145158
1519 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1520 * confusing; unless the time zone has a raw offset of zero, one or the
1521 * other of these will wrap. We've modified the test given in the bug
1522 * report to therefore only check the behavior of a calendar with a zero raw
1523 * offset zone.
1524 */
test4145158()1525 void CalendarRegressionTest::test4145158()
1526 {
1527 UErrorCode status = U_ZERO_ERROR;
1528 GregorianCalendar *calendar = new GregorianCalendar(status);
1529 if(status == U_USING_FALLBACK_WARNING || U_FAILURE(status)) {
1530 dataerrln("Error creating calendar %s", u_errorName(status));
1531 delete calendar;
1532 return;
1533 }
1534
1535 calendar->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1536
1537 calendar->setTime(makeDate(INT32_MIN),status);
1538 int32_t year1 = calendar->get(UCAL_YEAR,status);
1539 int32_t era1 = calendar->get(UCAL_ERA,status);
1540
1541 calendar->setTime(makeDate(INT32_MAX),status);
1542 int32_t year2 = calendar->get(UCAL_YEAR,status);
1543 int32_t era2 = calendar->get(UCAL_ERA,status);
1544
1545 if (year1 == year2 && era1 == era2) {
1546 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1547 }
1548
1549 delete calendar;
1550 }
1551
1552 /**
1553 * @bug 4145983
1554 * Maximum value for YEAR field wrong.
1555 */
1556 // {sfb} this is not directly applicable in C++, since all
1557 // possible doubles are not representable by our Calendar.
1558 // In Java, all longs are representable.
1559 // We can determine limits programmatically
1560 // Using DBL_MAX is a bit of a hack, since for large doubles
1561 // Calendar gets squirrely and doesn't behave in any sort
1562 // of linear fashion (ie years jump around, up/down, etc) for a
1563 // small change in millis.
test4145983()1564 void CalendarRegressionTest::test4145983()
1565 {
1566 UErrorCode status = U_ZERO_ERROR;
1567 GregorianCalendar *calendar = new GregorianCalendar(status);
1568 if(U_FAILURE(status)) {
1569 dataerrln("Error creating calendar %s", u_errorName(status));
1570 delete calendar;
1571 return;
1572 }
1573 calendar->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1574 UDate DATES [] = { LATEST_SUPPORTED_MILLIS, EARLIEST_SUPPORTED_MILLIS };
1575 for (int32_t i=0; i<2; ++i) {
1576 calendar->setTime(DATES[i], status);
1577 int32_t year = calendar->get(UCAL_YEAR,status);
1578 int32_t maxYear = calendar->getMaximum(UCAL_YEAR);
1579 if (year > maxYear) {
1580 errln(UnicodeString("Failed for ")+DATES[i]+" ms: year=" +
1581 year + ", maxYear=" + maxYear);
1582 }
1583 }
1584
1585 delete calendar;
1586 }
1587
1588 /**
1589 * @bug 4147269
1590 * This is a bug in the validation code of GregorianCalendar:: As reported,
1591 * the bug seems worse than it really is, due to a bug in the way the bug
1592 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR
1593 * field. - liu 6/29/98
1594 */
test4147269()1595 void CalendarRegressionTest::test4147269()
1596 {
1597 UErrorCode status = U_ZERO_ERROR;
1598 GregorianCalendar *calendar = new GregorianCalendar(status);
1599 if(status == U_USING_FALLBACK_WARNING || U_FAILURE(status)) {
1600 dataerrln("Error creating calendar %s", u_errorName(status));
1601 delete calendar;
1602 return;
1603 }
1604 calendar->setLenient(FALSE);
1605 UDate date = makeDate(1996, UCAL_JANUARY, 3); // Arbitrary date
1606 for (int32_t field = 0; field < UCAL_FIELD_COUNT; field++) {
1607 calendar->setTime(date,status);
1608 // Note: In the bug report, getActualMaximum() was called instead
1609 // of getMaximum() -- this was an error. The validation code doesn't
1610 // use getActualMaximum(), since that's too costly.
1611 int32_t max = calendar->getMaximum((UCalendarDateFields)field);
1612 int32_t value = max+1;
1613 calendar->set((UCalendarDateFields)field, value);
1614 //try {
1615 calendar->getTime(status); // Force time computation
1616 // We expect an exception to be thrown. If we fall through
1617 // to the next line, then we have a bug.
1618 if(U_SUCCESS(status))
1619 errln(UnicodeString("Test failed with field ") + FIELD_NAME[field] +
1620 ", date before: " + date +
1621 ", date after: " + calendar->getTime(status) +
1622 ", value: " + value + " (max = " + max +")");
1623 //} catch (IllegalArgumentException e) {}
1624 }
1625
1626 delete calendar;
1627 }
1628
1629 /**
1630 * @bug 4149677
1631 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
1632 * doesn't behave as a pure Julian calendar.
1633 * CANNOT REPRODUCE THIS BUG
1634 */
1635 void
Test4149677()1636 CalendarRegressionTest::Test4149677()
1637 {
1638 UErrorCode status = U_ZERO_ERROR;
1639
1640 TimeZone *zones [] = {
1641 TimeZone::createTimeZone("GMT"),
1642 TimeZone::createTimeZone("PST"),
1643 TimeZone::createTimeZone("EAT")
1644 };
1645 if(U_FAILURE(status)) {
1646 errln("Couldn't create zones");
1647 return;
1648 // could leak memory
1649 }
1650
1651 for (int32_t i=0; i < 3; ++i) {
1652 GregorianCalendar *calendar = new GregorianCalendar(zones[i], status);
1653 if(U_FAILURE(status)) {
1654 dataerrln("Couldnt' create calendar.: %s", u_errorName(status));
1655 return;
1656 }
1657
1658 // Make sure extreme values don't wrap around
1659 calendar->setTime(EARLIEST_SUPPORTED_MILLIS, status);
1660 if(U_FAILURE(status))
1661 errln("setTime failed");
1662 if (calendar->get(UCAL_ERA, status) != GregorianCalendar::BC || U_FAILURE(status)) {
1663 errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year");
1664 }
1665 calendar->setTime(LATEST_SUPPORTED_MILLIS, status);
1666 if(U_FAILURE(status))
1667 errln("setTime failed");
1668 if (calendar->get(UCAL_ERA, status) != GregorianCalendar::AD || U_FAILURE(status)) {
1669 errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year");
1670 }
1671
1672 calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status);
1673 if(U_FAILURE(status))
1674 errln("setGregorianChange failed");
1675 // to obtain a pure Julian calendar
1676
1677 UBool is100Leap = calendar->isLeapYear(100);
1678 if (!is100Leap) {
1679 UnicodeString temp;
1680 errln("test failed with zone " + zones[i]->getID(temp));
1681 errln(" cutover date is Date(Long.MAX_VALUE)");
1682 errln(" isLeapYear(100) returns: " + is100Leap);
1683 }
1684 delete calendar;
1685 }
1686
1687 // no need for cleanup- zones were adopted
1688 }
1689
1690 /**
1691 * @bug 4162587
1692 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar
1693 * and Date classes will misbehave.
1694 */
1695 void
Test4162587()1696 CalendarRegressionTest::Test4162587()
1697 {
1698 UErrorCode status = U_ZERO_ERROR;
1699 TimeZone *savedef = TimeZone::createDefault();
1700 TimeZone *tz = TimeZone::createTimeZone("PST");
1701 //TimeZone::adoptDefault(tz);
1702 TimeZone::setDefault(*tz);
1703
1704 GregorianCalendar *cal = new GregorianCalendar(tz, status);
1705 if(U_FAILURE(status)) {
1706 dataerrln("Couldn't create calendar.: %s", u_errorName(status));
1707 return;
1708 }
1709 UDate d0, dPlus, dMinus;
1710
1711 for(int32_t i=0; i<5; ++i) {
1712 if (i>0) logln("---");
1713
1714 cal->clear();
1715 cal->set(1998, UCAL_APRIL, 5, i, 0);
1716 d0 = cal->getTime(status);
1717 if(U_FAILURE(status))
1718 errln("Coudln't get time (1)");
1719 //String s0 = d.toString();
1720 logln(UnicodeString("0 ") + i + ": " + d0/*s0*/);
1721
1722 cal->clear();
1723 cal->set(1998, UCAL_APRIL, 4, i+24, 0);
1724 dPlus = cal->getTime(status);
1725 if(U_FAILURE(status))
1726 errln("Coudln't get time (2)");
1727 //String sPlus = d.toString();
1728 logln(UnicodeString("+ ") + i + ": " + dPlus/*sPlus*/);
1729
1730 cal->clear();
1731 cal->set(1998, UCAL_APRIL, 6, i-24, 0);
1732 dMinus = cal->getTime(status);
1733 if(U_FAILURE(status))
1734 errln("Coudln't get time (3)");
1735 //String sMinus = d.toString();
1736 logln(UnicodeString("- ") + i + ": " + dMinus/*sMinus*/);
1737
1738 if (d0 != dPlus || d0 != dMinus) {
1739 errln("Fail: All three lines must match");
1740 }
1741 }
1742 TimeZone::setDefault(*savedef);
1743 //delete tz;
1744 delete cal;
1745 delete savedef;
1746 }
1747
1748 /**
1749 * @bug 4165343
1750 * Adding 12 months behaves differently from adding 1 year
1751 */
1752 void
Test4165343()1753 CalendarRegressionTest::Test4165343()
1754 {
1755 UErrorCode status = U_ZERO_ERROR;
1756 GregorianCalendar *calendar = new GregorianCalendar(1996, UCAL_FEBRUARY, 29, status);
1757 if(U_FAILURE(status)) {
1758 dataerrln("Couldn't create calendar.: %s", u_errorName(status));
1759 return;
1760 }
1761 UDate start = calendar->getTime(status);
1762 if(U_FAILURE(status))
1763 errln("Couldn't getTime (1)");
1764 logln(UnicodeString("init date: ") + start);
1765 calendar->add(UCAL_MONTH, 12, status);
1766 if(U_FAILURE(status))
1767 errln("Couldn't add(MONTH, 12)");
1768 UDate date1 = calendar->getTime(status);
1769 if(U_FAILURE(status))
1770 errln("Couldn't getTime (2)");
1771 logln(UnicodeString("after adding 12 months: ") + date1);
1772 calendar->setTime(start, status);
1773 if(U_FAILURE(status))
1774 errln("Couldn't setTime");
1775 calendar->add(UCAL_YEAR, 1, status);
1776 if(U_FAILURE(status))
1777 errln("Couldn't add(YEAR, 1)");
1778 UDate date2 = calendar->getTime(status);
1779 if(U_FAILURE(status))
1780 errln("Couldn't getTime (3)");
1781 logln(UnicodeString("after adding one year : ") + date2);
1782 if (date1 == date2) {
1783 logln("Test passed");
1784 } else {
1785 errln("Test failed");
1786 }
1787 delete calendar;
1788 }
1789
1790 /**
1791 * @bug 4166109
1792 * GregorianCalendar.getActualMaximum() does not account for first day of week.
1793 */
1794 void
Test4166109()1795 CalendarRegressionTest::Test4166109()
1796 {
1797 /* Test month:
1798 *
1799 * March 1998
1800 * Su Mo Tu We Th Fr Sa
1801 * 1 2 3 4 5 6 7
1802 * 8 9 10 11 12 13 14
1803 * 15 16 17 18 19 20 21
1804 * 22 23 24 25 26 27 28
1805 * 29 30 31
1806 */
1807 UBool passed = TRUE;
1808 UErrorCode status = U_ZERO_ERROR;
1809 UCalendarDateFields field = UCAL_WEEK_OF_MONTH;
1810
1811 GregorianCalendar *calendar = new GregorianCalendar(Locale::getUS(), status);
1812 if(U_FAILURE(status)) {
1813 dataerrln("Couldn't create calendar.: %s", u_errorName(status));
1814 return;
1815 }
1816 calendar->set(1998, UCAL_MARCH, 1);
1817 calendar->setMinimalDaysInFirstWeek(1);
1818 logln(UnicodeString("Date: ") + calendar->getTime(status)); // 888817448000
1819
1820 int32_t firstInMonth = calendar->get(UCAL_DATE, status);
1821 if(U_FAILURE(status))
1822 errln("get(D_O_M) failed");
1823
1824 for(int32_t firstInWeek = UCAL_SUNDAY; firstInWeek <= UCAL_SATURDAY; firstInWeek++) {
1825 calendar->setFirstDayOfWeek((UCalendarDaysOfWeek)firstInWeek);
1826 int32_t returned = calendar->getActualMaximum(field, status);
1827 int32_t expected = (31 + ((firstInMonth - firstInWeek + 7)% 7) + 6) / 7;
1828
1829 logln(UnicodeString("First day of week = ") + firstInWeek +
1830 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned +
1831 " expected = " + expected +
1832 ((returned == expected) ? " ok" : " FAIL"));
1833
1834 if (returned != expected) {
1835 passed = FALSE;
1836 }
1837 }
1838 if (!passed) {
1839 errln("Test failed");
1840 }
1841
1842 delete calendar;
1843 }
1844
1845 /**
1846 * @bug 4167060
1847 * Calendar.getActualMaximum(YEAR) works wrong.
1848 */
1849 void
Test4167060()1850 CalendarRegressionTest::Test4167060()
1851 {
1852 UErrorCode status = U_ZERO_ERROR;
1853 UCalendarDateFields field = UCAL_YEAR;
1854 DateFormat *format = new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy G"),
1855 Locale::getUS(), status);
1856 if(U_FAILURE(status)) {
1857 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status));
1858 return;
1859 }
1860
1861 GregorianCalendar *calendars [] = {
1862 new GregorianCalendar(100, UCAL_NOVEMBER, 1, status),
1863 new GregorianCalendar(-99 /*100BC*/, UCAL_JANUARY, 1, status),
1864 new GregorianCalendar(1996, UCAL_FEBRUARY, 29, status),
1865 };
1866 if(U_FAILURE(status)) {
1867 errln("Couldn't create GregorianCalendars");
1868 return;
1869 // could leak
1870 }
1871
1872 UnicodeString id [] = { "Hybrid", "Gregorian", "Julian" };
1873
1874 for (int32_t k=0; k<3; ++k) {
1875 logln("--- " + id[k] + " ---");
1876
1877 for (int32_t j=0; j < 3; ++j) {
1878 GregorianCalendar *calendar = calendars[j];
1879 if (k == 1) {
1880 calendar->setGregorianChange(EARLIEST_SUPPORTED_MILLIS, status);
1881 }
1882 else if (k == 2) {
1883 calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status);
1884 }
1885
1886 if(U_FAILURE(status))
1887 errln("setGregorianChange() failed");
1888 format->adoptCalendar((Calendar*)calendar->clone());
1889
1890 UDate dateBefore = calendar->getTime(status);
1891 if(U_FAILURE(status))
1892 errln("getTime() failed");
1893
1894 int32_t maxYear = calendar->getActualMaximum(field, status);
1895 UnicodeString temp;
1896 logln(UnicodeString("maxYear: ") + maxYear + " for " + format->format(calendar->getTime(status), temp));
1897 temp.remove();
1898 logln("date before: " + format->format(dateBefore, temp));
1899
1900 int32_t years[] = {2000, maxYear-1, maxYear, maxYear+1};
1901
1902 for (int32_t i = 0; i < 4; i++) {
1903 UBool valid = years[i] <= maxYear;
1904 calendar->set(field, years[i]);
1905 UDate dateAfter = calendar->getTime(status);
1906 if(U_FAILURE(status))
1907 errln("getTime() failed");
1908 int32_t newYear = calendar->get(field, status);
1909 if(U_FAILURE(status))
1910 errln(UnicodeString("get(") + (int32_t)field + ") failed");
1911 calendar->setTime(dateBefore, status); // restore calendar for next use
1912 if(U_FAILURE(status))
1913 errln("setTime() failed");
1914
1915 temp.remove();
1916 logln(UnicodeString(" Year ") + years[i] + (valid? " ok " : " bad") +
1917 " => " + format->format(dateAfter, temp));
1918 if (valid && newYear != years[i]) {
1919 errln(UnicodeString(" FAIL: ") + newYear + " should be valid; date, month and time shouldn't change");
1920 }
1921 // {sfb} this next line is a hack, but it should work since if a
1922 // double has an exponent, adding 1 should not yield the same double
1923 else if (!valid && /*newYear == years[i]*/ dateAfter + 1.0 == dateAfter) {
1924 errln(UnicodeString(" FAIL: ") + newYear + " should be invalid");
1925 }
1926 }
1927 }
1928 }
1929
1930 delete format;
1931 delete calendars[0];
1932 delete calendars[1];
1933 delete calendars[2];
1934 }
1935
1936 /**
1937 * Week of year is wrong at the start and end of the year.
1938 */
Test4197699()1939 void CalendarRegressionTest::Test4197699() {
1940 UErrorCode status = U_ZERO_ERROR;
1941 GregorianCalendar cal(status);
1942 cal.setFirstDayOfWeek(UCAL_MONDAY);
1943 cal.setMinimalDaysInFirstWeek(4);
1944 SimpleDateFormat fmt("E dd MMM yyyy 'DOY='D 'WOY='w",
1945 Locale::getUS(), status);
1946 fmt.setCalendar(cal);
1947 if (U_FAILURE(status)) {
1948 dataerrln("Couldn't initialize test - %s", u_errorName(status));
1949 return;
1950 }
1951
1952 int32_t DATA[] = {
1953 2000, UCAL_JANUARY, 1, 52,
1954 2001, UCAL_DECEMBER, 31, 1,
1955 };
1956 int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
1957
1958 UnicodeString str;
1959 DateFormat& dfmt = *(DateFormat*)&fmt;
1960 for (int32_t i=0; i<DATA_length; ) {
1961 cal.clear();
1962 cal.set(DATA[i], DATA[i+1], DATA[i+2]);
1963 i += 3;
1964 int32_t expWOY = DATA[i++];
1965 int32_t actWOY = cal.get(UCAL_WEEK_OF_YEAR, status);
1966 if (expWOY == actWOY) {
1967 logln(UnicodeString("Ok: ") + dfmt.format(cal.getTime(status), str.remove()));
1968 } else {
1969 errln(UnicodeString("FAIL: ") + dfmt.format(cal.getTime(status), str.remove())
1970 + ", expected WOY=" + expWOY);
1971 cal.add(UCAL_DATE, -8, status);
1972 for (int j=0; j<14; ++j) {
1973 cal.add(UCAL_DATE, 1, status);
1974 logln(dfmt.format(cal.getTime(status), str.remove()));
1975 }
1976 }
1977 if (U_FAILURE(status)) {
1978 errln("FAIL: Unexpected error from Calendar");
1979 return;
1980 }
1981 }
1982 }
1983
1984 enum Action { ADD=1, ROLL=2 };
1985 enum Sign { PLUS=1, MINUS=2 };
1986
1987 #define ONE_HOUR (60*60*1000)
1988 #define ONE_DAY (24*ONE_HOUR)
1989
1990 typedef struct {
1991 UCalendarDateFields field;
1992 int8_t actionMask; // ADD or ROLL or both
1993 int8_t signMask; // PLUS or MINUS or both
1994 int32_t amount;
1995 int32_t before; // ms before cutover
1996 int32_t after; // ms after cutover
1997 } J81_DATA;
1998
1999 /**
2000 * Rolling and adding across the Gregorian cutover should work as expected.
2001 * Jitterbug 81.
2002 */
TestJ81()2003 void CalendarRegressionTest::TestJ81() {
2004 UErrorCode status = U_ZERO_ERROR;
2005 UnicodeString temp, temp2, temp3;
2006 int32_t i;
2007 GregorianCalendar cal(TimeZone::createTimeZone("GMT"), Locale::getUS(), status);
2008 SimpleDateFormat fmt("HH:mm 'w'w 'd'D E d MMM yyyy", Locale::getUS(), status);
2009 if (U_FAILURE(status)) {
2010 dataerrln("Error: Cannot create calendar or format - %s", u_errorName(status));
2011 return;
2012 }
2013 fmt.setCalendar(cal);
2014 // Get the Gregorian cutover
2015 UDate cutover = cal.getGregorianChange();
2016 UDate days = ONE_DAY;
2017 days = cutover/days;
2018 logln(UnicodeString("Cutover: {") +
2019 fmt.format(cutover, temp) + "}(epoch days-" + (int)days + ", jd" + (2440588 + days) +")");
2020
2021 // Check woy and doy handling. Reference data:
2022 /* w40 d274 Mon 1 Oct 1582
2023 w40 d275 Tue 2 Oct 1582
2024 w40 d276 Wed 3 Oct 1582
2025 w40 d277 Thu 4 Oct 1582
2026 w40 d278 Fri 15 Oct 1582
2027 w40 d279 Sat 16 Oct 1582
2028 w41 d280 Sun 17 Oct 1582
2029 w41 d281 Mon 18 Oct 1582
2030 w41 d282 Tue 19 Oct 1582
2031 w41 d283 Wed 20 Oct 1582
2032 w41 d284 Thu 21 Oct 1582
2033 w41 d285 Fri 22 Oct 1582
2034 w41 d286 Sat 23 Oct 1582
2035 w42 d287 Sun 24 Oct 1582
2036 w42 d288 Mon 25 Oct 1582
2037 w42 d289 Tue 26 Oct 1582
2038 w42 d290 Wed 27 Oct 1582
2039 w42 d291 Thu 28 Oct 1582
2040 w42 d292 Fri 29 Oct 1582
2041 w42 d293 Sat 30 Oct 1582
2042 w43 d294 Sun 31 Oct 1582
2043 w43 d295 Mon 1 Nov 1582 */
2044 int32_t DOY_DATA[] = {
2045 // dom, woy, doy
2046 1, 40, 274, UCAL_MONDAY,
2047 4, 40, 277, UCAL_THURSDAY,
2048 15, 40, 278, UCAL_FRIDAY,
2049 17, 41, 280, UCAL_SUNDAY,
2050 24, 42, 287, UCAL_SUNDAY,
2051 25, 42, 288, UCAL_MONDAY,
2052 26, 42, 289, UCAL_TUESDAY,
2053 27, 42, 290, UCAL_WEDNESDAY,
2054 28, 42, 291, UCAL_THURSDAY,
2055 29, 42, 292, UCAL_FRIDAY,
2056 30, 42, 293, UCAL_SATURDAY,
2057 31, 43, 294, UCAL_SUNDAY
2058 };
2059 int32_t DOY_DATA_length = (int32_t)(sizeof(DOY_DATA) / sizeof(DOY_DATA[0]));
2060
2061 for (i=0; i<DOY_DATA_length; i+=4) {
2062 // Test time->fields
2063 cal.set(1582, UCAL_OCTOBER, DOY_DATA[i]);
2064 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
2065 int32_t doy = cal.get(UCAL_DAY_OF_YEAR, status);
2066 int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status);
2067 if (U_FAILURE(status)) {
2068 errln("Error: get() failed");
2069 break;
2070 }
2071 if (woy != DOY_DATA[i+1] || doy != DOY_DATA[i+2] || dow != DOY_DATA[i+3]) {
2072 errln((UnicodeString)"Fail: expect woy=" + DOY_DATA[i+1] +
2073 ", doy=" + DOY_DATA[i+2] + ", dow=" + DOY_DATA[i+3] + " on " +
2074 fmt.format(cal.getTime(status), temp.remove()) +
2075 " set(1582,OCTOBER, " + DOY_DATA[i] + ")");
2076 logln(CalendarTest::calToStr(cal));
2077 status = U_ZERO_ERROR;
2078 } else {
2079 logln((UnicodeString)"PASS: expect woy=" + DOY_DATA[i+1] +
2080 ", doy=" + DOY_DATA[i+2] + ", dow=" + DOY_DATA[i+3] + " on " +
2081 fmt.format(cal.getTime(status), temp.remove()));
2082 logln(CalendarTest::calToStr(cal));
2083 status = U_ZERO_ERROR;
2084 }
2085 // Test fields->time for WOY
2086 cal.clear();
2087 cal.set(UCAL_YEAR, 1582);
2088 cal.set(UCAL_WEEK_OF_YEAR, DOY_DATA[i+1]);
2089 cal.set(UCAL_DAY_OF_WEEK, DOY_DATA[i+3]);
2090 int32_t dom = cal.get(UCAL_DATE, status);
2091 if (U_FAILURE(status)) {
2092 errln("Error: get() failed");
2093 break;
2094 }
2095 if (dom != DOY_DATA[i]) {
2096 errln((UnicodeString)"Fail: set woy=" + DOY_DATA[i+1] +
2097 " dow=" + DOY_DATA[i+3] + " => " +
2098 fmt.format(cal.getTime(status), temp.remove()) +
2099 ", expected 1582 Oct " + DOY_DATA[i]);
2100 logln(CalendarTest::calToStr(cal));
2101 status = U_ZERO_ERROR;
2102 }
2103
2104 // Test fields->time for DOY
2105 cal.clear();
2106 cal.set(UCAL_YEAR, 1582);
2107 cal.set(UCAL_DAY_OF_YEAR, DOY_DATA[i+2]);
2108 dom = cal.get(UCAL_DATE, status);
2109 if (U_FAILURE(status)) {
2110 errln("Error: get() failed");
2111 break;
2112 }
2113 if (dom != DOY_DATA[i]) {
2114 errln((UnicodeString)"Fail: set doy=" + DOY_DATA[i+2] +
2115 " => " +
2116 fmt.format(cal.getTime(status), temp.remove()) +
2117 ", expected 1582 Oct " + DOY_DATA[i]);
2118 status = U_ZERO_ERROR;
2119 }
2120 }
2121 status = U_ZERO_ERROR;
2122
2123 #define ADD_ROLL ADD|ROLL
2124 #define PLUS_MINUS PLUS|MINUS
2125 // Test cases
2126 J81_DATA DATA[] = {
2127 { UCAL_WEEK_OF_YEAR, ADD_ROLL, PLUS_MINUS, 1, -ONE_DAY, +6*ONE_DAY },
2128 { UCAL_WEEK_OF_YEAR, ADD_ROLL, PLUS_MINUS, 1, -ONE_DAY, +6*ONE_DAY },
2129 { UCAL_WEEK_OF_MONTH, ADD|ROLL, PLUS|MINUS, 1, -ONE_DAY, +6*ONE_DAY },
2130 { UCAL_DATE, ADD|ROLL, PLUS|MINUS, 2, -ONE_DAY, +1*ONE_DAY },
2131 { UCAL_DATE, ROLL, PLUS, -6, -ONE_DAY, +14*ONE_DAY },
2132 { UCAL_DATE, ROLL, PLUS, -7, 0, +14*ONE_DAY },
2133 { UCAL_DATE, ROLL, PLUS, -7, +ONE_DAY, +15*ONE_DAY },
2134 { UCAL_DATE, ROLL, PLUS, +18, -ONE_DAY, -4*ONE_DAY },
2135 { UCAL_DAY_OF_YEAR, ADD|ROLL, PLUS|MINUS, 2, -ONE_DAY, +1*ONE_DAY },
2136 { UCAL_DAY_OF_WEEK, ADD|ROLL, PLUS|MINUS, 2, -ONE_DAY, +1*ONE_DAY },
2137 { UCAL_DAY_OF_WEEK_IN_MONTH, ADD|ROLL, PLUS|MINUS, 1, -ONE_DAY, +6*ONE_DAY },
2138 { UCAL_AM_PM, ADD, PLUS|MINUS, 4, -12*ONE_HOUR, +36*ONE_HOUR },
2139 { UCAL_HOUR, ADD, PLUS|MINUS, 48, -12*ONE_HOUR, +36*ONE_HOUR },
2140 { UCAL_HOUR_OF_DAY, ADD, PLUS|MINUS, 48, -12*ONE_HOUR, +36*ONE_HOUR },
2141 { UCAL_MINUTE, ADD, PLUS|MINUS, 48*60, -12*ONE_HOUR, +36*ONE_HOUR },
2142 { UCAL_SECOND, ADD, PLUS|MINUS, 48*60*60, -12*ONE_HOUR, +36*ONE_HOUR },
2143 { UCAL_MILLISECOND, ADD, PLUS|MINUS, 48*ONE_HOUR, -12*ONE_HOUR, +36*ONE_HOUR },
2144 // NOTE: These are not supported yet. See jitterbug 180.
2145 // Uncomment these lines when add/roll supported on these fields.
2146 // { Calendar::YEAR_WOY, ADD|ROLL, 1, -ONE_DAY, +6*ONE_DAY },
2147 // { Calendar::DOW_LOCAL, ADD|ROLL, 2, -ONE_DAY, +1*ONE_DAY }
2148 };
2149 int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
2150
2151 // Now run the tests
2152 for (i=0; i<DATA_length; ++i) {
2153 for (Action action=ADD; action<=ROLL; action=(Action)(action+1)) {
2154 if (!(DATA[i].actionMask & action)) {
2155 continue;
2156 }
2157 for (Sign sign=PLUS; sign<=MINUS; sign=(Sign)(sign+1)) {
2158 if (!(DATA[i].signMask & sign)) {
2159 continue;
2160 }
2161 status = U_ZERO_ERROR;
2162 int32_t amount = DATA[i].amount * (sign==MINUS?-1:1);
2163 UDate date = cutover +
2164 (sign==PLUS ? DATA[i].before : DATA[i].after);
2165 UDate expected = cutover +
2166 (sign==PLUS ? DATA[i].after : DATA[i].before);
2167 cal.setTime(date, status);
2168 if (U_FAILURE(status)) {
2169 errln((UnicodeString)"FAIL: setTime returned error code " + u_errorName(status));
2170 continue;
2171 }
2172 if (action == ADD) {
2173 cal.add(DATA[i].field, amount, status);
2174 } else {
2175 cal.roll(DATA[i].field, amount, status);
2176 }
2177 if (U_FAILURE(status)) {
2178 errln((UnicodeString)"FAIL: " +
2179 (action==ADD?"add ":"roll ") + FIELD_NAME[DATA[i].field] +
2180 " returned error code " + u_errorName(status));
2181 continue;
2182 }
2183 UDate result = cal.getTime(status);
2184 if (U_FAILURE(status)) {
2185 errln((UnicodeString)"FAIL: getTime returned error code " + u_errorName(status));
2186 continue;
2187 }
2188 if (result == expected) {
2189 logln((UnicodeString)"Ok: {" +
2190 fmt.format(date, temp.remove()) +
2191 "}(" + date/ONE_DAY +
2192 (action==ADD?") add ":") roll ") +
2193 amount + " " + FIELD_NAME[DATA[i].field] + " -> {" +
2194 fmt.format(result, temp2.remove()) +
2195 "}(" + result/ONE_DAY + ")");
2196 } else {
2197 errln((UnicodeString)"FAIL: {" +
2198 fmt.format(date, temp.remove()) +
2199 "}(" + date/ONE_DAY +
2200 (action==ADD?") add ":") roll ") +
2201 amount + " " + FIELD_NAME[DATA[i].field] + " -> {" +
2202 fmt.format(result, temp2.remove()) +
2203 "}(" + result/ONE_DAY + "), expect {" +
2204 fmt.format(expected, temp3.remove()) +
2205 "}(" + expected/ONE_DAY + ")");
2206 }
2207 }
2208 }
2209 }
2210 }
2211
2212 /**
2213 * Test fieldDifference().
2214 */
TestJ438(void)2215 void CalendarRegressionTest::TestJ438(void) {
2216 UErrorCode ec = U_ZERO_ERROR;
2217 int32_t DATA[] = {
2218 2000, UCAL_JANUARY, 20, 2010, UCAL_JUNE, 15,
2219 2010, UCAL_JUNE, 15, 2000, UCAL_JANUARY, 20,
2220 1964, UCAL_SEPTEMBER, 7, 1999, UCAL_JUNE, 4,
2221 1999, UCAL_JUNE, 4, 1964, UCAL_SEPTEMBER, 7,
2222 };
2223 int32_t DATA_length = (int32_t)(sizeof(DATA)/sizeof(DATA[0]));
2224 Calendar* pcal = Calendar::createInstance(Locale::getUS(), ec);
2225 if(U_FAILURE(ec)) {
2226 dataerrln("Error creating calendar %s", u_errorName(ec));
2227 delete pcal;
2228 return;
2229 }
2230 Calendar& cal = *pcal;
2231 int32_t i;
2232 SimpleDateFormat fmt(UnicodeString("MMM dd yyyy",""), ec);
2233 fmt.setCalendar(cal);
2234 UnicodeString s, t, u;
2235 if (!failure(ec, "setup")) {
2236 for (i=0; i<DATA_length; i+=6) {
2237 int32_t y1 = DATA[i];
2238 int32_t m1 = DATA[i+1];
2239 int32_t d1 = DATA[i+2];
2240 int32_t y2 = DATA[i+3];
2241 int32_t m2 = DATA[i+4];
2242 int32_t d2 = DATA[i+5];
2243
2244 cal.clear();
2245 cal.set(y1, m1, d1);
2246 UDate date1 = cal.getTime(ec);
2247 if (failure(ec, "getTime"))
2248 break;
2249 cal.set(y2, m2, d2);
2250 UDate date2 = cal.getTime(ec);
2251 if (failure(ec, "getTime"))
2252 break;
2253
2254 cal.setTime(date1, ec);
2255 if (failure(ec, "setTime"))
2256 break;
2257 int32_t dy = cal.fieldDifference(date2, UCAL_YEAR, ec);
2258 int32_t dm = cal.fieldDifference(date2, UCAL_MONTH, ec);
2259 int32_t dd = cal.fieldDifference(date2, UCAL_DATE, ec);
2260 if (failure(ec, "fieldDifference"))
2261 break;
2262
2263 {
2264 Calendar *cal2 = cal.clone();
2265 UErrorCode ec2 = U_ZERO_ERROR;
2266
2267 cal2->setTime(date1, ec2);
2268
2269 int32_t dy2 = cal2->fieldDifference(date2, Calendar::YEAR, ec2);
2270 int32_t dm2 = cal2->fieldDifference(date2, Calendar::MONTH, ec2);
2271 int32_t dd2 = cal2->fieldDifference(date2, Calendar::DATE, ec2);
2272 if (failure(ec2, "fieldDifference(date, Calendar::DATE, ec)"))
2273 break;
2274 if( (dd2 != dd) ||
2275 (dm2 != dm) ||
2276 (dy2 != dy)){
2277 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n");
2278 }
2279 delete cal2;
2280 }
2281
2282
2283 logln(UnicodeString("") +
2284 fmt.format(date2, s.remove()) + " - " +
2285 fmt.format(date1, t.remove()) + " = " +
2286 dy + "y " + dm + "m " + dd + "d");
2287
2288 cal.setTime(date1, ec);
2289 if (failure(ec, "setTime"))
2290 break;
2291 cal.add(UCAL_YEAR, dy, ec);
2292 cal.add(UCAL_MONTH, dm, ec);
2293 cal.add(UCAL_DATE, dd, ec);
2294 if (failure(ec, "add"))
2295 break;
2296 UDate date22 = cal.getTime(ec);
2297 if (failure(ec, "getTime"))
2298 break;
2299 if (date2 != date22) {
2300 errln(UnicodeString("FAIL: ") +
2301 fmt.format(date1, s.remove()) + " + " +
2302 dy + "y " + dm + "m " + dd + "d = " +
2303 fmt.format(date22, t.remove()) + ", exp " +
2304 fmt.format(date2, u.remove()));
2305 } else {
2306 logln(UnicodeString("Ok: ") +
2307 fmt.format(date1, s.remove()) + " + " +
2308 dy + "y " + dm + "m " + dd + "d = " +
2309 fmt.format(date22, t.remove()));
2310 }
2311 }
2312 }
2313 delete pcal;
2314 }
2315
TestT5555()2316 void CalendarRegressionTest::TestT5555()
2317 {
2318 UErrorCode ec = U_ZERO_ERROR;
2319 Calendar *cal = Calendar::createInstance(ec);
2320
2321 if (cal == NULL || U_FAILURE(ec)) {
2322 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec));
2323 delete cal;
2324 return;
2325 }
2326
2327 // Set to Wednesday, February 21, 2007
2328 cal->set(2007, UCAL_FEBRUARY, 21);
2329
2330 // Advance three years
2331 cal->add(UCAL_MONTH, 36, ec);
2332
2333 // Set to last Wednesday of the month
2334 cal->set(UCAL_DAY_OF_WEEK_IN_MONTH, -1);
2335
2336 cal->getTime(ec);
2337
2338 int32_t yy, mm, dd, ee;
2339
2340 yy = cal->get(UCAL_YEAR, ec);
2341 mm = cal->get(UCAL_MONTH, ec);
2342 dd = cal->get(UCAL_DATE, ec);
2343 ee = cal->get(UCAL_DAY_OF_WEEK, ec);
2344
2345 // Should be set to Wednesday, February 24, 2010
2346 if (U_FAILURE(ec) || yy != 2010 || mm != UCAL_FEBRUARY || dd != 24 || ee != UCAL_WEDNESDAY) {
2347 errln("FAIL: got date %4d/%02d/%02d, expected 210/02/24: ", yy, mm + 1, dd);
2348 }
2349 delete cal;
2350 }
2351
2352 typedef struct {
2353 int32_t startYear;
2354 int32_t startMonth; // 0-based
2355 int32_t startDay; // 1-based
2356 UCalendarDateFields fieldToChange;
2357 int32_t fieldDelta;
2358 int32_t endYear;
2359 int32_t endMonth; // 0-based
2360 int32_t endDay; // 1-based
2361 } CoptEthCalTestItem;
2362
2363 // year 1724 in coptic calendar =
2364 // year 2000 in ethiopic calendar (276 more than coptic) =
2365 // year 7500 in ethiopic-amete-alem calendar (5776 more than coptic)
2366 // (2007-2008 in gregorian calendar depending on month)
2367 static const CoptEthCalTestItem coptEthCalTestItems[] = {
2368 { 1724, 12, 1, UCAL_MONTH, +1, 1725, 0, 1 },
2369 { 1724, 12, 1, UCAL_MONTH, +9, 1725, 8, 1 },
2370 { 1723, 12, 2, UCAL_MONTH, +1, 1724, 0, 2 }, // 1723 is a leap year
2371 { 1723, 12, 2, UCAL_MONTH, +9, 1724, 8, 2 },
2372 { 1725, 0, 1, UCAL_MONTH, -1, 1724, 12, 1 },
2373 { 1725, 0, 1, UCAL_MONTH, -6, 1724, 7, 1 },
2374 { 1724, 12, 1, UCAL_DATE, +8, 1725, 0, 4 },
2375 { 1723, 12, 1, UCAL_DATE, +8, 1724, 0, 3 }, // 1723 is a leap year
2376 { 1724, 0, 1, UCAL_DATE, -1, 1723, 12, 6 }, // 1723 is a leap year
2377 { 0, 0, 0, (UCalendarDateFields)0, 0, 0, 0, 0 } // terminator
2378 };
2379
2380 typedef struct {
2381 const char * locale;
2382 int32_t yearOffset;
2383 } CoptEthCalLocale;
2384
2385 static const CoptEthCalLocale copEthCalLocales[] = {
2386 { "en@calendar=coptic", 0 },
2387 { "en@calendar=ethiopic", 276 },
2388 { NULL, 0 } // terminator
2389 };
2390
TestT6745()2391 void CalendarRegressionTest::TestT6745()
2392 {
2393 const CoptEthCalLocale * testLocalePtr;
2394 for ( testLocalePtr = copEthCalLocales; testLocalePtr->locale != NULL; ++testLocalePtr) {
2395 UErrorCode status = U_ZERO_ERROR;
2396 Calendar *cal = Calendar::createInstance(Locale(testLocalePtr->locale), status);
2397 if ( U_FAILURE(status) ) {
2398 dataerrln((UnicodeString)"FAIL: Calendar::createInstance, locale " + testLocalePtr->locale + ", status " + u_errorName(status));
2399 continue;
2400 }
2401 const CoptEthCalTestItem * testItemPtr;
2402 for (testItemPtr = coptEthCalTestItems; testItemPtr->fieldDelta != 0; ++testItemPtr) {
2403 status = U_ZERO_ERROR;
2404 cal->set( testItemPtr->startYear + testLocalePtr->yearOffset, testItemPtr->startMonth, testItemPtr->startDay, 9, 0 );
2405 cal->add( testItemPtr->fieldToChange, testItemPtr->fieldDelta, status );
2406 if ( U_FAILURE(status) ) {
2407 errln((UnicodeString)"FAIL: Calendar::add, locale " + testLocalePtr->locale + ", field/delta " +
2408 testItemPtr->fieldToChange + "/" + testItemPtr->fieldDelta + ", status " + u_errorName(status));
2409 continue;
2410 }
2411 int32_t endYear = testItemPtr->endYear + testLocalePtr->yearOffset;
2412 int32_t year = cal->get(UCAL_YEAR, status);
2413 int32_t month = cal->get(UCAL_MONTH, status);
2414 int32_t day = cal->get(UCAL_DATE, status);
2415 if ( U_FAILURE(status) || year != endYear || month != testItemPtr->endMonth || day != testItemPtr->endDay ) {
2416 errln((UnicodeString)"ERROR: Calendar::add, locale " + testLocalePtr->locale + ", field/delta " +
2417 testItemPtr->fieldToChange + "/" + testItemPtr->fieldDelta + ", status " + u_errorName(status) +
2418 ", expected " + endYear + "/" + testItemPtr->endMonth + "/" + testItemPtr->endDay +
2419 ", got " + year + "/" + month + "/" + day );
2420 }
2421 }
2422 delete cal;
2423 }
2424 }
2425
2426 /**
2427 * Test behavior of fieldDifference around leap years. Also test a large
2428 * field difference to check binary search.
2429 */
TestLeapFieldDifference()2430 void CalendarRegressionTest::TestLeapFieldDifference() {
2431 UErrorCode ec = U_ZERO_ERROR;
2432 Calendar* cal = Calendar::createInstance(ec);
2433 if (cal == NULL || U_FAILURE(ec)) {
2434 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec));
2435 delete cal;
2436 return;
2437 }
2438 cal->set(2004, UCAL_FEBRUARY, 29);
2439 UDate date2004 = cal->getTime(ec);
2440 cal->set(2000, UCAL_FEBRUARY, 29);
2441 UDate date2000 = cal->getTime(ec);
2442 if (U_FAILURE(ec)) {
2443 errln("FAIL: getTime()");
2444 delete cal;
2445 return;
2446 }
2447 int32_t y = cal->fieldDifference(date2004, UCAL_YEAR, ec);
2448 int32_t d = cal->fieldDifference(date2004, UCAL_DAY_OF_YEAR, ec);
2449 if (U_FAILURE(ec)) {
2450 errln("FAIL: fieldDifference()");
2451 delete cal;
2452 return;
2453 }
2454 if (d == 0) {
2455 logln((UnicodeString)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y + " years, " + d + " days");
2456 } else {
2457 errln((UnicodeString)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y + " years, " + d + " days");
2458 }
2459 cal->setTime(date2004, ec);
2460 y = cal->fieldDifference(date2000, UCAL_YEAR, ec);
2461 d = cal->fieldDifference(date2000, UCAL_DAY_OF_YEAR, ec);
2462 if (U_FAILURE(ec)) {
2463 errln("FAIL: setTime() / fieldDifference()");
2464 delete cal;
2465 return;
2466 }
2467 if (d == 0) {
2468 logln((UnicodeString)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y + " years, " + d + " days");
2469 } else {
2470 errln((UnicodeString)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y + " years, " + d + " days");
2471 }
2472 // Test large difference
2473 cal->set(2001, UCAL_APRIL, 5); // 2452005
2474 UDate ayl = cal->getTime(ec);
2475 cal->set(1964, UCAL_SEPTEMBER, 7); // 2438646
2476 UDate asl = cal->getTime(ec);
2477 if (U_FAILURE(ec)) {
2478 errln("FAIL: getTime()");
2479 delete cal;
2480 return;
2481 }
2482 d = cal->fieldDifference(ayl, UCAL_DATE, ec);
2483 cal->setTime(ayl, ec);
2484 int32_t d2 = cal->fieldDifference(asl, UCAL_DATE, ec);
2485 if (U_FAILURE(ec)) {
2486 errln("FAIL: setTime() / fieldDifference()");
2487 delete cal;
2488 return;
2489 }
2490 if (d == -d2 && d == 13359) {
2491 logln((UnicodeString)"Ok: large field difference symmetrical " + d);
2492 } else {
2493 logln((UnicodeString)"FAIL: large field difference incorrect " + d + ", " + d2 +
2494 ", expect +/- 13359");
2495 }
2496 delete cal;
2497 }
2498
2499 /**
2500 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543.
2501 */
TestMalaysianInstance()2502 void CalendarRegressionTest::TestMalaysianInstance() {
2503 Locale loc("ms", "MY"); // Malay (Malaysia)
2504 UErrorCode ec = U_ZERO_ERROR;
2505 Calendar* cal = Calendar::createInstance(loc, ec);
2506 if (U_FAILURE(ec)) {
2507 dataerrln("FAIL: Can't construct calendar for ms_MY: %s", u_errorName(ec));
2508 }
2509 delete cal;
2510 }
2511
2512 /**
2513 * setFirstDayOfWeek and setMinimalDaysInFirstWeek may change the
2514 * field <=> time mapping, since they affect the interpretation of
2515 * the WEEK_OF_MONTH or WEEK_OF_YEAR fields.
2516 */
TestWeekShift()2517 void CalendarRegressionTest::TestWeekShift() {
2518 UErrorCode ec = U_ZERO_ERROR;
2519 GregorianCalendar cal(TimeZone::createTimeZone("America/Los_Angeles"),
2520 Locale("en", "US"), ec);
2521 if (U_FAILURE(ec)) {
2522 dataerrln("Fail GregorianCalendar: %s", u_errorName(ec));
2523 return;
2524 }
2525 cal.setTime(UDate(997257600000.0), ec); // Wed Aug 08 01:00:00 PDT 2001
2526 // In pass one, change the first day of week so that the weeks
2527 // shift in August 2001. In pass two, change the minimal days
2528 // in the first week so that the weeks shift in August 2001.
2529 // August 2001
2530 // Su Mo Tu We Th Fr Sa
2531 // 1 2 3 4
2532 // 5 6 7 8 9 10 11
2533 // 12 13 14 15 16 17 18
2534 // 19 20 21 22 23 24 25
2535 // 26 27 28 29 30 31
2536 for (int32_t pass=0; pass<2; ++pass) {
2537 if (pass==0) {
2538 cal.setFirstDayOfWeek(UCAL_WEDNESDAY);
2539 cal.setMinimalDaysInFirstWeek(4);
2540 } else {
2541 cal.setFirstDayOfWeek(UCAL_SUNDAY);
2542 cal.setMinimalDaysInFirstWeek(4);
2543 }
2544 cal.add(UCAL_DATE, 1, ec); // Force recalc
2545 cal.add(UCAL_DATE, -1, ec);
2546
2547 UDate time1 = cal.getTime(ec); // Get time -- should not change
2548
2549 // Now change a week parameter and then force a recalc.
2550 // The bug is that the recalc should not be necessary --
2551 // calendar should do so automatically.
2552 if (pass==0) {
2553 cal.setFirstDayOfWeek(UCAL_THURSDAY);
2554 } else {
2555 cal.setMinimalDaysInFirstWeek(5);
2556 }
2557
2558 int32_t woy1 = cal.get(UCAL_WEEK_OF_YEAR, ec);
2559 int32_t wom1 = cal.get(UCAL_WEEK_OF_MONTH, ec);
2560
2561 cal.add(UCAL_DATE, 1, ec); // Force recalc
2562 cal.add(UCAL_DATE, -1, ec);
2563
2564 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, ec);
2565 int32_t wom2 = cal.get(UCAL_WEEK_OF_MONTH, ec);
2566
2567 UDate time2 = cal.getTime(ec);
2568
2569 if (U_FAILURE(ec)) {
2570 errln("FAIL: internal test error");
2571 return;
2572 }
2573
2574 if (time1 != time2) {
2575 errln("FAIL: shifting week should not alter time");
2576 } else {
2577 // logln(time1);
2578 }
2579 if (woy1 == woy2 && wom1 == wom2) {
2580 logln((UnicodeString)"Ok: WEEK_OF_YEAR: " + woy1 +
2581 ", WEEK_OF_MONTH: " + wom1);
2582 } else {
2583 errln((UnicodeString)"FAIL: WEEK_OF_YEAR: " + woy1 + " => " + woy2 +
2584 ", WEEK_OF_MONTH: " + wom1 + " => " + wom2 +
2585 " after week shift");
2586 }
2587 }
2588 }
2589
2590 /**
2591 * Make sure that when adding a day, we actually wind up in a
2592 * different day. The DST adjustments we use to keep the hour
2593 * constant across DST changes can backfire and change the day.
2594 */
TestTimeZoneTransitionAdd()2595 void CalendarRegressionTest::TestTimeZoneTransitionAdd() {
2596 UErrorCode ec = U_ZERO_ERROR;
2597 Locale locale(Locale::getUS()); // could also be CHINA
2598 SimpleDateFormat dateFormat("MM/dd/yyyy HH:mm z", locale, ec);
2599
2600 StringEnumeration *tz = TimeZone::createEnumeration();
2601 if (tz == NULL) {
2602 dataerrln("FAIL: TimeZone::createEnumeration");
2603 return;
2604 }
2605
2606 UnicodeString buf1, buf2;
2607
2608 const UChar* id;
2609 while ((id = tz->unext(NULL, ec)) != NULL && U_SUCCESS(ec)) {
2610 if (U_FAILURE(ec)) {
2611 errln("FAIL: StringEnumeration::unext");
2612 break;
2613 }
2614
2615 TimeZone *t = TimeZone::createTimeZone(id);
2616 if (t == NULL) {
2617 errln("FAIL: TimeZone::createTimeZone");
2618 break;
2619 }
2620 dateFormat.setTimeZone(*t);
2621
2622 Calendar *cal = Calendar::createInstance(t, locale, ec);
2623 if (cal == NULL || U_FAILURE(ec)) {
2624 errln("FAIL: Calendar::createTimeZone");
2625 delete cal;
2626 break;
2627 }
2628
2629 cal->clear();
2630 // Scan the year 2003, overlapping the edges of the year
2631 cal->set(UCAL_YEAR, 2002);
2632 cal->set(UCAL_MONTH, UCAL_DECEMBER);
2633 cal->set(UCAL_DATE, 25);
2634
2635 for (int32_t i=0; i<365+10 && U_SUCCESS(ec); ++i) {
2636 UDate yesterday = cal->getTime(ec);
2637 int32_t yesterday_day = cal->get(UCAL_DATE, ec);
2638 cal->add(UCAL_DATE, 1, ec);
2639 if (yesterday_day == cal->get(UCAL_DATE, ec)) {
2640 errln(UnicodeString(id) + " " +
2641 dateFormat.format(yesterday, buf1) + " +1d= " +
2642 dateFormat.format(cal->getTime(ec), buf2));
2643 buf1.truncate(0);
2644 buf2.truncate(0);
2645 }
2646 }
2647 delete cal;
2648 }
2649
2650 if (U_FAILURE(ec)) {
2651 dataerrln("FAIL: %s", u_errorName(ec));
2652 }
2653
2654 delete tz;
2655 }
2656
2657 UDate
makeDate(int32_t y,int32_t m,int32_t d,int32_t hr,int32_t min,int32_t sec)2658 CalendarRegressionTest::makeDate(int32_t y, int32_t m, int32_t d,
2659 int32_t hr, int32_t min, int32_t sec)
2660 {
2661 UDate result;
2662
2663 UErrorCode status = U_ZERO_ERROR;
2664 Calendar *cal = Calendar::createInstance(status);
2665 cal->clear();
2666
2667 cal->set(UCAL_YEAR, y);
2668
2669 if(m != 0) cal->set(UCAL_MONTH, m);
2670 if(d != 0) cal->set(UCAL_DATE, d);
2671 if(hr != 0) cal->set(UCAL_HOUR, hr);
2672 if(min != 0) cal->set(UCAL_MINUTE, min);
2673 if(sec != 0) cal->set(UCAL_SECOND, sec);
2674
2675 result = cal->getTime(status);
2676
2677 delete cal;
2678
2679 return result;
2680 }
2681
TestDeprecates(void)2682 void CalendarRegressionTest::TestDeprecates(void)
2683 {
2684 UErrorCode status = U_ZERO_ERROR;
2685 Calendar *c1 = Calendar::createInstance("ja_JP@calendar=japanese",status);
2686 Calendar *c2 = Calendar::createInstance("ja_JP_TRADITIONAL",status);
2687
2688 if(!c1 || !c2 || U_FAILURE(status)) {
2689 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status));
2690 return;
2691 }
2692
2693 c2->set(UCAL_HOUR,2);
2694 c1->setTime(c2->getTime(status),status);
2695 // *c1 = *c2;
2696
2697 c1->roll(Calendar::HOUR,(int32_t)3,status);
2698 c2->roll(UCAL_HOUR,(int32_t)3,status);
2699
2700 if(U_FAILURE(status)) {
2701 errln("Error code when trying to roll");
2702 } else if(*c1 != *c2) {
2703 errln("roll(EDateField, int32_t) had different effect than roll(UCalendarField, int32_t)");
2704 }
2705
2706 c1->setTime(c2->getTime(status),status);
2707 c1->roll(Calendar::HOUR,(UBool)FALSE,status);
2708 c2->roll(UCAL_HOUR,(UBool)FALSE,status);
2709
2710 if(U_FAILURE(status)) {
2711 errln("Error code when trying to roll(UBool)");
2712 } else if(*c1 != *c2) {
2713 errln("roll(EDateField, UBool) had different effect than roll(UCalendarField, UBool)");
2714 }
2715
2716 delete c1;
2717 delete c2;
2718
2719 status = U_ZERO_ERROR;
2720
2721 c1 = Calendar::createInstance("th_TH_TRADITIONAL",status);
2722 c2 = Calendar::createInstance("th_TH@calendar=buddhist",status);
2723
2724 if(!c1 || !c2 || U_FAILURE(status)) {
2725 errln("Couldn't create calendars for add of HOUR");
2726 return;
2727 }
2728
2729 c2->set(UCAL_HOUR,2);
2730 c1->setTime(c2->getTime(status),status);
2731 //*c1 = *c2;
2732
2733 c1->add(Calendar::HOUR,(int32_t)1,status);
2734
2735 if(U_FAILURE(status)) {
2736 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status));
2737 }
2738
2739 c2->add(UCAL_HOUR,(int32_t)1,status);
2740
2741 if(U_FAILURE(status)) {
2742 errln("Error code when trying to add - UCAL_HOUR %s", u_errorName(status));
2743 } else if(*c1 != *c2) {
2744 errln("add(EDateField) had different effect than add(UCalendarField)");
2745 }
2746
2747 delete c1;
2748 delete c2;
2749
2750 status = U_ZERO_ERROR;
2751
2752 c1 = Calendar::createInstance("es_ES",status);
2753 c2 = Calendar::createInstance("es_ES",status);
2754
2755 if(!c1 || !c2 || U_FAILURE(status)) {
2756 errln("Couldn't create calendars for add of YEAR");
2757 return;
2758 }
2759
2760 c2->set(UCAL_YEAR,1900);
2761 c1->setTime(c2->getTime(status),status);
2762 //*c1 = *c2;
2763
2764 c1->add(Calendar::YEAR,(int32_t)9,status);
2765 c2->add(UCAL_YEAR,(int32_t)9,status);
2766
2767 if(U_FAILURE(status)) {
2768 errln("Error code when trying to add YEARs");
2769 } else if(*c1 != *c2) {
2770 errln("add(EDateField YEAR) had different effect than add(UCalendarField YEAR)");
2771 }
2772
2773 delete c1;
2774 delete c2;
2775
2776 }
2777
TestT8057(void)2778 void CalendarRegressionTest::TestT8057(void) {
2779 // Set the calendar to the last day in a leap year
2780 UErrorCode status = U_ZERO_ERROR;
2781 GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status);
2782 if(U_FAILURE(status)) {
2783 errln("Error creating Calendar: %s", u_errorName(status));
2784 delete cal;
2785 return;
2786 }
2787 cal->setLenient(FALSE);
2788 cal->clear();
2789 cal->set(2008, UCAL_DECEMBER, 31);
2790
2791 // Force calculating then fields once.
2792 UDate t = cal->getTime(status);
2793 if(U_FAILURE(status)) {
2794 errln("Error while calculating the date");
2795 delete cal;
2796 return;
2797 }
2798
2799 UDate expected = 1262246400000.0; // 2009-12-31 00:00 PST
2800
2801 cal->add(UCAL_YEAR, 1, status);
2802 t = cal->getTime(status);
2803 if (U_SUCCESS(status)) {
2804 if (t != expected) {
2805 dataerrln((UnicodeString)"FAIL: wrong date after add: expected=" + expected + " returned=" + t);
2806 }
2807 } else {
2808 errln("FAIL: error while adding one year");
2809 }
2810
2811 delete cal;
2812 }
2813
2814 #endif /* #if !UCONFIG_NO_FORMATTING */
2815