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