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