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