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