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