1/******************************************************************** 2 * Copyright (c) 1997-2013, International Business Machines 3 * Corporation and others. All Rights Reserved. 4 ******************************************************************** 5 * 6 * File CCALTST.C 7 * 8 * Modification History: 9 * Name Description 10 * Madhu Katragadda Creation 11 ******************************************************************** 12 */ 13 14/* C API AND FUNCTIONALITY TEST FOR CALENDAR (ucol.h)*/ 15 16#include "unicode/utypes.h" 17 18#if !UCONFIG_NO_FORMATTING 19 20#include <stdlib.h> 21#include <string.h> 22 23#include "unicode/uloc.h" 24#include "unicode/ucal.h" 25#include "unicode/udat.h" 26#include "unicode/ustring.h" 27#include "cintltst.h" 28#include "ccaltst.h" 29#include "cformtst.h" 30#include "cstring.h" 31#include "ulist.h" 32 33void TestGregorianChange(void); 34void TestFieldDifference(void); 35void TestAddRollEra0AndEraBounds(void); 36void TestGetTZTransition(void); 37 38void addCalTest(TestNode** root); 39 40void addCalTest(TestNode** root) 41{ 42 43 addTest(root, &TestCalendar, "tsformat/ccaltst/TestCalendar"); 44 addTest(root, &TestGetSetDateAPI, "tsformat/ccaltst/TestGetSetDateAPI"); 45 addTest(root, &TestFieldGetSet, "tsformat/ccaltst/TestFieldGetSet"); 46 addTest(root, &TestAddRollExtensive, "tsformat/ccaltst/TestAddRollExtensive"); 47 addTest(root, &TestGetLimits, "tsformat/ccaltst/TestGetLimits"); 48 addTest(root, &TestDOWProgression, "tsformat/ccaltst/TestDOWProgression"); 49 addTest(root, &TestGMTvsLocal, "tsformat/ccaltst/TestGMTvsLocal"); 50 addTest(root, &TestGregorianChange, "tsformat/ccaltst/TestGregorianChange"); 51 addTest(root, &TestGetKeywordValuesForLocale, "tsformat/ccaltst/TestGetKeywordValuesForLocale"); 52 addTest(root, &TestWeekend, "tsformat/ccaltst/TestWeekend"); 53 addTest(root, &TestFieldDifference, "tsformat/ccaltst/TestFieldDifference"); 54 addTest(root, &TestAmbiguousWallTime, "tsformat/ccaltst/TestAmbiguousWallTime"); 55 addTest(root, &TestAddRollEra0AndEraBounds, "tsformat/ccaltst/TestAddRollEra0AndEraBounds"); 56 addTest(root, &TestGetTZTransition, "tsformat/ccaltst/TestGetTZTransition"); 57} 58 59/* "GMT" */ 60static const UChar fgGMTID [] = { 0x0047, 0x004d, 0x0054, 0x0000 }; 61 62/* "PST" */ 63static const UChar PST[] = {0x50, 0x53, 0x54, 0x00}; /* "PST" */ 64 65static const UChar EUROPE_PARIS[] = {0x45, 0x75, 0x72, 0x6F, 0x70, 0x65, 0x2F, 0x50, 0x61, 0x72, 0x69, 0x73, 0x00}; /* "Europe/Paris" */ 66 67static const UChar AMERICA_LOS_ANGELES[] = {0x41, 0x6D, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2F, 68 0x4C, 0x6F, 0x73, 0x5F, 0x41, 0x6E, 0x67, 0x65, 0x6C, 0x65, 0x73, 0x00}; /* America/Los_Angeles */ 69 70typedef struct { 71 const char * locale; 72 UCalendarType calType; 73 const char * expectedResult; 74} UCalGetTypeTest; 75 76static const UCalGetTypeTest ucalGetTypeTests[] = { 77 { "en_US", UCAL_GREGORIAN, "gregorian" }, 78 { "ja_JP@calendar=japanese", UCAL_DEFAULT, "japanese" }, 79 { "th_TH", UCAL_GREGORIAN, "gregorian" }, 80 { "th_TH", UCAL_DEFAULT, "buddhist" }, 81 { "th-TH-u-ca-gregory", UCAL_DEFAULT, "gregorian" }, 82 { "ja_JP@calendar=japanese", UCAL_GREGORIAN, "gregorian" }, 83 { "", UCAL_GREGORIAN, "gregorian" }, 84 { NULL, UCAL_GREGORIAN, "gregorian" }, 85 { NULL, 0, NULL } /* terminator */ 86}; 87 88static void TestCalendar() 89{ 90 UCalendar *caldef = 0, *caldef2 = 0, *calfr = 0, *calit = 0, *calfrclone = 0; 91 UEnumeration* uenum = NULL; 92 int32_t count, count2, i,j; 93 UChar tzID[4]; 94 UChar *tzdname = 0; 95 UErrorCode status = U_ZERO_ERROR; 96 UDate now; 97 UDateFormat *datdef = 0; 98 UChar *result = 0; 99 int32_t resultlength, resultlengthneeded; 100 char tempMsgBuf[256]; 101 UChar zone1[32], zone2[32]; 102 const char *tzver = 0; 103 UChar canonicalID[64]; 104 UBool isSystemID = FALSE; 105 const UCalGetTypeTest * ucalGetTypeTestPtr; 106 107#ifdef U_USE_UCAL_OBSOLETE_2_8 108 /*Testing countAvailableTimeZones*/ 109 int32_t offset=0; 110 log_verbose("\nTesting ucal_countAvailableTZIDs\n"); 111 count=ucal_countAvailableTZIDs(offset); 112 log_verbose("The number of timezone id's present with offset 0 are %d:\n", count); 113 if(count < 5) /* Don't hard code an exact == test here! */ 114 log_err("FAIL: error in the ucal_countAvailableTZIDs - got %d expected at least 5 total\n", count); 115 116 /*Testing getAvailableTZIDs*/ 117 log_verbose("\nTesting ucal_getAvailableTZIDs"); 118 for(i=0;i<count;i++){ 119 ucal_getAvailableTZIDs(offset, i, &status); 120 if(U_FAILURE(status)){ 121 log_err("FAIL: ucal_getAvailableTZIDs returned %s\n", u_errorName(status)); 122 } 123 log_verbose("%s\n", u_austrcpy(tempMsgBuf, ucal_getAvailableTZIDs(offset, i, &status))); 124 } 125 /*get Illegal TZID where index >= count*/ 126 ucal_getAvailableTZIDs(offset, i, &status); 127 if(status != U_INDEX_OUTOFBOUNDS_ERROR){ 128 log_err("FAIL:for TZID index >= count Expected INDEX_OUTOFBOUNDS_ERROR Got %s\n", u_errorName(status)); 129 } 130 status=U_ZERO_ERROR; 131#endif 132 133 /*Test ucal_openTimeZones, ucal_openCountryTimeZones and ucal_openTimeZoneIDEnumeration */ 134 for (j=0; j<6; ++j) { 135 const char *api = "?"; 136 const int32_t offsetMinus5 = -5*60*60*1000; 137 switch (j) { 138 case 0: 139 api = "ucal_openTimeZones()"; 140 uenum = ucal_openTimeZones(&status); 141 break; 142 case 1: 143 api = "ucal_openCountryTimeZones(US)"; 144 uenum = ucal_openCountryTimeZones("US", &status); 145 break; 146 case 2: 147 api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL)"; 148 uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, &status); 149 break; 150 case 3: 151 api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_CANONICAL_LOCATION, CA, NULL)"; 152 uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL_LOCATION, "CA", NULL, &status); 153 break; 154 case 4: 155 api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_ANY, NULL, -5 hour)"; 156 uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, NULL, &offsetMinus5, &status); 157 break; 158 case 5: 159 api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_ANY, US, -5 hour)"; 160 uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, "US", &offsetMinus5, &status); 161 break; 162 } 163 if (U_FAILURE(status)) { 164 log_err_status(status, "FAIL: %s failed with %s\n", api, 165 u_errorName(status)); 166 } else { 167 const char* id; 168 int32_t len; 169 count = uenum_count(uenum, &status); 170 log_verbose("%s returned %d timezone id's:\n", api, count); 171 if (count < 5) { /* Don't hard code an exact == test here! */ 172 log_data_err("FAIL: in %s, got %d, expected at least 5 -> %s (Are you missing data?)\n", api, count, u_errorName(status)); 173 } 174 uenum_reset(uenum, &status); 175 if (U_FAILURE(status)){ 176 log_err("FAIL: uenum_reset for %s returned %s\n", 177 api, u_errorName(status)); 178 } 179 for (i=0; i<count; i++) { 180 id = uenum_next(uenum, &len, &status); 181 if (U_FAILURE(status)){ 182 log_err("FAIL: uenum_next for %s returned %s\n", 183 api, u_errorName(status)); 184 } else { 185 log_verbose("%s\n", id); 186 } 187 } 188 /* Next one should be NULL */ 189 id = uenum_next(uenum, &len, &status); 190 if (id != NULL) { 191 log_err("FAIL: uenum_next for %s returned %s, expected NULL\n", 192 api, id); 193 } 194 } 195 uenum_close(uenum); 196 } 197 198 /*Test ucal_getDSTSavings*/ 199 status = U_ZERO_ERROR; 200 i = ucal_getDSTSavings(fgGMTID, &status); 201 if (U_FAILURE(status)) { 202 log_err("FAIL: ucal_getDSTSavings(GMT) => %s\n", 203 u_errorName(status)); 204 } else if (i != 0) { 205 log_data_err("FAIL: ucal_getDSTSavings(GMT) => %d, expect 0 (Are you missing data?)\n", i); 206 } 207 i = ucal_getDSTSavings(PST, &status); 208 if (U_FAILURE(status)) { 209 log_err("FAIL: ucal_getDSTSavings(PST) => %s\n", 210 u_errorName(status)); 211 } else if (i != 1*60*60*1000) { 212 log_err("FAIL: ucal_getDSTSavings(PST) => %d, expect %d\n", i, 1*60*60*1000); 213 } 214 215 /*Test ucal_set/getDefaultTimeZone*/ 216 status = U_ZERO_ERROR; 217 i = ucal_getDefaultTimeZone(zone1, sizeof(zone1)/sizeof(zone1[0]), &status); 218 if (U_FAILURE(status)) { 219 log_err("FAIL: ucal_getDefaultTimeZone() => %s\n", 220 u_errorName(status)); 221 } else { 222 ucal_setDefaultTimeZone(EUROPE_PARIS, &status); 223 if (U_FAILURE(status)) { 224 log_err("FAIL: ucal_setDefaultTimeZone(Europe/Paris) => %s\n", 225 u_errorName(status)); 226 } else { 227 i = ucal_getDefaultTimeZone(zone2, sizeof(zone2)/sizeof(zone2[0]), &status); 228 if (U_FAILURE(status)) { 229 log_err("FAIL: ucal_getDefaultTimeZone() => %s\n", 230 u_errorName(status)); 231 } else { 232 if (u_strcmp(zone2, EUROPE_PARIS) != 0) { 233 log_data_err("FAIL: ucal_getDefaultTimeZone() did not return Europe/Paris (Are you missing data?)\n"); 234 } 235 } 236 } 237 status = U_ZERO_ERROR; 238 ucal_setDefaultTimeZone(zone1, &status); 239 } 240 241 /*Test ucal_getTZDataVersion*/ 242 status = U_ZERO_ERROR; 243 tzver = ucal_getTZDataVersion(&status); 244 if (U_FAILURE(status)) { 245 log_err_status(status, "FAIL: ucal_getTZDataVersion() => %s\n", u_errorName(status)); 246 } else if (uprv_strlen(tzver) != 5 /*4 digits + 1 letter*/) { 247 log_err("FAIL: Bad version string was returned by ucal_getTZDataVersion\n"); 248 } else { 249 log_verbose("PASS: ucal_getTZDataVersion returned %s\n", tzver); 250 } 251 252 /*Testing ucal_getCanonicalTimeZoneID*/ 253 status = U_ZERO_ERROR; 254 resultlength = ucal_getCanonicalTimeZoneID(PST, -1, 255 canonicalID, sizeof(canonicalID)/sizeof(UChar), &isSystemID, &status); 256 if (U_FAILURE(status)) { 257 log_err("FAIL: error in ucal_getCanonicalTimeZoneID : %s\n", u_errorName(status)); 258 } else { 259 if (u_strcmp(AMERICA_LOS_ANGELES, canonicalID) != 0) { 260 log_data_err("FAIL: ucal_getCanonicalTimeZoneID(%s) returned %s : expected - %s (Are you missing data?)\n", 261 PST, canonicalID, AMERICA_LOS_ANGELES); 262 } 263 if (!isSystemID) { 264 log_data_err("FAIL: ucal_getCanonicalTimeZoneID(%s) set %d to isSystemID (Are you missing data?)\n", 265 PST, isSystemID); 266 } 267 } 268 269 /*Testing the ucal_open() function*/ 270 status = U_ZERO_ERROR; 271 log_verbose("\nTesting the ucal_open()\n"); 272 u_uastrcpy(tzID, "PST"); 273 caldef=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status); 274 if(U_FAILURE(status)){ 275 log_data_err("FAIL: error in ucal_open caldef : %s\n - (Are you missing data?)", u_errorName(status)); 276 } 277 278 caldef2=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status); 279 if(U_FAILURE(status)){ 280 log_data_err("FAIL: error in ucal_open caldef : %s - (Are you missing data?)\n", u_errorName(status)); 281 } 282 u_strcpy(tzID, fgGMTID); 283 calfr=ucal_open(tzID, u_strlen(tzID), "fr_FR", UCAL_TRADITIONAL, &status); 284 if(U_FAILURE(status)){ 285 log_data_err("FAIL: error in ucal_open calfr : %s - (Are you missing data?)\n", u_errorName(status)); 286 } 287 calit=ucal_open(tzID, u_strlen(tzID), "it_IT", UCAL_TRADITIONAL, &status); 288 if(U_FAILURE(status)) { 289 log_data_err("FAIL: error in ucal_open calit : %s - (Are you missing data?)\n", u_errorName(status)); 290 } 291 292 /*Testing the clone() function*/ 293 calfrclone = ucal_clone(calfr, &status); 294 if(U_FAILURE(status)){ 295 log_data_err("FAIL: error in ucal_clone calfr : %s - (Are you missing data?)\n", u_errorName(status)); 296 } 297 298 /*Testing udat_getAvailable() and udat_countAvailable()*/ 299 log_verbose("\nTesting getAvailableLocales and countAvailable()\n"); 300 count=ucal_countAvailable(); 301 /* use something sensible w/o hardcoding the count */ 302 if(count > 0) { 303 log_verbose("PASS: ucal_countAvailable() works fine\n"); 304 log_verbose("The no: of locales for which calendars are avilable are %d\n", count); 305 } else { 306 log_data_err("FAIL: Error in countAvailable()\n"); 307 } 308 309 for(i=0;i<count;i++) { 310 log_verbose("%s\n", ucal_getAvailable(i)); 311 } 312 313 314 /*Testing the equality between calendar's*/ 315 log_verbose("\nTesting ucal_equivalentTo()\n"); 316 if(caldef && caldef2 && calfr && calit) { 317 if(ucal_equivalentTo(caldef, caldef2) == FALSE || ucal_equivalentTo(caldef, calfr)== TRUE || 318 ucal_equivalentTo(caldef, calit)== TRUE || ucal_equivalentTo(calfr, calfrclone) == FALSE) { 319 log_data_err("FAIL: Error. equivalentTo test failed (Are you missing data?)\n"); 320 } else { 321 log_verbose("PASS: equivalentTo test passed\n"); 322 } 323 } 324 325 326 /*Testing the current time and date using ucal_getnow()*/ 327 log_verbose("\nTesting the ucal_getNow function to check if it is fetching tbe current time\n"); 328 now=ucal_getNow(); 329 /* open the date format and format the date to check the output */ 330 datdef=udat_open(UDAT_FULL,UDAT_FULL ,NULL, NULL, 0,NULL,0,&status); 331 if(U_FAILURE(status)){ 332 log_data_err("FAIL: error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status)); 333 return; 334 } 335 log_verbose("PASS: The current date and time fetched is %s\n", u_austrcpy(tempMsgBuf, myDateFormat(datdef, now)) ); 336 337 338 /*Testing the TimeZoneDisplayName */ 339 log_verbose("\nTesting the fetching of time zone display name\n"); 340 /*for the US locale */ 341 resultlength=0; 342 resultlengthneeded=ucal_getTimeZoneDisplayName(caldef, UCAL_DST, "en_US", NULL, resultlength, &status); 343 344 if(status==U_BUFFER_OVERFLOW_ERROR) 345 { 346 status=U_ZERO_ERROR; 347 resultlength=resultlengthneeded+1; 348 result=(UChar*)malloc(sizeof(UChar) * resultlength); 349 ucal_getTimeZoneDisplayName(caldef, UCAL_DST, "en_US", result, resultlength, &status); 350 } 351 if(U_FAILURE(status)) { 352 log_err("FAIL: Error in getting the timezone display name : %s\n", u_errorName(status)); 353 } 354 else{ 355 log_verbose("PASS: getting the time zone display name successful : %s, %d needed \n", 356 u_errorName(status), resultlengthneeded); 357 } 358 359 360#define expectPDT "Pacific Daylight Time" 361 362 tzdname=(UChar*)malloc(sizeof(UChar) * (sizeof(expectPDT)+1)); 363 u_uastrcpy(tzdname, expectPDT); 364 if(u_strcmp(tzdname, result)==0){ 365 log_verbose("PASS: got the correct time zone display name %s\n", u_austrcpy(tempMsgBuf, result) ); 366 } 367 else{ 368 log_err("FAIL: got the wrong time zone(DST) display name %s, wanted %s\n", austrdup(result) , expectPDT); 369 } 370 371 ucal_getTimeZoneDisplayName(caldef, UCAL_SHORT_DST, "en_US", result, resultlength, &status); 372 u_uastrcpy(tzdname, "PDT"); 373 if(u_strcmp(tzdname, result) != 0){ 374 log_err("FAIL: got the wrong time zone(SHORT_DST) display name %s, wanted %s\n", austrdup(result), austrdup(tzdname)); 375 } 376 377 ucal_getTimeZoneDisplayName(caldef, UCAL_STANDARD, "en_US", result, resultlength, &status); 378 u_uastrcpy(tzdname, "Pacific Standard Time"); 379 if(u_strcmp(tzdname, result) != 0){ 380 log_err("FAIL: got the wrong time zone(STANDARD) display name %s, wanted %s\n", austrdup(result), austrdup(tzdname)); 381 } 382 383 ucal_getTimeZoneDisplayName(caldef, UCAL_SHORT_STANDARD, "en_US", result, resultlength, &status); 384 u_uastrcpy(tzdname, "PST"); 385 if(u_strcmp(tzdname, result) != 0){ 386 log_err("FAIL: got the wrong time zone(SHORT_STANDARD) display name %s, wanted %s\n", austrdup(result), austrdup(tzdname)); 387 } 388 389 390 /*testing the setAttributes and getAttributes of a UCalendar*/ 391 log_verbose("\nTesting the getAttributes and set Attributes\n"); 392 count=ucal_getAttribute(calit, UCAL_LENIENT); 393 count2=ucal_getAttribute(calfr, UCAL_LENIENT); 394 ucal_setAttribute(calit, UCAL_LENIENT, 0); 395 ucal_setAttribute(caldef, UCAL_LENIENT, count2); 396 if( ucal_getAttribute(calit, UCAL_LENIENT) !=0 || 397 ucal_getAttribute(calfr, UCAL_LENIENT)!=ucal_getAttribute(caldef, UCAL_LENIENT) ) 398 log_err("FAIL: there is an error in getAttributes or setAttributes\n"); 399 else 400 log_verbose("PASS: attribute set and got successfully\n"); 401 /*set it back to orginal value */ 402 log_verbose("Setting it back to normal\n"); 403 ucal_setAttribute(calit, UCAL_LENIENT, count); 404 if(ucal_getAttribute(calit, UCAL_LENIENT)!=count) 405 log_err("FAIL: Error in setting the attribute back to normal\n"); 406 407 /*setting the first day of the week to other values */ 408 count=ucal_getAttribute(calit, UCAL_FIRST_DAY_OF_WEEK); 409 for (i=1; i<=7; ++i) { 410 ucal_setAttribute(calit, UCAL_FIRST_DAY_OF_WEEK,i); 411 if (ucal_getAttribute(calit, UCAL_FIRST_DAY_OF_WEEK) != i) 412 log_err("FAIL: set/getFirstDayOfWeek failed\n"); 413 } 414 /*get bogus Attribute*/ 415 count=ucal_getAttribute(calit, (UCalendarAttribute)99); /* BOGUS_ATTRIBUTE */ 416 if(count != -1){ 417 log_err("FAIL: get/bogus attribute should return -1\n"); 418 } 419 420 /*set it back to normal */ 421 ucal_setAttribute(calit, UCAL_FIRST_DAY_OF_WEEK,count); 422 /*setting minimal days of the week to other values */ 423 count=ucal_getAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK); 424 for (i=1; i<=7; ++i) { 425 ucal_setAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,i); 426 if (ucal_getAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK) != i) 427 log_err("FAIL: set/getMinimalDaysInFirstWeek failed\n"); 428 } 429 /*set it back to normal */ 430 ucal_setAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,count); 431 432 433 /*testing if the UCalendar's timezone is currently in day light saving's time*/ 434 log_verbose("\nTesting if the UCalendar is currently in daylight saving's time\n"); 435 ucal_setDateTime(caldef, 1999, UCAL_MARCH, 3, 10, 45, 20, &status); 436 ucal_inDaylightTime(caldef, &status ); 437 if(U_FAILURE(status)) { 438 log_err("Error in ucal_inDaylightTime: %s\n", u_errorName(status)); 439 } 440 if(!ucal_inDaylightTime(caldef, &status)) 441 log_verbose("PASS: It is not in daylight saving's time\n"); 442 else 443 log_err("FAIL: It is not in daylight saving's time\n"); 444 445 /*closing the UCalendar*/ 446 ucal_close(caldef); 447 ucal_close(caldef2); 448 ucal_close(calfr); 449 ucal_close(calit); 450 ucal_close(calfrclone); 451 452 /*testing ucal_getType, and ucal_open with UCAL_GREGORIAN*/ 453 for (ucalGetTypeTestPtr = ucalGetTypeTests; ucalGetTypeTestPtr->expectedResult != NULL; ++ucalGetTypeTestPtr) { 454 const char * localeToDisplay = (ucalGetTypeTestPtr->locale != NULL)? ucalGetTypeTestPtr->locale: "<NULL>"; 455 status = U_ZERO_ERROR; 456 caldef = ucal_open(NULL, 0, ucalGetTypeTestPtr->locale, ucalGetTypeTestPtr->calType, &status); 457 if ( U_SUCCESS(status) ) { 458 const char * calType = ucal_getType(caldef, &status); 459 if ( U_SUCCESS(status) && calType != NULL ) { 460 if ( uprv_strcmp( calType, ucalGetTypeTestPtr->expectedResult ) != 0 ) { 461 log_err("FAIL: ucal_open %s type %d does not return %s calendar\n", localeToDisplay, 462 ucalGetTypeTestPtr->calType, ucalGetTypeTestPtr->expectedResult); 463 } 464 } else { 465 log_err("FAIL: ucal_open %s type %d, then ucal_getType fails\n", localeToDisplay, ucalGetTypeTestPtr->calType); 466 } 467 ucal_close(caldef); 468 } else { 469 log_err("FAIL: ucal_open %s type %d fails\n", localeToDisplay, ucalGetTypeTestPtr->calType); 470 } 471 } 472 473 /*closing the UDateFormat used */ 474 udat_close(datdef); 475 free(result); 476 free(tzdname); 477} 478 479/*------------------------------------------------------*/ 480/*Testing the getMillis, setMillis, setDate and setDateTime functions extensively*/ 481 482static void TestGetSetDateAPI() 483{ 484 UCalendar *caldef = 0, *caldef2 = 0, *caldef3 = 0; 485 UChar tzID[4]; 486 UDate d1; 487 int32_t hour; 488 int32_t zoneOffset; 489 UDateFormat *datdef = 0; 490 UErrorCode status=U_ZERO_ERROR; 491 UDate d2= 837039928046.0; 492 UChar temp[30]; 493 double testMillis; 494 int32_t dateBit; 495 UChar id[4]; 496 int32_t idLen; 497 498 log_verbose("\nOpening the calendars()\n"); 499 u_strcpy(tzID, fgGMTID); 500 /*open the calendars used */ 501 caldef=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status); 502 caldef2=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status); 503 caldef3=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status); 504 /*open the dateformat */ 505 /* this is supposed to open default date format, but later on it treats it like it is "en_US" 506 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ 507 /*datdef=udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL,fgGMTID,-1, &status);*/ 508 datdef=udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US",fgGMTID,-1,NULL,0, &status); 509 if(U_FAILURE(status)) 510 { 511 log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status)); 512 return; 513 } 514 515 /*Testing getMillis and setMillis */ 516 log_verbose("\nTesting the date and time fetched in millis for a calendar using getMillis\n"); 517 d1=ucal_getMillis(caldef, &status); 518 if(U_FAILURE(status)){ 519 log_err("Error in getMillis : %s\n", u_errorName(status)); 520 } 521 522 /*testing setMillis */ 523 log_verbose("\nTesting the set date and time function using setMillis\n"); 524 ucal_setMillis(caldef, d2, &status); 525 if(U_FAILURE(status)){ 526 log_err("Error in setMillis : %s\n", u_errorName(status)); 527 } 528 529 /*testing if the calendar date is set properly or not */ 530 d1=ucal_getMillis(caldef, &status); 531 if(u_strcmp(myDateFormat(datdef, d1), myDateFormat(datdef, d2))!=0) 532 log_err("error in setMillis or getMillis\n"); 533 /*-------------------*/ 534 535 /*testing large negative millis*/ 536 /*test a previously failed millis and beyond the lower bounds - ICU trac #9403 */ 537 // -184303902611600000.0 - just beyond lower bounds (#9403 sets U_ILLEGAL_ARGUMENT_ERROR in strict mode) 538 // -46447814188001000.0 - fixed by #9403 539 540 log_verbose("\nTesting very large valid millis & invalid setMillis values (in both strict & lienent modes) detected\n"); 541 542 testMillis = -46447814188001000.0; // point where floorDivide in handleComputeFields failed as per #9403 543 log_verbose("using value[%lf]\n", testMillis); 544 ucal_setAttribute(caldef3, UCAL_LENIENT, 0); 545 ucal_setMillis(caldef3, testMillis, &status); 546 if(U_FAILURE(status)){ 547 log_err("Fail: setMillis incorrectly detected invalid value : for millis : %e : returned : %s\n", testMillis, u_errorName(status)); 548 status = U_ZERO_ERROR; 549 } 550 551 log_verbose("\nTesting invalid setMillis values detected\n"); 552 testMillis = -184303902611600000.0; 553 log_verbose("using value[%lf]\n", testMillis); 554 ucal_setAttribute(caldef3, UCAL_LENIENT, 1); 555 ucal_setMillis(caldef3, testMillis, &status); 556 if(U_FAILURE(status)){ 557 log_err("Fail: setMillis incorrectly detected invalid value : for millis : %e : returned : %s\n", testMillis, u_errorName(status)); 558 status = U_ZERO_ERROR; 559 } else { 560 dateBit = ucal_get(caldef2, UCAL_MILLISECOND, &status); 561 if(testMillis == dateBit) 562 { 563 log_err("Fail: error in setMillis, allowed invalid value %e : returns millisecond : %d", testMillis, dateBit); 564 } else { 565 log_verbose("Pass: setMillis correctly pinned min, returned : %d", dateBit); 566 } 567 } 568 569 log_verbose("\nTesting invalid setMillis values detected\n"); 570 testMillis = -184303902611600000.0; 571 log_verbose("using value[%lf]\n", testMillis); 572 ucal_setAttribute(caldef3, UCAL_LENIENT, 0); 573 ucal_setMillis(caldef3, testMillis, &status); 574 if(U_FAILURE(status)){ 575 log_verbose("Pass: Illegal argument error as expected : for millis : %e : returned : %s\n", testMillis, u_errorName(status)); 576 status = U_ZERO_ERROR; 577 } else { 578 dateBit = ucal_get(caldef3, UCAL_DAY_OF_MONTH, &status); 579 log_err("Fail: error in setMillis, allowed invalid value %e : returns DayOfMonth : %d", testMillis, dateBit); 580 } 581 /*-------------------*/ 582 583 584 ctest_setTimeZone(NULL, &status); 585 586 /*testing ucal_setTimeZone() and ucal_getTimeZoneID function*/ 587 log_verbose("\nTesting if the function ucal_setTimeZone() and ucal_getTimeZoneID work fine\n"); 588 idLen = ucal_getTimeZoneID(caldef2, id, sizeof(id)/sizeof(id[0]), &status); 589 if (U_FAILURE(status)) { 590 log_err("Error in getTimeZoneID : %s\n", u_errorName(status)); 591 } else if (u_strcmp(id, fgGMTID) != 0) { 592 log_err("FAIL: getTimeZoneID returns a wrong ID: actual=%d, expected=%s\n", austrdup(id), austrdup(fgGMTID)); 593 } else { 594 log_verbose("PASS: getTimeZoneID works fine\n"); 595 } 596 597 ucal_setMillis(caldef2, d2, &status); 598 if(U_FAILURE(status)){ 599 log_err("Error in getMillis : %s\n", u_errorName(status)); 600 } 601 hour=ucal_get(caldef2, UCAL_HOUR_OF_DAY, &status); 602 603 u_uastrcpy(tzID, "PST"); 604 ucal_setTimeZone(caldef2,tzID, 3, &status); 605 if(U_FAILURE(status)){ 606 log_err("Error in setting the time zone using ucal_setTimeZone(): %s\n", u_errorName(status)); 607 } 608 else 609 log_verbose("ucal_setTimeZone worked fine\n"); 610 611 idLen = ucal_getTimeZoneID(caldef2, id, sizeof(id)/sizeof(id[0]), &status); 612 if (U_FAILURE(status)) { 613 log_err("Error in getTimeZoneID : %s\n", u_errorName(status)); 614 } else if (u_strcmp(id, tzID) != 0) { 615 log_err("FAIL: getTimeZoneID returns a wrong ID: actual=%d, expected=%s\n", austrdup(id), austrdup(tzID)); 616 } else { 617 log_verbose("PASS: getTimeZoneID works fine\n"); 618 } 619 620 if(hour == ucal_get(caldef2, UCAL_HOUR_OF_DAY, &status)) 621 log_err("FAIL: Error setting the time zone doesn't change the represented time\n"); 622 else if((hour-8 + 1) != ucal_get(caldef2, UCAL_HOUR_OF_DAY, &status)) /*because it is not in daylight savings time */ 623 log_err("FAIL: Error setTimeZone doesn't change the represented time correctly with 8 hour offset\n"); 624 else 625 log_verbose("PASS: setTimeZone works fine\n"); 626 627 /*testing setTimeZone roundtrip */ 628 log_verbose("\nTesting setTimeZone() roundtrip\n"); 629 u_strcpy(tzID, fgGMTID); 630 ucal_setTimeZone(caldef2, tzID, 3, &status); 631 if(U_FAILURE(status)){ 632 log_err("Error in setting the time zone using ucal_setTimeZone(): %s\n", u_errorName(status)); 633 } 634 if(d2==ucal_getMillis(caldef2, &status)) 635 log_verbose("PASS: setTimeZone roundtrip test passed\n"); 636 else 637 log_err("FAIL: setTimeZone roundtrip test failed\n"); 638 639 zoneOffset = ucal_get(caldef2, UCAL_ZONE_OFFSET, &status); 640 if(U_FAILURE(status)){ 641 log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone(): %s\n", u_errorName(status)); 642 } 643 else if (zoneOffset != 0) { 644 log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone() offset=%d\n", zoneOffset); 645 } 646 647 ucal_setTimeZone(caldef2, NULL, -1, &status); 648 if(U_FAILURE(status)){ 649 log_err("Error in setting the time zone using ucal_setTimeZone(): %s\n", u_errorName(status)); 650 } 651 if(ucal_getMillis(caldef2, &status)) 652 log_verbose("PASS: setTimeZone roundtrip test passed\n"); 653 else 654 log_err("FAIL: setTimeZone roundtrip test failed\n"); 655 656 zoneOffset = ucal_get(caldef2, UCAL_ZONE_OFFSET, &status); 657 if(U_FAILURE(status)){ 658 log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone(): %s\n", u_errorName(status)); 659 } 660 else if (zoneOffset != -28800000) { 661 log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone() offset=%d\n", zoneOffset); 662 } 663 664 ctest_resetTimeZone(); 665 666/*----------------------------* */ 667 668 669 670 /*Testing if setDate works fine */ 671 log_verbose("\nTesting the ucal_setDate() function \n"); 672 u_uastrcpy(temp, "Dec 17, 1971, 11:05:28 PM"); 673 ucal_setDate(caldef,1971, UCAL_DECEMBER, 17, &status); 674 if(U_FAILURE(status)){ 675 log_err("error in setting the calendar date : %s\n", u_errorName(status)); 676 } 677 /*checking if the calendar date is set properly or not */ 678 d1=ucal_getMillis(caldef, &status); 679 if(u_strcmp(myDateFormat(datdef, d1), temp)==0) 680 log_verbose("PASS:setDate works fine\n"); 681 else 682 log_err("FAIL:Error in setDate()\n"); 683 684 685 /* Testing setDate Extensively with various input values */ 686 log_verbose("\nTesting ucal_setDate() extensively\n"); 687 ucal_setDate(caldef, 1999, UCAL_JANUARY, 10, &status); 688 verify1("1999 10th day of January is :", caldef, datdef, 1999, UCAL_JANUARY, 10); 689 ucal_setDate(caldef, 1999, UCAL_DECEMBER, 3, &status); 690 verify1("1999 3rd day of December is :", caldef, datdef, 1999, UCAL_DECEMBER, 3); 691 ucal_setDate(caldef, 2000, UCAL_MAY, 3, &status); 692 verify1("2000 3rd day of May is :", caldef, datdef, 2000, UCAL_MAY, 3); 693 ucal_setDate(caldef, 1999, UCAL_AUGUST, 32, &status); 694 verify1("1999 32th day of August is :", caldef, datdef, 1999, UCAL_SEPTEMBER, 1); 695 ucal_setDate(caldef, 1999, UCAL_MARCH, 0, &status); 696 verify1("1999 0th day of March is :", caldef, datdef, 1999, UCAL_FEBRUARY, 28); 697 ucal_setDate(caldef, 0, UCAL_MARCH, 12, &status); 698 699 /*--------------------*/ 700 701 /*Testing if setDateTime works fine */ 702 log_verbose("\nTesting the ucal_setDateTime() function \n"); 703 u_uastrcpy(temp, "May 3, 1972, 4:30:42 PM"); 704 ucal_setDateTime(caldef,1972, UCAL_MAY, 3, 16, 30, 42, &status); 705 if(U_FAILURE(status)){ 706 log_err("error in setting the calendar date : %s\n", u_errorName(status)); 707 } 708 /*checking if the calendar date is set properly or not */ 709 d1=ucal_getMillis(caldef, &status); 710 if(u_strcmp(myDateFormat(datdef, d1), temp)==0) 711 log_verbose("PASS: setDateTime works fine\n"); 712 else 713 log_err("FAIL: Error in setDateTime\n"); 714 715 716 717 /*Testing setDateTime extensively with various input values*/ 718 log_verbose("\nTesting ucal_setDateTime() function extensively\n"); 719 ucal_setDateTime(caldef, 1999, UCAL_OCTOBER, 10, 6, 45, 30, &status); 720 verify2("1999 10th day of October at 6:45:30 is :", caldef, datdef, 1999, UCAL_OCTOBER, 10, 6, 45, 30, 0 ); 721 ucal_setDateTime(caldef, 1999, UCAL_MARCH, 3, 15, 10, 55, &status); 722 verify2("1999 3rd day of March at 15:10:55 is :", caldef, datdef, 1999, UCAL_MARCH, 3, 3, 10, 55, 1); 723 ucal_setDateTime(caldef, 1999, UCAL_MAY, 3, 25, 30, 45, &status); 724 verify2("1999 3rd day of May at 25:30:45 is :", caldef, datdef, 1999, UCAL_MAY, 4, 1, 30, 45, 0); 725 ucal_setDateTime(caldef, 1999, UCAL_AUGUST, 32, 22, 65, 40, &status); 726 verify2("1999 32th day of August at 22:65:40 is :", caldef, datdef, 1999, UCAL_SEPTEMBER, 1, 11, 5, 40,1); 727 ucal_setDateTime(caldef, 1999, UCAL_MARCH, 12, 0, 0, 0,&status); 728 verify2("1999 12th day of March at 0:0:0 is :", caldef, datdef, 1999, UCAL_MARCH, 12, 0, 0, 0, 0); 729 ucal_setDateTime(caldef, 1999, UCAL_MARCH, 12, -10, -10,0, &status); 730 verify2("1999 12th day of March is at -10:-10:0 :", caldef, datdef, 1999, UCAL_MARCH, 11, 1, 50, 0, 1); 731 732 733 734 /*close caldef and datdef*/ 735 ucal_close(caldef); 736 ucal_close(caldef2); 737 ucal_close(caldef3); 738 udat_close(datdef); 739} 740 741/*----------------------------------------------------------- */ 742/** 743 * Confirm the functioning of the calendar field related functions. 744 */ 745static void TestFieldGetSet() 746{ 747 UCalendar *cal = 0; 748 UChar tzID[4]; 749 UDateFormat *datdef = 0; 750 UDate d1; 751 UErrorCode status=U_ZERO_ERROR; 752 log_verbose("\nFetching pointer to UCalendar using the ucal_open()\n"); 753 u_strcpy(tzID, fgGMTID); 754 /*open the calendar used */ 755 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status); 756 if (U_FAILURE(status)) { 757 log_data_err("ucal_open failed: %s - (Are you missing data?)\n", u_errorName(status)); 758 return; 759 } 760 datdef=udat_open(UDAT_SHORT,UDAT_SHORT ,NULL,fgGMTID,-1,NULL, 0, &status); 761 if(U_FAILURE(status)) 762 { 763 log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status)); 764 } 765 766 /*Testing ucal_get()*/ 767 log_verbose("\nTesting the ucal_get() function of Calendar\n"); 768 ucal_setDateTime(cal, 1999, UCAL_MARCH, 12, 5, 25, 30, &status); 769 if(U_FAILURE(status)){ 770 log_data_err("error in the setDateTime() : %s (Are you missing data?)\n", u_errorName(status)); 771 } 772 if(ucal_get(cal, UCAL_YEAR, &status)!=1999 || ucal_get(cal, UCAL_MONTH, &status)!=2 || 773 ucal_get(cal, UCAL_DATE, &status)!=12 || ucal_get(cal, UCAL_HOUR, &status)!=5) 774 log_data_err("error in ucal_get() -> %s (Are you missing data?)\n", u_errorName(status)); 775 else if(ucal_get(cal, UCAL_DAY_OF_WEEK_IN_MONTH, &status)!=2 || ucal_get(cal, UCAL_DAY_OF_WEEK, &status)!=6 776 || ucal_get(cal, UCAL_WEEK_OF_MONTH, &status)!=2 || ucal_get(cal, UCAL_WEEK_OF_YEAR, &status)!= 11) 777 log_err("FAIL: error in ucal_get()\n"); 778 else 779 log_verbose("PASS: ucal_get() works fine\n"); 780 781 /*Testing the ucal_set() , ucal_clear() functions of calendar*/ 782 log_verbose("\nTesting the set, and clear field functions of calendar\n"); 783 ucal_setAttribute(cal, UCAL_LENIENT, 0); 784 ucal_clear(cal); 785 ucal_set(cal, UCAL_YEAR, 1997); 786 ucal_set(cal, UCAL_MONTH, UCAL_JUNE); 787 ucal_set(cal, UCAL_DATE, 3); 788 verify1("1997 third day of June = ", cal, datdef, 1997, UCAL_JUNE, 3); 789 ucal_clear(cal); 790 ucal_set(cal, UCAL_YEAR, 1997); 791 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 792 ucal_set(cal, UCAL_MONTH, UCAL_JUNE); 793 ucal_set(cal, UCAL_DAY_OF_WEEK_IN_MONTH, 1); 794 verify1("1997 first Tuesday in June = ", cal, datdef, 1997, UCAL_JUNE, 3); 795 ucal_clear(cal); 796 ucal_set(cal, UCAL_YEAR, 1997); 797 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 798 ucal_set(cal, UCAL_MONTH, UCAL_JUNE); 799 ucal_set(cal, UCAL_DAY_OF_WEEK_IN_MONTH, - 1); 800 verify1("1997 last Tuesday in June = ", cal, datdef,1997, UCAL_JUNE, 24); 801 /*give undesirable input */ 802 status = U_ZERO_ERROR; 803 ucal_clear(cal); 804 ucal_set(cal, UCAL_YEAR, 1997); 805 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 806 ucal_set(cal, UCAL_MONTH, UCAL_JUNE); 807 ucal_set(cal, UCAL_DAY_OF_WEEK_IN_MONTH, 0); 808 d1 = ucal_getMillis(cal, &status); 809 if (status != U_ILLEGAL_ARGUMENT_ERROR) { 810 log_err("FAIL: U_ILLEGAL_ARGUMENT_ERROR was not returned for : 1997 zero-th Tuesday in June\n"); 811 } else { 812 log_verbose("PASS: U_ILLEGAL_ARGUMENT_ERROR as expected\n"); 813 } 814 status = U_ZERO_ERROR; 815 ucal_clear(cal); 816 ucal_set(cal, UCAL_YEAR, 1997); 817 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 818 ucal_set(cal, UCAL_MONTH, UCAL_JUNE); 819 ucal_set(cal, UCAL_WEEK_OF_MONTH, 1); 820 verify1("1997 Tuesday in week 1 of June = ", cal,datdef, 1997, UCAL_JUNE, 3); 821 ucal_clear(cal); 822 ucal_set(cal, UCAL_YEAR, 1997); 823 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 824 ucal_set(cal, UCAL_MONTH, UCAL_JUNE); 825 ucal_set(cal, UCAL_WEEK_OF_MONTH, 5); 826 verify1("1997 Tuesday in week 5 of June = ", cal,datdef, 1997, UCAL_JULY, 1); 827 status = U_ZERO_ERROR; 828 ucal_clear(cal); 829 ucal_set(cal, UCAL_YEAR, 1997); 830 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 831 ucal_set(cal, UCAL_MONTH, UCAL_JUNE); 832 ucal_set(cal, UCAL_WEEK_OF_MONTH, 0); 833 ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,1); 834 d1 = ucal_getMillis(cal,&status); 835 if (status != U_ILLEGAL_ARGUMENT_ERROR){ 836 log_err("FAIL: U_ILLEGAL_ARGUMENT_ERROR was not returned for : 1997 Tuesday zero-th week in June\n"); 837 } else { 838 log_verbose("PASS: U_ILLEGAL_ARGUMENT_ERROR as expected\n"); 839 } 840 status = U_ZERO_ERROR; 841 ucal_clear(cal); 842 ucal_set(cal, UCAL_YEAR_WOY, 1997); 843 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 844 ucal_set(cal, UCAL_WEEK_OF_YEAR, 1); 845 verify1("1997 Tuesday in week 1 of year = ", cal, datdef,1996, UCAL_DECEMBER, 31); 846 ucal_clear(cal); 847 ucal_set(cal, UCAL_YEAR, 1997); 848 ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 849 ucal_set(cal, UCAL_WEEK_OF_YEAR, 10); 850 verify1("1997 Tuesday in week 10 of year = ", cal,datdef, 1997, UCAL_MARCH, 4); 851 ucal_clear(cal); 852 ucal_set(cal, UCAL_YEAR, 1999); 853 ucal_set(cal, UCAL_DAY_OF_YEAR, 1); 854 verify1("1999 1st day of the year =", cal, datdef, 1999, UCAL_JANUARY, 1); 855 ucal_set(cal, UCAL_MONTH, -3); 856 d1 = ucal_getMillis(cal,&status); 857 if (status != U_ILLEGAL_ARGUMENT_ERROR){ 858 log_err("FAIL: U_ILLEGAL_ARGUMENT_ERROR was not returned for : 1999 -3th month\n"); 859 } else { 860 log_verbose("PASS: U_ILLEGAL_ARGUMENT_ERROR as expected\n"); 861 } 862 863 ucal_setAttribute(cal, UCAL_LENIENT, 1); 864 865 ucal_set(cal, UCAL_MONTH, -3); 866 verify1("1999 -3th month should be", cal, datdef, 1998, UCAL_OCTOBER, 1); 867 868 869 /*testing isSet and clearField()*/ 870 if(!ucal_isSet(cal, UCAL_WEEK_OF_YEAR)) 871 log_err("FAIL: error in isSet\n"); 872 else 873 log_verbose("PASS: isSet working fine\n"); 874 ucal_clearField(cal, UCAL_WEEK_OF_YEAR); 875 if(ucal_isSet(cal, UCAL_WEEK_OF_YEAR)) 876 log_err("FAIL: there is an error in clearField or isSet\n"); 877 else 878 log_verbose("PASS :clearField working fine\n"); 879 880 /*-------------------------------*/ 881 882 ucal_close(cal); 883 udat_close(datdef); 884} 885 886typedef struct { 887 const char * zone; 888 int32_t year; 889 int32_t month; 890 int32_t day; 891 int32_t hour; 892} TransitionItem; 893 894static const TransitionItem transitionItems[] = { 895 { "America/Caracas", 2007, UCAL_DECEMBER, 8, 10 }, /* day before change in UCAL_ZONE_OFFSET */ 896 { "US/Pacific", 2011, UCAL_MARCH, 12, 10 }, /* day before change in UCAL_DST_OFFSET */ 897 { NULL, 0, 0, 0, 0 } 898}; 899 900/* ------------------------------------- */ 901/** 902 * Execute adding and rolling in Calendar extensively, 903 */ 904static void TestAddRollExtensive() 905{ 906 const TransitionItem * itemPtr; 907 UCalendar *cal = 0; 908 int32_t i,limit; 909 UChar tzID[32]; 910 UCalendarDateFields e; 911 int32_t y,m,d,hr,min,sec,ms; 912 int32_t maxlimit = 40; 913 UErrorCode status = U_ZERO_ERROR; 914 y = 1997; m = UCAL_FEBRUARY; d = 1; hr = 1; min = 1; sec = 0; ms = 0; 915 916 log_verbose("Testing add and roll extensively\n"); 917 918 u_uastrcpy(tzID, "PST"); 919 /*open the calendar used */ 920 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status);; 921 if (U_FAILURE(status)) { 922 log_data_err("ucal_open() failed : %s - (Are you missing data?)\n", u_errorName(status)); 923 return; 924 } 925 926 ucal_set(cal, UCAL_YEAR, y); 927 ucal_set(cal, UCAL_MONTH, m); 928 ucal_set(cal, UCAL_DATE, d); 929 ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,1); 930 931 /* Confirm that adding to various fields works.*/ 932 log_verbose("\nTesting to confirm that adding to various fields works with ucal_add()\n"); 933 checkDate(cal, y, m, d); 934 ucal_add(cal,UCAL_YEAR, 1, &status); 935 if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status)); return; } 936 y++; 937 checkDate(cal, y, m, d); 938 ucal_add(cal,UCAL_MONTH, 12, &status); 939 if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; } 940 y+=1; 941 checkDate(cal, y, m, d); 942 ucal_add(cal,UCAL_DATE, 1, &status); 943 if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; } 944 d++; 945 checkDate(cal, y, m, d); 946 ucal_add(cal,UCAL_DATE, 2, &status); 947 if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; } 948 d += 2; 949 checkDate(cal, y, m, d); 950 ucal_add(cal,UCAL_DATE, 28, &status); 951 if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; } 952 ++m; 953 checkDate(cal, y, m, d); 954 ucal_add(cal, (UCalendarDateFields)-1, 10, &status); 955 if(status==U_ILLEGAL_ARGUMENT_ERROR) 956 log_verbose("Pass: Illegal argument error as expected\n"); 957 else{ 958 log_err("Fail: No, illegal argument error as expected. Got....: %s\n", u_errorName(status)); 959 } 960 status=U_ZERO_ERROR; 961 962 963 /*confirm that applying roll to various fields works fine*/ 964 log_verbose("\nTesting to confirm that ucal_roll() works\n"); 965 ucal_roll(cal, UCAL_DATE, -1, &status); 966 if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; } 967 d -=1; 968 checkDate(cal, y, m, d); 969 ucal_roll(cal, UCAL_MONTH, -2, &status); 970 if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; } 971 m -=2; 972 checkDate(cal, y, m, d); 973 ucal_roll(cal, UCAL_DATE, 1, &status); 974 if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; } 975 d +=1; 976 checkDate(cal, y, m, d); 977 ucal_roll(cal, UCAL_MONTH, -12, &status); 978 if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; } 979 checkDate(cal, y, m, d); 980 ucal_roll(cal, UCAL_YEAR, -1, &status); 981 if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; } 982 y -=1; 983 checkDate(cal, y, m, d); 984 ucal_roll(cal, UCAL_DATE, 29, &status); 985 if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; } 986 d = 2; 987 checkDate(cal, y, m, d); 988 ucal_roll(cal, (UCalendarDateFields)-1, 10, &status); 989 if(status==U_ILLEGAL_ARGUMENT_ERROR) 990 log_verbose("Pass: illegal arguement error as expected\n"); 991 else{ 992 log_err("Fail: no illegal argument error got..: %s\n", u_errorName(status)); 993 return; 994 } 995 status=U_ZERO_ERROR; 996 ucal_clear(cal); 997 ucal_setDateTime(cal, 1999, UCAL_FEBRUARY, 28, 10, 30, 45, &status); 998 if(U_FAILURE(status)){ 999 log_err("error is setting the datetime: %s\n", u_errorName(status)); 1000 } 1001 ucal_add(cal, UCAL_MONTH, 1, &status); 1002 checkDate(cal, 1999, UCAL_MARCH, 28); 1003 ucal_add(cal, UCAL_MILLISECOND, 1000, &status); 1004 checkDateTime(cal, 1999, UCAL_MARCH, 28, 10, 30, 46, 0, UCAL_MILLISECOND); 1005 1006 ucal_close(cal); 1007/*--------------- */ 1008 status=U_ZERO_ERROR; 1009 /* Testing add and roll extensively */ 1010 log_verbose("\nTesting the ucal_add() and ucal_roll() functions extensively\n"); 1011 y = 1997; m = UCAL_FEBRUARY; d = 1; hr = 1; min = 1; sec = 0; ms = 0; 1012 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status); 1013 if (U_FAILURE(status)) { 1014 log_err("ucal_open failed: %s\n", u_errorName(status)); 1015 return; 1016 } 1017 ucal_set(cal, UCAL_YEAR, y); 1018 ucal_set(cal, UCAL_MONTH, m); 1019 ucal_set(cal, UCAL_DATE, d); 1020 ucal_set(cal, UCAL_HOUR, hr); 1021 ucal_set(cal, UCAL_MINUTE, min); 1022 ucal_set(cal, UCAL_SECOND,sec); 1023 ucal_set(cal, UCAL_MILLISECOND, ms); 1024 ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,1); 1025 status=U_ZERO_ERROR; 1026 1027 log_verbose("\nTesting UCalendar add...\n"); 1028 for(e = UCAL_YEAR;e < UCAL_FIELD_COUNT; e=(UCalendarDateFields)((int32_t)e + 1)) { 1029 limit = maxlimit; 1030 status = U_ZERO_ERROR; 1031 for (i = 0; i < limit; i++) { 1032 ucal_add(cal, e, 1, &status); 1033 if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; } 1034 } 1035 for (i = 0; i < limit; i++) { 1036 ucal_add(cal, e, -1, &status); 1037 if (U_FAILURE(status)) { 1038 log_err("ucal_add -1 failed: %s\n", u_errorName(status)); 1039 return; 1040 } 1041 } 1042 checkDateTime(cal, y, m, d, hr, min, sec, ms, e); 1043 } 1044 log_verbose("\nTesting calendar ucal_roll()...\n"); 1045 for(e = UCAL_YEAR;e < UCAL_FIELD_COUNT; e=(UCalendarDateFields)((int32_t)e + 1)) { 1046 limit = maxlimit; 1047 status = U_ZERO_ERROR; 1048 for (i = 0; i < limit; i++) { 1049 ucal_roll(cal, e, 1, &status); 1050 if (U_FAILURE(status)) { 1051 limit = i; 1052 status = U_ZERO_ERROR; 1053 } 1054 } 1055 for (i = 0; i < limit; i++) { 1056 ucal_roll(cal, e, -1, &status); 1057 if (U_FAILURE(status)) { 1058 log_err("ucal_roll -1 failed: %s\n", u_errorName(status)); 1059 return; 1060 } 1061 } 1062 checkDateTime(cal, y, m, d, hr, min, sec, ms, e); 1063 } 1064 1065 ucal_close(cal); 1066/*--------------- */ 1067 log_verbose("\nTesting ucal_add() across ZONE_OFFSET and DST_OFFSE transitions.\n"); 1068 for (itemPtr = transitionItems; itemPtr->zone != NULL; itemPtr++) { 1069 status=U_ZERO_ERROR; 1070 u_uastrcpy(tzID, itemPtr->zone); 1071 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status); 1072 if (U_FAILURE(status)) { 1073 log_err("ucal_open failed for zone %s: %s\n", itemPtr->zone, u_errorName(status)); 1074 continue; 1075 } 1076 ucal_setDateTime(cal, itemPtr->year, itemPtr->month, itemPtr->day, itemPtr->hour, 0, 0, &status); 1077 ucal_add(cal, UCAL_DATE, 1, &status); 1078 hr = ucal_get(cal, UCAL_HOUR_OF_DAY, &status); 1079 if ( U_FAILURE(status) ) { 1080 log_err("ucal_add failed adding day across transition for zone %s: %s\n", itemPtr->zone, u_errorName(status)); 1081 } else if ( hr != itemPtr->hour ) { 1082 log_err("ucal_add produced wrong hour %d when adding day across transition for zone %s\n", hr, itemPtr->zone); 1083 } else { 1084 ucal_add(cal, UCAL_DATE, -1, &status); 1085 hr = ucal_get(cal, UCAL_HOUR_OF_DAY, &status); 1086 if ( U_FAILURE(status) ) { 1087 log_err("ucal_add failed subtracting day across transition for zone %s: %s\n", itemPtr->zone, u_errorName(status)); 1088 } else if ( hr != itemPtr->hour ) { 1089 log_err("ucal_add produced wrong hour %d when subtracting day across transition for zone %s\n", hr, itemPtr->zone); 1090 } 1091 } 1092 ucal_close(cal); 1093 } 1094} 1095 1096/*------------------------------------------------------ */ 1097/*Testing the Limits for various Fields of Calendar*/ 1098static void TestGetLimits() 1099{ 1100 UCalendar *cal = 0; 1101 int32_t min, max, gr_min, le_max, ac_min, ac_max, val; 1102 UChar tzID[4]; 1103 UErrorCode status = U_ZERO_ERROR; 1104 1105 1106 u_uastrcpy(tzID, "PST"); 1107 /*open the calendar used */ 1108 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status);; 1109 if (U_FAILURE(status)) { 1110 log_data_err("ucal_open() for gregorian calendar failed in TestGetLimits: %s - (Are you missing data?)\n", u_errorName(status)); 1111 return; 1112 } 1113 1114 log_verbose("\nTesting the getLimits function for various fields\n"); 1115 1116 1117 1118 ucal_setDate(cal, 1999, UCAL_MARCH, 5, &status); /* Set the date to be March 5, 1999 */ 1119 val = ucal_get(cal, UCAL_DAY_OF_WEEK, &status); 1120 min = ucal_getLimit(cal, UCAL_DAY_OF_WEEK, UCAL_MINIMUM, &status); 1121 max = ucal_getLimit(cal, UCAL_DAY_OF_WEEK, UCAL_MAXIMUM, &status); 1122 if ( (min != UCAL_SUNDAY || max != UCAL_SATURDAY ) && (min > val && val > max) && (val != UCAL_FRIDAY)){ 1123 log_err("FAIL: Min/max bad\n"); 1124 log_err("FAIL: Day of week %d out of range\n", val); 1125 log_err("FAIL: FAIL: Day of week should be SUNDAY Got %d\n", val); 1126 } 1127 else 1128 log_verbose("getLimits successful\n"); 1129 1130 val = ucal_get(cal, UCAL_DAY_OF_WEEK_IN_MONTH, &status); 1131 min = ucal_getLimit(cal, UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_MINIMUM, &status); 1132 max = ucal_getLimit(cal, UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_MAXIMUM, &status); 1133 if ( (min != 0 || max != 5 ) && (min > val && val > max) && (val != 1)){ 1134 log_err("FAIL: Min/max bad\n"); 1135 log_err("FAIL: Day of week in month %d out of range\n", val); 1136 log_err("FAIL: FAIL: Day of week in month should be SUNDAY Got %d\n", val); 1137 1138 } 1139 else 1140 log_verbose("getLimits successful\n"); 1141 1142 min=ucal_getLimit(cal, UCAL_MONTH, UCAL_MINIMUM, &status); 1143 max=ucal_getLimit(cal, UCAL_MONTH, UCAL_MAXIMUM, &status); 1144 gr_min=ucal_getLimit(cal, UCAL_MONTH, UCAL_GREATEST_MINIMUM, &status); 1145 le_max=ucal_getLimit(cal, UCAL_MONTH, UCAL_LEAST_MAXIMUM, &status); 1146 ac_min=ucal_getLimit(cal, UCAL_MONTH, UCAL_ACTUAL_MINIMUM, &status); 1147 ac_max=ucal_getLimit(cal, UCAL_MONTH, UCAL_ACTUAL_MAXIMUM, &status); 1148 if(U_FAILURE(status)){ 1149 log_err("Error in getLimits: %s\n", u_errorName(status)); 1150 } 1151 if(min!=0 || max!=11 || gr_min!=0 || le_max!=11 || ac_min!=0 || ac_max!=11) 1152 log_err("There is and error in getLimits in fetching the values\n"); 1153 else 1154 log_verbose("getLimits successful\n"); 1155 1156 ucal_setDateTime(cal, 1999, UCAL_MARCH, 5, 4, 10, 35, &status); 1157 val=ucal_get(cal, UCAL_HOUR_OF_DAY, &status); 1158 min=ucal_getLimit(cal, UCAL_HOUR_OF_DAY, UCAL_MINIMUM, &status); 1159 max=ucal_getLimit(cal, UCAL_HOUR_OF_DAY, UCAL_MAXIMUM, &status); 1160 gr_min=ucal_getLimit(cal, UCAL_MINUTE, UCAL_GREATEST_MINIMUM, &status); 1161 le_max=ucal_getLimit(cal, UCAL_MINUTE, UCAL_LEAST_MAXIMUM, &status); 1162 ac_min=ucal_getLimit(cal, UCAL_MINUTE, UCAL_ACTUAL_MINIMUM, &status); 1163 ac_max=ucal_getLimit(cal, UCAL_SECOND, UCAL_ACTUAL_MAXIMUM, &status); 1164 if( (min!=0 || max!= 11 || gr_min!=0 || le_max!=60 || ac_min!=0 || ac_max!=60) && 1165 (min>val && val>max) && val!=4){ 1166 1167 log_err("FAIL: Min/max bad\n"); 1168 log_err("FAIL: Hour of Day %d out of range\n", val); 1169 log_err("FAIL: HOUR_OF_DAY should be 4 Got %d\n", val); 1170 } 1171 else 1172 log_verbose("getLimits successful\n"); 1173 1174 1175 /*get BOGUS_LIMIT type*/ 1176 val=ucal_getLimit(cal, UCAL_SECOND, (UCalendarLimitType)99, &status); 1177 if(val != -1){ 1178 log_err("FAIL: ucal_getLimit() with BOGUS type should return -1\n"); 1179 } 1180 status=U_ZERO_ERROR; 1181 1182 1183 ucal_close(cal); 1184} 1185 1186 1187 1188/* ------------------------------------- */ 1189 1190/** 1191 * Test that the days of the week progress properly when add is called repeatedly 1192 * for increments of 24 days. 1193 */ 1194static void TestDOWProgression() 1195{ 1196 int32_t initialDOW, DOW, newDOW, expectedDOW; 1197 UCalendar *cal = 0; 1198 UDateFormat *datfor = 0; 1199 UDate date1; 1200 int32_t delta=24; 1201 UErrorCode status = U_ZERO_ERROR; 1202 UChar tzID[4]; 1203 char tempMsgBuf[256]; 1204 u_strcpy(tzID, fgGMTID); 1205 /*open the calendar used */ 1206 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);; 1207 if (U_FAILURE(status)) { 1208 log_data_err("ucal_open failed: %s - (Are you missing data?)\n", u_errorName(status)); 1209 return; 1210 } 1211 1212 datfor=udat_open(UDAT_MEDIUM,UDAT_MEDIUM ,NULL, fgGMTID,-1,NULL, 0, &status); 1213 if(U_FAILURE(status)){ 1214 log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status)); 1215 } 1216 1217 1218 ucal_setDate(cal, 1999, UCAL_JANUARY, 1, &status); 1219 1220 log_verbose("\nTesting the DOW progression\n"); 1221 1222 initialDOW = ucal_get(cal, UCAL_DAY_OF_WEEK, &status); 1223 if (U_FAILURE(status)) { log_data_err("ucal_get() failed: %s (Are you missing data?)\n", u_errorName(status) ); return; } 1224 newDOW = initialDOW; 1225 do { 1226 DOW = newDOW; 1227 log_verbose("DOW = %d...\n", DOW); 1228 date1=ucal_getMillis(cal, &status); 1229 if(U_FAILURE(status)){ log_err("ucal_getMiilis() failed: %s\n", u_errorName(status)); return;} 1230 log_verbose("%s\n", u_austrcpy(tempMsgBuf, myDateFormat(datfor, date1))); 1231 1232 ucal_add(cal,UCAL_DAY_OF_WEEK, delta, &status); 1233 if (U_FAILURE(status)) { log_err("ucal_add() failed: %s\n", u_errorName(status)); return; } 1234 1235 newDOW = ucal_get(cal, UCAL_DAY_OF_WEEK, &status); 1236 if (U_FAILURE(status)) { log_err("ucal_get() failed: %s\n", u_errorName(status)); return; } 1237 expectedDOW = 1 + (DOW + delta - 1) % 7; 1238 date1=ucal_getMillis(cal, &status); 1239 if(U_FAILURE(status)){ log_err("ucal_getMiilis() failed: %s\n", u_errorName(status)); return;} 1240 if (newDOW != expectedDOW) { 1241 log_err("Day of week should be %d instead of %d on %s", expectedDOW, newDOW, 1242 u_austrcpy(tempMsgBuf, myDateFormat(datfor, date1)) ); 1243 return; 1244 } 1245 } 1246 while (newDOW != initialDOW); 1247 1248 ucal_close(cal); 1249 udat_close(datfor); 1250} 1251 1252/* ------------------------------------- */ 1253 1254/** 1255 * Confirm that the offset between local time and GMT behaves as expected. 1256 */ 1257static void TestGMTvsLocal() 1258{ 1259 log_verbose("\nTesting the offset between the GMT and local time\n"); 1260 testZones(1999, 1, 1, 12, 0, 0); 1261 testZones(1999, 4, 16, 18, 30, 0); 1262 testZones(1998, 12, 17, 19, 0, 0); 1263} 1264 1265/* ------------------------------------- */ 1266 1267static void testZones(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc) 1268{ 1269 int32_t offset,utc, expected; 1270 UCalendar *gmtcal = 0, *cal = 0; 1271 UDate date1; 1272 double temp; 1273 UDateFormat *datfor = 0; 1274 UErrorCode status = U_ZERO_ERROR; 1275 UChar tzID[4]; 1276 char tempMsgBuf[256]; 1277 1278 u_strcpy(tzID, fgGMTID); 1279 gmtcal=ucal_open(tzID, 3, "en_US", UCAL_TRADITIONAL, &status);; 1280 if (U_FAILURE(status)) { 1281 log_data_err("ucal_open failed: %s - (Are you missing data?)\n", u_errorName(status)); 1282 return; 1283 } 1284 u_uastrcpy(tzID, "PST"); 1285 cal = ucal_open(tzID, 3, "en_US", UCAL_TRADITIONAL, &status); 1286 if (U_FAILURE(status)) { 1287 log_err("ucal_open failed: %s\n", u_errorName(status)); 1288 return; 1289 } 1290 1291 datfor=udat_open(UDAT_MEDIUM,UDAT_MEDIUM ,NULL, fgGMTID,-1,NULL, 0, &status); 1292 if(U_FAILURE(status)){ 1293 log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status)); 1294 } 1295 1296 ucal_setDateTime(gmtcal, yr, mo - 1, dt, hr, mn, sc, &status); 1297 if (U_FAILURE(status)) { 1298 log_data_err("ucal_setDateTime failed: %s (Are you missing data?)\n", u_errorName(status)); 1299 return; 1300 } 1301 ucal_set(gmtcal, UCAL_MILLISECOND, 0); 1302 date1 = ucal_getMillis(gmtcal, &status); 1303 if (U_FAILURE(status)) { 1304 log_err("ucal_getMillis failed: %s\n", u_errorName(status)); 1305 return; 1306 } 1307 log_verbose("date = %s\n", u_austrcpy(tempMsgBuf, myDateFormat(datfor, date1)) ); 1308 1309 1310 ucal_setMillis(cal, date1, &status); 1311 if (U_FAILURE(status)) { 1312 log_err("ucal_setMillis() failed: %s\n", u_errorName(status)); 1313 return; 1314 } 1315 1316 offset = ucal_get(cal, UCAL_ZONE_OFFSET, &status); 1317 offset += ucal_get(cal, UCAL_DST_OFFSET, &status); 1318 1319 if (U_FAILURE(status)) { 1320 log_err("ucal_get() failed: %s\n", u_errorName(status)); 1321 return; 1322 } 1323 temp=(double)((double)offset / 1000.0 / 60.0 / 60.0); 1324 /*printf("offset for %s %f hr\n", austrdup(myDateFormat(datfor, date1)), temp);*/ 1325 1326 utc = ((ucal_get(cal, UCAL_HOUR_OF_DAY, &status) * 60 + 1327 ucal_get(cal, UCAL_MINUTE, &status)) * 60 + 1328 ucal_get(cal, UCAL_SECOND, &status)) * 1000 + 1329 ucal_get(cal, UCAL_MILLISECOND, &status) - offset; 1330 if (U_FAILURE(status)) { 1331 log_err("ucal_get() failed: %s\n", u_errorName(status)); 1332 return; 1333 } 1334 1335 expected = ((hr * 60 + mn) * 60 + sc) * 1000; 1336 if (utc != expected) { 1337 temp=(double)(utc - expected)/ 1000 / 60 / 60.0; 1338 log_err("FAIL: Discrepancy of %d millis = %fhr\n", utc-expected, temp ); 1339 } 1340 else 1341 log_verbose("PASS: the offset between local and GMT is correct\n"); 1342 ucal_close(gmtcal); 1343 ucal_close(cal); 1344 udat_close(datfor); 1345} 1346 1347/* ------------------------------------- */ 1348 1349 1350 1351 1352/* INTERNAL FUNCTIONS USED */ 1353/*------------------------------------------------------------------------------------------- */ 1354 1355/* ------------------------------------- */ 1356static void checkDateTime(UCalendar* c, 1357 int32_t y, int32_t m, int32_t d, 1358 int32_t hr, int32_t min, int32_t sec, 1359 int32_t ms, UCalendarDateFields field) 1360 1361{ 1362 UErrorCode status = U_ZERO_ERROR; 1363 if (ucal_get(c, UCAL_YEAR, &status) != y || 1364 ucal_get(c, UCAL_MONTH, &status) != m || 1365 ucal_get(c, UCAL_DATE, &status) != d || 1366 ucal_get(c, UCAL_HOUR, &status) != hr || 1367 ucal_get(c, UCAL_MINUTE, &status) != min || 1368 ucal_get(c, UCAL_SECOND, &status) != sec || 1369 ucal_get(c, UCAL_MILLISECOND, &status) != ms) { 1370 log_err("U_FAILURE for field %d, Expected y/m/d h:m:s:ms of %d/%d/%d %d:%d:%d:%d got %d/%d/%d %d:%d:%d:%d\n", 1371 (int32_t)field, y, m + 1, d, hr, min, sec, ms, 1372 ucal_get(c, UCAL_YEAR, &status), 1373 ucal_get(c, UCAL_MONTH, &status) + 1, 1374 ucal_get(c, UCAL_DATE, &status), 1375 ucal_get(c, UCAL_HOUR, &status), 1376 ucal_get(c, UCAL_MINUTE, &status) + 1, 1377 ucal_get(c, UCAL_SECOND, &status), 1378 ucal_get(c, UCAL_MILLISECOND, &status) ); 1379 1380 if (U_FAILURE(status)){ 1381 log_err("ucal_get failed: %s\n", u_errorName(status)); 1382 return; 1383 } 1384 1385 } 1386 else 1387 log_verbose("Confirmed: %d/%d/%d %d:%d:%d:%d\n", y, m + 1, d, hr, min, sec, ms); 1388 1389} 1390 1391/* ------------------------------------- */ 1392static void checkDate(UCalendar* c, int32_t y, int32_t m, int32_t d) 1393{ 1394 UErrorCode status = U_ZERO_ERROR; 1395 if (ucal_get(c,UCAL_YEAR, &status) != y || 1396 ucal_get(c, UCAL_MONTH, &status) != m || 1397 ucal_get(c, UCAL_DATE, &status) != d) { 1398 1399 log_err("FAILURE: Expected y/m/d of %d/%d/%d got %d/%d/%d\n", y, m + 1, d, 1400 ucal_get(c, UCAL_YEAR, &status), 1401 ucal_get(c, UCAL_MONTH, &status) + 1, 1402 ucal_get(c, UCAL_DATE, &status) ); 1403 1404 if (U_FAILURE(status)) { 1405 log_err("ucal_get failed: %s\n", u_errorName(status)); 1406 return; 1407 } 1408 } 1409 else 1410 log_verbose("Confirmed: %d/%d/%d\n", y, m + 1, d); 1411 1412 1413} 1414 1415/* ------------------------------------- */ 1416 1417/* ------------------------------------- */ 1418 1419static void verify1(const char* msg, UCalendar* c, UDateFormat* dat, int32_t year, int32_t month, int32_t day) 1420{ 1421 UDate d1; 1422 UErrorCode status = U_ZERO_ERROR; 1423 if (ucal_get(c, UCAL_YEAR, &status) == year && 1424 ucal_get(c, UCAL_MONTH, &status) == month && 1425 ucal_get(c, UCAL_DATE, &status) == day) { 1426 if (U_FAILURE(status)) { 1427 log_err("FAIL: Calendar::get failed: %s\n", u_errorName(status)); 1428 return; 1429 } 1430 log_verbose("PASS: %s\n", msg); 1431 d1=ucal_getMillis(c, &status); 1432 if (U_FAILURE(status)) { 1433 log_err("ucal_getMillis failed: %s\n", u_errorName(status)); 1434 return; 1435 } 1436 /*log_verbose(austrdup(myDateFormat(dat, d1)) );*/ 1437 } 1438 else { 1439 log_err("FAIL: %s\n", msg); 1440 d1=ucal_getMillis(c, &status); 1441 if (U_FAILURE(status)) { 1442 log_err("ucal_getMillis failed: %s\n", u_errorName(status) ); 1443 return; 1444 } 1445 log_err("Got %s Expected %d/%d/%d \n", austrdup(myDateFormat(dat, d1)), year, month + 1, day ); 1446 return; 1447 } 1448 1449 1450} 1451 1452/* ------------------------------------ */ 1453static void verify2(const char* msg, UCalendar* c, UDateFormat* dat, int32_t year, int32_t month, int32_t day, 1454 int32_t hour, int32_t min, int32_t sec, int32_t am_pm) 1455{ 1456 UDate d1; 1457 UErrorCode status = U_ZERO_ERROR; 1458 char tempMsgBuf[256]; 1459 1460 if (ucal_get(c, UCAL_YEAR, &status) == year && 1461 ucal_get(c, UCAL_MONTH, &status) == month && 1462 ucal_get(c, UCAL_DATE, &status) == day && 1463 ucal_get(c, UCAL_HOUR, &status) == hour && 1464 ucal_get(c, UCAL_MINUTE, &status) == min && 1465 ucal_get(c, UCAL_SECOND, &status) == sec && 1466 ucal_get(c, UCAL_AM_PM, &status) == am_pm ){ 1467 if (U_FAILURE(status)) { 1468 log_err("FAIL: Calendar::get failed: %s\n", u_errorName(status)); 1469 return; 1470 } 1471 log_verbose("PASS: %s\n", msg); 1472 d1=ucal_getMillis(c, &status); 1473 if (U_FAILURE(status)) { 1474 log_err("ucal_getMillis failed: %s\n", u_errorName(status)); 1475 return; 1476 } 1477 log_verbose("%s\n" , u_austrcpy(tempMsgBuf, myDateFormat(dat, d1)) ); 1478 } 1479 else { 1480 log_err("FAIL: %s\n", msg); 1481 d1=ucal_getMillis(c, &status); 1482 if (U_FAILURE(status)) { 1483 log_err("ucal_getMillis failed: %s\n", u_errorName(status)); 1484 return; 1485 } 1486 log_err("Got %s Expected %d/%d/%d/ %d:%d:%d %s\n", austrdup(myDateFormat(dat, d1)), 1487 year, month + 1, day, hour, min, sec, (am_pm==0) ? "AM": "PM"); 1488 1489 return; 1490 } 1491 1492 1493} 1494 1495void TestGregorianChange() { 1496 static const UChar utc[] = { 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0 }; /* "Etc/GMT" */ 1497 const int32_t dayMillis = 86400 * INT64_C(1000); /* 1 day = 86400 seconds */ 1498 UCalendar *cal; 1499 UDate date; 1500 UErrorCode errorCode = U_ZERO_ERROR; 1501 1502 /* Test ucal_setGregorianChange() on a Gregorian calendar. */ 1503 errorCode = U_ZERO_ERROR; 1504 cal = ucal_open(utc, -1, "", UCAL_GREGORIAN, &errorCode); 1505 if(U_FAILURE(errorCode)) { 1506 log_data_err("ucal_open(UTC) failed: %s - (Are you missing data?)\n", u_errorName(errorCode)); 1507 return; 1508 } 1509 ucal_setGregorianChange(cal, -365 * (dayMillis * (UDate)1), &errorCode); 1510 if(U_FAILURE(errorCode)) { 1511 log_err("ucal_setGregorianChange(1969) failed: %s\n", u_errorName(errorCode)); 1512 } else { 1513 date = ucal_getGregorianChange(cal, &errorCode); 1514 if(U_FAILURE(errorCode) || date != -365 * (dayMillis * (UDate)1)) { 1515 log_err("ucal_getGregorianChange() failed: %s, date = %f\n", u_errorName(errorCode), date); 1516 } 1517 } 1518 ucal_close(cal); 1519 1520 /* Test ucal_setGregorianChange() on a non-Gregorian calendar where it should fail. */ 1521 errorCode = U_ZERO_ERROR; 1522 cal = ucal_open(utc, -1, "th@calendar=buddhist", UCAL_TRADITIONAL, &errorCode); 1523 if(U_FAILURE(errorCode)) { 1524 log_err("ucal_open(UTC, non-Gregorian) failed: %s\n", u_errorName(errorCode)); 1525 return; 1526 } 1527 ucal_setGregorianChange(cal, -730 * (dayMillis * (UDate)1), &errorCode); 1528 if(errorCode != U_UNSUPPORTED_ERROR) { 1529 log_err("ucal_setGregorianChange(non-Gregorian calendar) did not yield U_UNSUPPORTED_ERROR but %s\n", 1530 u_errorName(errorCode)); 1531 } 1532 errorCode = U_ZERO_ERROR; 1533 date = ucal_getGregorianChange(cal, &errorCode); 1534 if(errorCode != U_UNSUPPORTED_ERROR) { 1535 log_err("ucal_getGregorianChange(non-Gregorian calendar) did not yield U_UNSUPPORTED_ERROR but %s\n", 1536 u_errorName(errorCode)); 1537 } 1538 ucal_close(cal); 1539} 1540 1541static void TestGetKeywordValuesForLocale() { 1542#define PREFERRED_SIZE 15 1543#define MAX_NUMBER_OF_KEYWORDS 4 1544 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS+1] = { 1545 { "root", "gregorian", NULL, NULL, NULL }, 1546 { "und", "gregorian", NULL, NULL, NULL }, 1547 { "en_US", "gregorian", NULL, NULL, NULL }, 1548 { "en_029", "gregorian", NULL, NULL, NULL }, 1549 { "th_TH", "buddhist", "gregorian", NULL, NULL }, 1550 { "und_TH", "buddhist", "gregorian", NULL, NULL }, 1551 { "en_TH", "buddhist", "gregorian", NULL, NULL }, 1552 { "he_IL", "gregorian", "hebrew", "islamic", "islamic-civil" }, 1553 { "ar_EG", "gregorian", "coptic", "islamic", "islamic-civil" }, 1554 { "ja", "gregorian", "japanese", NULL, NULL }, 1555 { "ps_Guru_IN", "gregorian", "indian", NULL, NULL }, 1556 { "th@calendar=gregorian", "buddhist", "gregorian", NULL, NULL }, 1557 { "en@calendar=islamic", "gregorian", NULL, NULL, NULL }, 1558 { "zh_TW", "gregorian", "roc", "chinese", NULL }, 1559 { "ar_IR", "persian", "gregorian", "islamic", "islamic-civil" }, 1560 }; 1561 const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 1, 1, 1, 1, 2, 2, 2, 4, 4, 2, 2, 2, 1, 3, 4 }; 1562 UErrorCode status = U_ZERO_ERROR; 1563 int32_t i, size, j; 1564 UEnumeration *all, *pref; 1565 const char *loc = NULL; 1566 UBool matchPref, matchAll; 1567 const char *value; 1568 int32_t valueLength; 1569 UList *ALLList = NULL; 1570 1571 UEnumeration *ALL = ucal_getKeywordValuesForLocale("calendar", uloc_getDefault(), FALSE, &status); 1572 if (U_SUCCESS(status)) { 1573 for (i = 0; i < PREFERRED_SIZE; i++) { 1574 pref = NULL; 1575 all = NULL; 1576 loc = PREFERRED[i][0]; 1577 pref = ucal_getKeywordValuesForLocale("calendar", loc, TRUE, &status); 1578 matchPref = FALSE; 1579 matchAll = FALSE; 1580 1581 value = NULL; 1582 valueLength = 0; 1583 1584 if (U_SUCCESS(status) && uenum_count(pref, &status) == EXPECTED_SIZE[i]) { 1585 matchPref = TRUE; 1586 for (j = 0; j < EXPECTED_SIZE[i]; j++) { 1587 if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) { 1588 if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) { 1589 matchPref = FALSE; 1590 break; 1591 } 1592 } else { 1593 matchPref = FALSE; 1594 log_err("ERROR getting keyword value for locale \"%s\"\n", loc); 1595 break; 1596 } 1597 } 1598 } 1599 1600 if (!matchPref) { 1601 log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc); 1602 break; 1603 } 1604 uenum_close(pref); 1605 1606 all = ucal_getKeywordValuesForLocale("calendar", loc, FALSE, &status); 1607 1608 size = uenum_count(all, &status); 1609 1610 if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) { 1611 matchAll = TRUE; 1612 ALLList = ulist_getListFromEnum(ALL); 1613 for (j = 0; j < size; j++) { 1614 if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) { 1615 if (!ulist_containsString(ALLList, value, uprv_strlen(value))) { 1616 log_err("Locale %s have %s not in ALL\n", loc, value); 1617 matchAll = FALSE; 1618 break; 1619 } 1620 } else { 1621 matchAll = FALSE; 1622 log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc); 1623 break; 1624 } 1625 } 1626 } 1627 if (!matchAll) { 1628 log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc); 1629 } 1630 1631 uenum_close(all); 1632 } 1633 } else { 1634 log_err_status(status, "Failed to get ALL keyword values for default locale %s: %s.\n", uloc_getDefault(), u_errorName(status)); 1635 } 1636 uenum_close(ALL); 1637} 1638 1639/* 1640 * Weekend tests, ported from 1641 * icu4j/trunk/main/tests/core/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java 1642 * and extended a bit. Notes below from IBMCalendarTest.java ... 1643 * This test tests for specific locale data. This is probably okay 1644 * as far as US data is concerned, but if the Arabic/Yemen data 1645 * changes, this test will have to be updated. 1646 */ 1647 1648typedef struct { 1649 int32_t year; 1650 int32_t month; 1651 int32_t day; 1652 int32_t hour; 1653 int32_t millisecOffset; 1654 UBool isWeekend; 1655} TestWeekendDates; 1656typedef struct { 1657 const char * locale; 1658 const TestWeekendDates * dates; 1659 int32_t numDates; 1660} TestWeekendDatesList; 1661 1662static const TestWeekendDates weekendDates_en_US[] = { 1663 { 2000, UCAL_MARCH, 17, 23, 0, 0 }, /* Fri 23:00 */ 1664 { 2000, UCAL_MARCH, 18, 0, -1, 0 }, /* Fri 23:59:59.999 */ 1665 { 2000, UCAL_MARCH, 18, 0, 0, 1 }, /* Sat 00:00 */ 1666 { 2000, UCAL_MARCH, 18, 15, 0, 1 }, /* Sat 15:00 */ 1667 { 2000, UCAL_MARCH, 19, 23, 0, 1 }, /* Sun 23:00 */ 1668 { 2000, UCAL_MARCH, 20, 0, -1, 1 }, /* Sun 23:59:59.999 */ 1669 { 2000, UCAL_MARCH, 20, 0, 0, 0 }, /* Mon 00:00 */ 1670 { 2000, UCAL_MARCH, 20, 8, 0, 0 }, /* Mon 08:00 */ 1671}; 1672static const TestWeekendDates weekendDates_ar_YE[] = { 1673 { 2000, UCAL_MARCH, 15, 23, 0, 0 }, /* Wed 23:00 */ 1674 { 2000, UCAL_MARCH, 16, 0, -1, 0 }, /* Wed 23:59:59.999 */ 1675 { 2000, UCAL_MARCH, 16, 0, 0, 1 }, /* Thu 00:00 */ 1676 { 2000, UCAL_MARCH, 16, 15, 0, 1 }, /* Thu 15:00 */ 1677 { 2000, UCAL_MARCH, 17, 23, 0, 1 }, /* Fri 23:00 */ 1678 { 2000, UCAL_MARCH, 18, 0, -1, 1 }, /* Fri 23:59:59.999 */ 1679 { 2000, UCAL_MARCH, 18, 0, 0, 0 }, /* Sat 00:00 */ 1680 { 2000, UCAL_MARCH, 18, 8, 0, 0 }, /* Sat 08:00 */ 1681}; 1682static const TestWeekendDatesList testDates[] = { 1683 { "en_US", weekendDates_en_US, sizeof(weekendDates_en_US)/sizeof(weekendDates_en_US[0]) }, 1684 { "ar_YE", weekendDates_ar_YE, sizeof(weekendDates_ar_YE)/sizeof(weekendDates_ar_YE[0]) }, 1685}; 1686 1687typedef struct { 1688 UCalendarDaysOfWeek dayOfWeek; 1689 UCalendarWeekdayType dayType; 1690 int32_t transition; /* transition time if dayType is UCAL_WEEKEND_ONSET or UCAL_WEEKEND_CEASE; else must be 0 */ 1691} TestDaysOfWeek; 1692typedef struct { 1693 const char * locale; 1694 const TestDaysOfWeek * days; 1695 int32_t numDays; 1696} TestDaysOfWeekList; 1697 1698static const TestDaysOfWeek daysOfWeek_en_US[] = { 1699 { UCAL_MONDAY, UCAL_WEEKDAY, 0 }, 1700 { UCAL_FRIDAY, UCAL_WEEKDAY, 0 }, 1701 { UCAL_SATURDAY, UCAL_WEEKEND, 0 }, 1702 { UCAL_SUNDAY, UCAL_WEEKEND_CEASE, 86400000 }, 1703}; 1704static const TestDaysOfWeek daysOfWeek_ar_YE[] = { /* Thursday:Friday */ 1705 { UCAL_WEDNESDAY,UCAL_WEEKDAY, 0 }, 1706 { UCAL_SATURDAY, UCAL_WEEKDAY, 0 }, 1707 { UCAL_THURSDAY, UCAL_WEEKEND, 0 }, 1708 { UCAL_FRIDAY, UCAL_WEEKEND_CEASE, 86400000 }, 1709}; 1710static const TestDaysOfWeekList testDays[] = { 1711 { "en_US", daysOfWeek_en_US, sizeof(daysOfWeek_en_US)/sizeof(daysOfWeek_en_US[0]) }, 1712 { "ar_YE", daysOfWeek_ar_YE, sizeof(daysOfWeek_ar_YE)/sizeof(daysOfWeek_ar_YE[0]) }, 1713}; 1714 1715static const UChar logDateFormat[] = { 0x0045,0x0045,0x0045,0x0020,0x004D,0x004D,0x004D,0x0020,0x0064,0x0064,0x0020,0x0079, 1716 0x0079,0x0079,0x0079,0x0020,0x0047,0x0020,0x0048,0x0048,0x003A,0x006D,0x006D,0x003A, 1717 0x0073,0x0073,0x002E,0x0053,0x0053,0x0053,0 }; /* "EEE MMM dd yyyy G HH:mm:ss.SSS" */ 1718enum { kFormattedDateMax = 2*sizeof(logDateFormat)/sizeof(logDateFormat[0]) }; 1719 1720static void TestWeekend() { 1721 const TestWeekendDatesList * testDatesPtr = testDates; 1722 const TestDaysOfWeekList * testDaysPtr = testDays; 1723 int32_t count, subCount; 1724 1725 UErrorCode fmtStatus = U_ZERO_ERROR; 1726 UDateFormat * fmt = udat_open(UDAT_NONE, UDAT_NONE, "en", NULL, 0, NULL, 0, &fmtStatus); 1727 if (U_SUCCESS(fmtStatus)) { 1728 udat_applyPattern(fmt, FALSE, logDateFormat, -1); 1729 } else { 1730 log_data_err("Unable to create UDateFormat - %s\n", u_errorName(fmtStatus)); 1731 return; 1732 } 1733 for (count = sizeof(testDates)/sizeof(testDates[0]); count-- > 0; ++testDatesPtr) { 1734 UErrorCode status = U_ZERO_ERROR; 1735 UCalendar * cal = ucal_open(NULL, 0, testDatesPtr->locale, UCAL_GREGORIAN, &status); 1736 log_verbose("locale: %s\n", testDatesPtr->locale); 1737 if (U_SUCCESS(status)) { 1738 const TestWeekendDates * weekendDatesPtr = testDatesPtr->dates; 1739 for (subCount = testDatesPtr->numDates; subCount--; ++weekendDatesPtr) { 1740 UDate dateToTest; 1741 UBool isWeekend; 1742 char fmtDateBytes[kFormattedDateMax] = "<could not format test date>"; /* initialize for failure */ 1743 1744 ucal_clear(cal); 1745 ucal_setDateTime(cal, weekendDatesPtr->year, weekendDatesPtr->month, weekendDatesPtr->day, 1746 weekendDatesPtr->hour, 0, 0, &status); 1747 dateToTest = ucal_getMillis(cal, &status) + weekendDatesPtr->millisecOffset; 1748 isWeekend = ucal_isWeekend(cal, dateToTest, &status); 1749 if (U_SUCCESS(fmtStatus)) { 1750 UChar fmtDate[kFormattedDateMax]; 1751 (void)udat_format(fmt, dateToTest, fmtDate, kFormattedDateMax, NULL, &fmtStatus); 1752 if (U_SUCCESS(fmtStatus)) { 1753 u_austrncpy(fmtDateBytes, fmtDate, kFormattedDateMax); 1754 fmtDateBytes[kFormattedDateMax-1] = 0; 1755 } else { 1756 fmtStatus = U_ZERO_ERROR; 1757 } 1758 } 1759 if ( U_FAILURE(status) ) { 1760 log_err("FAIL: locale %s date %s isWeekend() status %s\n", testDatesPtr->locale, fmtDateBytes, u_errorName(status) ); 1761 status = U_ZERO_ERROR; 1762 } else if ( (isWeekend!=0) != (weekendDatesPtr->isWeekend!=0) ) { 1763 log_err("FAIL: locale %s date %s isWeekend %d, expected the opposite\n", testDatesPtr->locale, fmtDateBytes, isWeekend ); 1764 } else { 1765 log_verbose("OK: locale %s date %s isWeekend %d\n", testDatesPtr->locale, fmtDateBytes, isWeekend ); 1766 } 1767 } 1768 ucal_close(cal); 1769 } else { 1770 log_data_err("FAIL: ucal_open for locale %s failed: %s - (Are you missing data?)\n", testDatesPtr->locale, u_errorName(status) ); 1771 } 1772 } 1773 if (U_SUCCESS(fmtStatus)) { 1774 udat_close(fmt); 1775 } 1776 1777 for (count = sizeof(testDays)/sizeof(testDays[0]); count-- > 0; ++testDaysPtr) { 1778 UErrorCode status = U_ZERO_ERROR; 1779 UCalendar * cal = ucal_open(NULL, 0, testDaysPtr->locale, UCAL_GREGORIAN, &status); 1780 log_verbose("locale: %s\n", testDaysPtr->locale); 1781 if (U_SUCCESS(status)) { 1782 const TestDaysOfWeek * daysOfWeekPtr = testDaysPtr->days; 1783 for (subCount = testDaysPtr->numDays; subCount--; ++daysOfWeekPtr) { 1784 int32_t transition = 0; 1785 UCalendarWeekdayType dayType = ucal_getDayOfWeekType(cal, daysOfWeekPtr->dayOfWeek, &status); 1786 if ( dayType == UCAL_WEEKEND_ONSET || dayType == UCAL_WEEKEND_CEASE ) { 1787 transition = ucal_getWeekendTransition(cal, daysOfWeekPtr->dayOfWeek, &status); 1788 } 1789 if ( U_FAILURE(status) ) { 1790 log_err("FAIL: locale %s DOW %d getDayOfWeekType() status %s\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, u_errorName(status) ); 1791 status = U_ZERO_ERROR; 1792 } else if ( dayType != daysOfWeekPtr->dayType || transition != daysOfWeekPtr->transition ) { 1793 log_err("FAIL: locale %s DOW %d type %d, expected %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType, daysOfWeekPtr->dayType ); 1794 } else { 1795 log_verbose("OK: locale %s DOW %d type %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType ); 1796 } 1797 } 1798 ucal_close(cal); 1799 } else { 1800 log_data_err("FAIL: ucal_open for locale %s failed: %s - (Are you missing data?)\n", testDaysPtr->locale, u_errorName(status) ); 1801 } 1802 } 1803} 1804 1805/** 1806 * TestFieldDifference 1807 */ 1808 1809typedef struct { 1810 const UChar * timezone; 1811 const char * locale; 1812 UDate start; 1813 UDate target; 1814 UBool progressive; /* TRUE to compute progressive difference for each field, FALSE to reset calendar after each call */ 1815 int32_t yDiff; 1816 int32_t MDiff; 1817 int32_t dDiff; 1818 int32_t HDiff; 1819 int32_t mDiff; 1820 int32_t sDiff; /* 0x7FFFFFFF indicates overflow error expected */ 1821} TFDItem; 1822 1823static const UChar tzUSPacific[] = { 0x55,0x53,0x2F,0x50,0x61,0x63,0x69,0x66,0x69,0x63,0 }; /* "US/Pacific" */ 1824static const UChar tzGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */ 1825 1826static const TFDItem tfdItems[] = { 1827 /* timezone locale start target progres yDf MDf dDf HDf mDf sDf */ 1828 /* For these we compute the progressive difference for each field - not resetting the calendar after each call */ 1829 { tzUSPacific, "en_US", 1267459800000.0, 1277772600000.0, TRUE, 0, 3, 27, 9, 40, 0 }, /* 2010-Mar-01 08:10 -> 2010-Jun-28 17:50 */ 1830 { tzUSPacific, "en_US", 1267459800000.0, 1299089280000.0, TRUE, 1, 0, 1, 1, 58, 0 }, /* 2010-Mar-01 08:10 -> 2011-Mar-02 10:08 */ 1831 /* For these we compute the total difference for each field - resetting the calendar after each call */ 1832 { tzGMT, "en_US", 0.0, 1073692800000.0, FALSE, 34, 408, 12427, 298248, 17894880, 1073692800 }, /* 1970-Jan-01 00:00 -> 2004-Jan-10 00:00 */ 1833 { tzGMT, "en_US", 0.0, 1073779200000.0, FALSE, 34, 408, 12428, 298272, 17896320, 1073779200 }, /* 1970-Jan-01 00:00 -> 2004-Jan-11 00:00 */ 1834 { tzGMT, "en_US", 0.0, 2147472000000.0, FALSE, 68, 816, 24855, 596520, 35791200, 2147472000 }, /* 1970-Jan-01 00:00 -> 2038-Jan-19 00:00 */ 1835 { tzGMT, "en_US", 0.0, 2147558400000.0, FALSE, 68, 816, 24856, 596544, 35792640, 0x7FFFFFFF }, /* 1970-Jan-01 00:00 -> 2038-Jan-20 00:00, seconds diff overflow */ 1836 { tzGMT, "en_US", 0.0, -1073692800000.0, FALSE, -34,-408,-12427,-298248,-17894880,-1073692800 }, /* 1970-Jan-01 00:00 -> 1935-Dec-24 00:00 */ 1837 { tzGMT, "en_US", 0.0, -1073779200000.0, FALSE, -34,-408,-12428,-298272,-17896320,-1073779200 }, /* 1970-Jan-01 00:00 -> 1935-Dec-23 00:00 */ 1838 /* check fwd/backward on either side of era boundary and across era boundary */ 1839 { tzGMT, "en_US", -61978089600000.0,-61820409600000.0, FALSE, 4, 59, 1825, 43800, 2628000, 157680000 }, /* CE 5-Dec-31 00:00 -> CE 10-Dec-30 00:00 */ 1840 { tzGMT, "en_US", -61820409600000.0,-61978089600000.0, FALSE, -4, -59, -1825, -43800, -2628000, -157680000 }, /* CE 10-Dec-30 00:00 -> CE 5-Dec-31 00:00 */ 1841 { tzGMT, "en_US", -62451129600000.0,-62293449600000.0, FALSE, 4, 59, 1825, 43800, 2628000, 157680000 }, /* BCE 10-Jan-04 00:00 -> BCE 5-Jan-03 00:00 */ 1842 { tzGMT, "en_US", -62293449600000.0,-62451129600000.0, FALSE, -4, -59, -1825, -43800, -2628000, -157680000 }, /* BCE 5-Jan-03 00:00 -> BCE 10-Jan-04 00:00 */ 1843 { tzGMT, "en_US", -62293449600000.0,-61978089600000.0, FALSE, 9, 119, 3650, 87600, 5256000, 315360000 }, /* BCE 5-Jan-03 00:00 -> CE 5-Dec-31 00:00 */ 1844 { tzGMT, "en_US", -61978089600000.0,-62293449600000.0, FALSE, -9,-119, -3650, -87600, -5256000, -315360000 }, /* CE 5-Dec-31 00:00 -> BCE 5-Jan-03 00:00 */ 1845 { tzGMT, "en@calendar=roc", -1672704000000.0, -1515024000000.0, FALSE, 4, 59, 1825, 43800, 2628000, 157680000 }, /* MG 5-Dec-30 00:00 -> MG 10-Dec-29 00:00 */ 1846 { tzGMT, "en@calendar=roc", -1515024000000.0, -1672704000000.0, FALSE, -4, -59, -1825, -43800, -2628000, -157680000 }, /* MG 10-Dec-29 00:00 -> MG 5-Dec-30 00:00 */ 1847 { tzGMT, "en@calendar=roc", -2145744000000.0, -1988064000000.0, FALSE, 4, 59, 1825, 43800, 2628000, 157680000 }, /* BMG 10-Jan-03 00:00 -> BMG 5-Jan-02 00:00 */ 1848 { tzGMT, "en@calendar=roc", -1988064000000.0, -2145744000000.0, FALSE, -4, -59, -1825, -43800, -2628000, -157680000 }, /* BMG 5-Jan-02 00:00 -> BMG 10-Jan-03 00:00 */ 1849 { tzGMT, "en@calendar=roc", -1988064000000.0, -1672704000000.0, FALSE, 9, 119, 3650, 87600, 5256000, 315360000 }, /* BMG 5-Jan-02 00:00 -> MG 5-Dec-30 00:00 */ 1850 { tzGMT, "en@calendar=roc", -1672704000000.0, -1988064000000.0, FALSE, -9,-119, -3650, -87600, -5256000, -315360000 }, /* MG 5-Dec-30 00:00 -> BMG 5-Jan-02 00:00 */ 1851 { tzGMT, "en@calendar=coptic",-53026531200000.0,-52868851200000.0, FALSE, 4, 64, 1825, 43800, 2628000, 157680000 }, /* Er1 5-Nas-05 00:00 -> Er1 10-Nas-04 00:00 */ 1852 { tzGMT, "en@calendar=coptic",-52868851200000.0,-53026531200000.0, FALSE, -4, -64, -1825, -43800, -2628000, -157680000 }, /* Er1 10-Nas-04 00:00 -> Er1 5-Nas-05 00:00 */ 1853 { tzGMT, "en@calendar=coptic",-53499571200000.0,-53341891200000.0, FALSE, 4, 64, 1825, 43800, 2628000, 157680000 }, /* Er0 10-Tou-04 00:00 -> Er0 5-Tou-02 00:00 */ 1854 { tzGMT, "en@calendar=coptic",-53341891200000.0,-53499571200000.0, FALSE, -4, -64, -1825, -43800, -2628000, -157680000 }, /* Er0 5-Tou-02 00:00 -> Er0 10-Tou-04 00:00 */ 1855 { tzGMT, "en@calendar=coptic",-53341891200000.0,-53026531200000.0, FALSE, 9, 129, 3650, 87600, 5256000, 315360000 }, /* Er0 5-Tou-02 00:00 -> Er1 5-Nas-05 00:00 */ 1856 { tzGMT, "en@calendar=coptic",-53026531200000.0,-53341891200000.0, FALSE, -9,-129, -3650, -87600, -5256000, -315360000 }, /* Er1 5-Nas-05 00:00 -> Er0 5-Tou-02 00:00 */ 1857 { NULL, NULL, 0.0, 0.0, FALSE, 0, 0, 0, 0, 0, 0 } /* terminator */ 1858}; 1859 1860void TestFieldDifference() { 1861 const TFDItem * tfdItemPtr; 1862 for (tfdItemPtr = tfdItems; tfdItemPtr->timezone != NULL; tfdItemPtr++) { 1863 UErrorCode status = U_ZERO_ERROR; 1864 UCalendar* ucal = ucal_open(tfdItemPtr->timezone, -1, tfdItemPtr->locale, UCAL_DEFAULT, &status); 1865 if (U_FAILURE(status)) { 1866 log_err("FAIL: for locale \"%s\", ucal_open had status %s\n", tfdItemPtr->locale, u_errorName(status) ); 1867 } else { 1868 int32_t yDf, MDf, dDf, HDf, mDf, sDf; 1869 if (tfdItemPtr->progressive) { 1870 ucal_setMillis(ucal, tfdItemPtr->start, &status); 1871 yDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_YEAR, &status); 1872 MDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MONTH, &status); 1873 dDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_DATE, &status); 1874 HDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_HOUR, &status); 1875 mDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MINUTE, &status); 1876 sDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_SECOND, &status); 1877 if (U_FAILURE(status)) { 1878 log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, ucal_setMillis or ucal_getFieldDifference had status %s\n", 1879 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, u_errorName(status) ); 1880 } else if ( yDf != tfdItemPtr->yDiff || 1881 MDf != tfdItemPtr->MDiff || 1882 dDf != tfdItemPtr->dDiff || 1883 HDf != tfdItemPtr->HDiff || 1884 mDf != tfdItemPtr->mDiff || 1885 sDf != tfdItemPtr->sDiff ) { 1886 log_data_err("FAIL: for locale \"%s\", start %.1f, target %.1f, expected y-M-d-H-m-s progressive diffs %d-%d-%d-%d-%d-%d, got %d-%d-%d-%d-%d-%d\n", 1887 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, 1888 tfdItemPtr->yDiff, tfdItemPtr->MDiff, tfdItemPtr->dDiff, tfdItemPtr->HDiff, tfdItemPtr->mDiff, tfdItemPtr->sDiff, 1889 yDf, MDf, dDf, HDf, mDf, sDf); 1890 } 1891 } else { 1892 ucal_setMillis(ucal, tfdItemPtr->start, &status); 1893 yDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_YEAR, &status); 1894 ucal_setMillis(ucal, tfdItemPtr->start, &status); 1895 MDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MONTH, &status); 1896 ucal_setMillis(ucal, tfdItemPtr->start, &status); 1897 dDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_DATE, &status); 1898 ucal_setMillis(ucal, tfdItemPtr->start, &status); 1899 HDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_HOUR, &status); 1900 ucal_setMillis(ucal, tfdItemPtr->start, &status); 1901 mDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MINUTE, &status); 1902 if (U_FAILURE(status)) { 1903 log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, ucal_setMillis or ucal_getFieldDifference (y-M-d-H-m) had status %s\n", 1904 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, u_errorName(status) ); 1905 } else if ( yDf != tfdItemPtr->yDiff || 1906 MDf != tfdItemPtr->MDiff || 1907 dDf != tfdItemPtr->dDiff || 1908 HDf != tfdItemPtr->HDiff || 1909 mDf != tfdItemPtr->mDiff ) { 1910 log_data_err("FAIL: for locale \"%s\", start %.1f, target %.1f, expected y-M-d-H-m total diffs %d-%d-%d-%d-%d, got %d-%d-%d-%d-%d\n", 1911 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, 1912 tfdItemPtr->yDiff, tfdItemPtr->MDiff, tfdItemPtr->dDiff, tfdItemPtr->HDiff, tfdItemPtr->mDiff, 1913 yDf, MDf, dDf, HDf, mDf); 1914 } 1915 ucal_setMillis(ucal, tfdItemPtr->start, &status); 1916 sDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_SECOND, &status); 1917 if (tfdItemPtr->sDiff != 0x7FFFFFFF) { 1918 if (U_FAILURE(status)) { 1919 log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, ucal_setMillis or ucal_getFieldDifference (seconds) had status %s\n", 1920 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, u_errorName(status) ); 1921 } else if (sDf != tfdItemPtr->sDiff) { 1922 log_data_err("FAIL: for locale \"%s\", start %.1f, target %.1f, expected seconds progressive diff %d, got %d\n", 1923 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, tfdItemPtr->sDiff, sDf); 1924 } 1925 } else if (!U_FAILURE(status)) { 1926 log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, for ucal_getFieldDifference (seconds) expected overflow error, got none\n", 1927 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target ); 1928 } 1929 } 1930 ucal_close(ucal); 1931 } 1932 } 1933} 1934 1935void TestAmbiguousWallTime() { 1936 UErrorCode status = U_ZERO_ERROR; 1937 UChar tzID[32]; 1938 UCalendar* ucal; 1939 UDate t, expected; 1940 1941 u_uastrcpy(tzID, "America/New_York"); 1942 ucal = ucal_open(tzID, -1, NULL, UCAL_DEFAULT, &status); 1943 if (U_FAILURE(status)) { 1944 log_err("FAIL: Failed to create a calendar"); 1945 return; 1946 } 1947 1948 if (ucal_getAttribute(ucal, UCAL_REPEATED_WALL_TIME) != UCAL_WALLTIME_LAST) { 1949 log_err("FAIL: Default UCAL_REPEATED_WALL_TIME value is not UCAL_WALLTIME_LAST"); 1950 } 1951 1952 if (ucal_getAttribute(ucal, UCAL_SKIPPED_WALL_TIME) != UCAL_WALLTIME_LAST) { 1953 log_err("FAIL: Default UCAL_SKIPPED_WALL_TIME value is not UCAL_WALLTIME_LAST"); 1954 } 1955 1956 /* UCAL_WALLTIME_FIRST on US fall transition */ 1957 ucal_setAttribute(ucal, UCAL_REPEATED_WALL_TIME, UCAL_WALLTIME_FIRST); 1958 ucal_clear(ucal); 1959 ucal_setDateTime(ucal, 2011, 11-1, 6, 1, 30, 0, &status); 1960 t = ucal_getMillis(ucal, &status); 1961 expected = 1320557400000.0; /* 2011-11-06T05:30:00Z */ 1962 if (U_FAILURE(status)) { 1963 log_err("FAIL: Calculating time 2011-11-06 01:30:00 with UCAL_WALLTIME_FIRST - %s\n", u_errorName(status)); 1964 status = U_ZERO_ERROR; 1965 } else if (t != expected) { 1966 log_data_err("FAIL: 2011-11-06 01:30:00 with UCAL_WALLTIME_FIRST - got: %f, expected: %f\n", t, expected); 1967 } 1968 1969 /* UCAL_WALLTIME_LAST on US fall transition */ 1970 ucal_setAttribute(ucal, UCAL_REPEATED_WALL_TIME, UCAL_WALLTIME_LAST); 1971 ucal_clear(ucal); 1972 ucal_setDateTime(ucal, 2011, 11-1, 6, 1, 30, 0, &status); 1973 t = ucal_getMillis(ucal, &status); 1974 expected = 1320561000000.0; /* 2011-11-06T06:30:00Z */ 1975 if (U_FAILURE(status)) { 1976 log_err("FAIL: Calculating time 2011-11-06 01:30:00 with UCAL_WALLTIME_LAST - %s\n", u_errorName(status)); 1977 status = U_ZERO_ERROR; 1978 } else if (t != expected) { 1979 log_data_err("FAIL: 2011-11-06 01:30:00 with UCAL_WALLTIME_LAST - got: %f, expected: %f\n", t, expected); 1980 } 1981 1982 /* UCAL_WALLTIME_FIRST on US spring transition */ 1983 ucal_setAttribute(ucal, UCAL_SKIPPED_WALL_TIME, UCAL_WALLTIME_FIRST); 1984 ucal_clear(ucal); 1985 ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status); 1986 t = ucal_getMillis(ucal, &status); 1987 expected = 1299997800000.0; /* 2011-03-13T06:30:00Z */ 1988 if (U_FAILURE(status)) { 1989 log_err("FAIL: Calculating time 2011-03-13 02:30:00 with UCAL_WALLTIME_FIRST - %s\n", u_errorName(status)); 1990 status = U_ZERO_ERROR; 1991 } else if (t != expected) { 1992 log_data_err("FAIL: 2011-03-13 02:30:00 with UCAL_WALLTIME_FIRST - got: %f, expected: %f\n", t, expected); 1993 } 1994 1995 /* UCAL_WALLTIME_LAST on US spring transition */ 1996 ucal_setAttribute(ucal, UCAL_SKIPPED_WALL_TIME, UCAL_WALLTIME_LAST); 1997 ucal_clear(ucal); 1998 ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status); 1999 t = ucal_getMillis(ucal, &status); 2000 expected = 1300001400000.0; /* 2011-03-13T07:30:00Z */ 2001 if (U_FAILURE(status)) { 2002 log_err("FAIL: Calculating time 2011-03-13 02:30:00 with UCAL_WALLTIME_LAST - %s\n", u_errorName(status)); 2003 status = U_ZERO_ERROR; 2004 } else if (t != expected) { 2005 log_data_err("FAIL: 2011-03-13 02:30:00 with UCAL_WALLTIME_LAST - got: %f, expected: %f\n", t, expected); 2006 } 2007 2008 /* UCAL_WALLTIME_NEXT_VALID on US spring transition */ 2009 ucal_setAttribute(ucal, UCAL_SKIPPED_WALL_TIME, UCAL_WALLTIME_NEXT_VALID); 2010 ucal_clear(ucal); 2011 ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status); 2012 t = ucal_getMillis(ucal, &status); 2013 expected = 1299999600000.0; /* 2011-03-13T07:00:00Z */ 2014 if (U_FAILURE(status)) { 2015 log_err("FAIL: Calculating time 2011-03-13 02:30:00 with UCAL_WALLTIME_NEXT_VALID - %s\n", u_errorName(status)); 2016 status = U_ZERO_ERROR; 2017 } else if (t != expected) { 2018 log_data_err("FAIL: 2011-03-13 02:30:00 with UCAL_WALLTIME_NEXT_VALID - got: %f, expected: %f\n", t, expected); 2019 } 2020 2021 /* non-lenient on US spring transition */ 2022 ucal_setAttribute(ucal, UCAL_LENIENT, 0); 2023 ucal_clear(ucal); 2024 ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status); 2025 t = ucal_getMillis(ucal, &status); 2026 if (U_SUCCESS(status)) { 2027 /* must return error */ 2028 log_data_err("FAIL: Non-lenient did not fail with 2011-03-13 02:30:00\n"); 2029 status = U_ZERO_ERROR; 2030 } 2031 2032 ucal_close(ucal); 2033} 2034 2035/** 2036 * TestAddRollEra0AndEraBounds, for #9226 2037 */ 2038 2039 typedef struct { 2040 const char * locale; 2041 UBool era0YearsGoBackwards; /* until we have API to get this, per #9393 */ 2042 } EraTestItem; 2043 2044static const EraTestItem eraTestItems[] = { 2045 /* calendars with non-modern era 0 that goes backwards, max era == 1 */ 2046 { "en@calendar=gregorian", TRUE }, 2047 { "en@calendar=roc", TRUE }, 2048 { "en@calendar=coptic", TRUE }, 2049 /* calendars with non-modern era 0 that goes forwards, max era > 1 */ 2050 { "en@calendar=japanese", FALSE }, 2051 { "en@calendar=chinese", FALSE }, 2052 /* calendars with non-modern era 0 that goes forwards, max era == 1 */ 2053 { "en@calendar=ethiopic", FALSE }, 2054 /* calendars with only one era = 0, forwards */ 2055 { "en@calendar=buddhist", FALSE }, 2056 { "en@calendar=hebrew", FALSE }, 2057 { "en@calendar=islamic", FALSE }, 2058 { "en@calendar=indian", FALSE }, 2059 { "en@calendar=persian", FALSE }, 2060 { "en@calendar=ethiopic-amete-alem", FALSE }, 2061 { NULL, FALSE } 2062}; 2063 2064static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; 2065 2066void TestAddRollEra0AndEraBounds() { 2067 const EraTestItem * eraTestItemPtr; 2068 for (eraTestItemPtr = eraTestItems; eraTestItemPtr->locale != NULL; eraTestItemPtr++) { 2069 UErrorCode status = U_ZERO_ERROR; 2070 UCalendar *ucalTest = ucal_open(zoneGMT, -1, eraTestItemPtr->locale, UCAL_DEFAULT, &status); 2071 if ( U_SUCCESS(status) ) { 2072 int32_t yrBefore, yrAfter, yrMax, eraAfter, eraMax, eraNow; 2073 2074 status = U_ZERO_ERROR; 2075 ucal_clear(ucalTest); 2076 ucal_set(ucalTest, UCAL_YEAR, 2); 2077 ucal_set(ucalTest, UCAL_ERA, 0); 2078 yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status); 2079 ucal_add(ucalTest, UCAL_YEAR, 1, &status); 2080 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2081 if (U_FAILURE(status)) { 2082 log_err("FAIL: set era 0 year 2 then add 1 year and get year for %s, error %s\n", 2083 eraTestItemPtr->locale, u_errorName(status)); 2084 } else if ( (eraTestItemPtr->era0YearsGoBackwards && yrAfter>yrBefore) || 2085 (!eraTestItemPtr->era0YearsGoBackwards && yrAfter<yrBefore) ) { 2086 log_err("FAIL: era 0 add 1 year does not move forward in time for %s\n", eraTestItemPtr->locale); 2087 } 2088 2089 status = U_ZERO_ERROR; 2090 ucal_clear(ucalTest); 2091 ucal_set(ucalTest, UCAL_YEAR, 2); 2092 ucal_set(ucalTest, UCAL_ERA, 0); 2093 yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status); 2094 ucal_roll(ucalTest, UCAL_YEAR, 1, &status); 2095 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2096 if (U_FAILURE(status)) { 2097 log_err("FAIL: set era 0 year 2 then roll 1 year and get year for %s, error %s\n", 2098 eraTestItemPtr->locale, u_errorName(status)); 2099 } else if ( (eraTestItemPtr->era0YearsGoBackwards && yrAfter>yrBefore) || 2100 (!eraTestItemPtr->era0YearsGoBackwards && yrAfter<yrBefore) ) { 2101 log_err("FAIL: era 0 roll 1 year does not move forward in time for %s\n", eraTestItemPtr->locale); 2102 } 2103 2104 status = U_ZERO_ERROR; 2105 ucal_clear(ucalTest); 2106 ucal_set(ucalTest, UCAL_YEAR, 1); 2107 ucal_set(ucalTest, UCAL_ERA, 0); 2108 if (eraTestItemPtr->era0YearsGoBackwards) { 2109 ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* roll forward in time to era 0 boundary */ 2110 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2111 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status); 2112 if (U_FAILURE(status)) { 2113 log_err("FAIL: set era 0 year 1 then roll 1 year and get year,era for %s, error %s\n", 2114 eraTestItemPtr->locale, u_errorName(status)); 2115 /* all calendars with era0YearsGoBackwards have "unbounded" era0 year values, so we should pin at yr 1 */ 2116 } else if (eraAfter != 0 || yrAfter != 1) { 2117 log_err("FAIL: era 0 roll 1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n", 2118 eraTestItemPtr->locale, eraAfter, yrAfter); 2119 } 2120 } else { 2121 /* roll backward in time to where era 0 years go negative, except for the Chinese 2122 calendar, which uses negative eras instead of having years outside the range 1-60 */ 2123 const char * calType = ucal_getType(ucalTest, &status); 2124 ucal_roll(ucalTest, UCAL_YEAR, -2, &status); 2125 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2126 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status); 2127 if (U_FAILURE(status)) { 2128 log_err("FAIL: set era 0 year 1 then roll -2 years and get year,era for %s, error %s\n", 2129 eraTestItemPtr->locale, u_errorName(status)); 2130 } else if ( uprv_strcmp(calType,"chinese")!=0 && (eraAfter != 0 || yrAfter != -1) ) { 2131 log_err("FAIL: era 0 roll -2 years from year 1 does not stay within era or produce year -1 for %s (get era %d year %d)\n", 2132 eraTestItemPtr->locale, eraAfter, yrAfter); 2133 } 2134 } 2135 2136 status = U_ZERO_ERROR; 2137 ucal_clear(ucalTest); 2138 { 2139 int32_t eraMin = ucal_getLimit(ucalTest, UCAL_ERA, UCAL_MINIMUM, &status); 2140 const char * calType = ucal_getType(ucalTest, &status); 2141 if (eraMin != 0 && uprv_strcmp(calType, "chinese") != 0) { 2142 log_err("FAIL: ucal_getLimit returns minimum era %d (should be 0) for calType %s, error %s\n", eraMin, calType, u_errorName(status)); 2143 } 2144 } 2145 2146 status = U_ZERO_ERROR; 2147 ucal_clear(ucalTest); 2148 ucal_set(ucalTest, UCAL_YEAR, 1); 2149 ucal_set(ucalTest, UCAL_ERA, 0); 2150 eraMax = ucal_getLimit(ucalTest, UCAL_ERA, UCAL_MAXIMUM, &status); 2151 if ( U_SUCCESS(status) && eraMax > 0 ) { 2152 /* try similar tests for era 1 (if calendar has it), in which years always go forward */ 2153 status = U_ZERO_ERROR; 2154 ucal_clear(ucalTest); 2155 ucal_set(ucalTest, UCAL_YEAR, 2); 2156 ucal_set(ucalTest, UCAL_ERA, 1); 2157 yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status); 2158 ucal_add(ucalTest, UCAL_YEAR, 1, &status); 2159 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2160 if (U_FAILURE(status)) { 2161 log_err("FAIL: set era 1 year 2 then add 1 year and get year for %s, error %s\n", 2162 eraTestItemPtr->locale, u_errorName(status)); 2163 } else if ( yrAfter<yrBefore ) { 2164 log_err("FAIL: era 1 add 1 year does not move forward in time for %s\n", eraTestItemPtr->locale); 2165 } 2166 2167 status = U_ZERO_ERROR; 2168 ucal_clear(ucalTest); 2169 ucal_set(ucalTest, UCAL_YEAR, 2); 2170 ucal_set(ucalTest, UCAL_ERA, 1); 2171 yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status); 2172 ucal_roll(ucalTest, UCAL_YEAR, 1, &status); 2173 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2174 if (U_FAILURE(status)) { 2175 log_err("FAIL: set era 1 year 2 then roll 1 year and get year for %s, error %s\n", 2176 eraTestItemPtr->locale, u_errorName(status)); 2177 } else if ( yrAfter<yrBefore ) { 2178 log_err("FAIL: era 1 roll 1 year does not move forward in time for %s\n", eraTestItemPtr->locale); 2179 } 2180 2181 status = U_ZERO_ERROR; 2182 ucal_clear(ucalTest); 2183 ucal_set(ucalTest, UCAL_YEAR, 1); 2184 ucal_set(ucalTest, UCAL_ERA, 1); 2185 yrMax = ucal_getLimit(ucalTest, UCAL_YEAR, UCAL_ACTUAL_MAXIMUM, &status); /* max year value for era 1 */ 2186 ucal_roll(ucalTest, UCAL_YEAR, -1, &status); /* roll down which should pin or wrap to end */ 2187 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2188 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status); 2189 if (U_FAILURE(status)) { 2190 log_err("FAIL: set era 1 year 1 then roll -1 year and get year,era for %s, error %s\n", 2191 eraTestItemPtr->locale, u_errorName(status)); 2192 /* if yrMax is reasonable we should wrap to that, else we should pin at yr 1 */ 2193 } else if (yrMax >= 32768) { 2194 if (eraAfter != 1 || yrAfter != 1) { 2195 log_err("FAIL: era 1 roll -1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n", 2196 eraTestItemPtr->locale, eraAfter, yrAfter); 2197 } 2198 } else if (eraAfter != 1 || yrAfter != yrMax) { 2199 log_err("FAIL: era 1 roll -1 year from year 1 does not stay within era or wrap to year %d for %s (get era %d year %d)\n", 2200 yrMax, eraTestItemPtr->locale, eraAfter, yrAfter); 2201 } else { 2202 /* now roll up which should wrap to beginning */ 2203 ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* now roll up which should wrap to beginning */ 2204 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2205 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status); 2206 if (U_FAILURE(status)) { 2207 log_err("FAIL: era 1 roll 1 year from end and get year,era for %s, error %s\n", 2208 eraTestItemPtr->locale, u_errorName(status)); 2209 } else if (eraAfter != 1 || yrAfter != 1) { 2210 log_err("FAIL: era 1 roll 1 year from year %d does not stay within era or wrap to year 1 for %s (get era %d year %d)\n", 2211 yrMax, eraTestItemPtr->locale, eraAfter, yrAfter); 2212 } 2213 } 2214 2215 /* if current era > 1, try the same roll tests for current era */ 2216 ucal_setMillis(ucalTest, ucal_getNow(), &status); 2217 eraNow = ucal_get(ucalTest, UCAL_ERA, &status); 2218 if ( U_SUCCESS(status) && eraNow > 1 ) { 2219 status = U_ZERO_ERROR; 2220 ucal_clear(ucalTest); 2221 ucal_set(ucalTest, UCAL_YEAR, 1); 2222 ucal_set(ucalTest, UCAL_ERA, eraNow); 2223 yrMax = ucal_getLimit(ucalTest, UCAL_YEAR, UCAL_ACTUAL_MAXIMUM, &status); /* max year value for this era */ 2224 ucal_roll(ucalTest, UCAL_YEAR, -1, &status); 2225 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2226 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status); 2227 if (U_FAILURE(status)) { 2228 log_err("FAIL: set era %d year 1 then roll -1 year and get year,era for %s, error %s\n", 2229 eraNow, eraTestItemPtr->locale, u_errorName(status)); 2230 /* if yrMax is reasonable we should wrap to that, else we should pin at yr 1 */ 2231 } else if (yrMax >= 32768) { 2232 if (eraAfter != eraNow || yrAfter != 1) { 2233 log_err("FAIL: era %d roll -1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n", 2234 eraNow, eraTestItemPtr->locale, eraAfter, yrAfter); 2235 } 2236 } else if (eraAfter != eraNow || yrAfter != yrMax) { 2237 log_err("FAIL: era %d roll -1 year from year 1 does not stay within era or wrap to year %d for %s (get era %d year %d)\n", 2238 eraNow, yrMax, eraTestItemPtr->locale, eraAfter, yrAfter); 2239 } else { 2240 /* now roll up which should wrap to beginning */ 2241 ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* now roll up which should wrap to beginning */ 2242 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status); 2243 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status); 2244 if (U_FAILURE(status)) { 2245 log_err("FAIL: era %d roll 1 year from end and get year,era for %s, error %s\n", 2246 eraNow, eraTestItemPtr->locale, u_errorName(status)); 2247 } else if (eraAfter != eraNow || yrAfter != 1) { 2248 log_err("FAIL: era %d roll 1 year from year %d does not stay within era or wrap to year 1 for %s (get era %d year %d)\n", 2249 eraNow, yrMax, eraTestItemPtr->locale, eraAfter, yrAfter); 2250 } 2251 } 2252 } 2253 } 2254 2255 ucal_close(ucalTest); 2256 } else { 2257 log_data_err("FAIL: ucal_open fails for zone GMT, locale %s, UCAL_DEFAULT\n", eraTestItemPtr->locale); 2258 } 2259 } 2260} 2261 2262/** 2263 * TestGetTZTransition, for #9606 2264 */ 2265 2266typedef struct { 2267 const char *descrip; /* test description */ 2268 const UChar * zoneName; /* pointer to zero-terminated zone name */ 2269 int32_t year; /* starting point for test is gregorian calendar noon on day specified by y,M,d here */ 2270 int32_t month; 2271 int32_t day; 2272 UBool hasPrev; /* does it have a previous transition from starting point? If so we test inclusive from that */ 2273 UBool hasNext; /* does it have a next transition from starting point? If so we test inclusive from that */ 2274} TZTransitionItem; 2275 2276/* have zoneGMT above */ 2277static const UChar zoneUSPacific[] = { 0x55,0x53,0x2F,0x50,0x61,0x63,0x69,0x66,0x69,0x63,0 }; /* "US/Pacific" */ 2278static const UChar zoneCairo[] = { 0x41,0x66,0x72,0x69,0x63,0x61,0x2F,0x43,0x61,0x69,0x72,0x6F,0 }; /* "Africa/Cairo", DST cancelled since 2011 */ 2279static const UChar zoneIceland[] = { 0x41,0x74,0x6C,0x61,0x6E,0x74,0x69,0x63,0x2F,0x52,0x65,0x79,0x6B,0x6A,0x61,0x76,0x69,0x6B,0 }; /* "Atlantic/Reykjavik", always on DST (since when?) */ 2280 2281static const TZTransitionItem tzTransitionItems[] = { 2282 { "USPacific mid 2012", zoneUSPacific, 2012, UCAL_JULY, 1, TRUE , TRUE }, 2283 { "USPacific mid 100", zoneUSPacific, 100, UCAL_JULY, 1, FALSE, TRUE }, /* no transitions before 100 CE... */ 2284 { "Cairo mid 2012", zoneCairo, 2012, UCAL_JULY, 1, TRUE , FALSE }, /* DST cancelled since 2011 */ 2285 { "Iceland mid 2012", zoneIceland, 2012, UCAL_JULY, 1, TRUE , FALSE }, /* always on DST */ 2286 { NULL, NULL, 0, 0, 0, FALSE, FALSE } /* terminator */ 2287}; 2288 2289void TestGetTZTransition() { 2290 UErrorCode status = U_ZERO_ERROR; 2291 UCalendar * ucal = ucal_open(zoneGMT, -1, "en", UCAL_GREGORIAN, &status); 2292 if ( U_SUCCESS(status) ) { 2293 const TZTransitionItem * itemPtr; 2294 for (itemPtr = tzTransitionItems; itemPtr->descrip != NULL; itemPtr++) { 2295 UDate curMillis; 2296 ucal_setTimeZone(ucal, itemPtr->zoneName, -1, &status); 2297 ucal_setDateTime(ucal, itemPtr->year, itemPtr->month, itemPtr->day, 12, 0, 0, &status); 2298 curMillis = ucal_getMillis(ucal, &status); 2299 if ( U_SUCCESS(status) ) { 2300 UDate transition1, transition2; 2301 UBool result; 2302 2303 result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_PREVIOUS, &transition1, &status); 2304 if (U_FAILURE(status) || result != itemPtr->hasPrev) { 2305 log_data_err("FAIL: %s ucal_getTimeZoneTransitionDate prev status %s, expected result %d but got %d\n", 2306 itemPtr->descrip, u_errorName(status), itemPtr->hasPrev, result); 2307 } else if (result) { 2308 ucal_setMillis(ucal, transition1, &status); 2309 result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE, &transition2, &status); 2310 if (U_FAILURE(status) || !result || transition2 != transition1) { 2311 log_err("FAIL: %s ucal_getTimeZoneTransitionDate prev_inc status %s, result %d, expected date %.1f but got %.1f\n", 2312 itemPtr->descrip, u_errorName(status), result, transition1, transition2); 2313 } 2314 } 2315 status = U_ZERO_ERROR; 2316 2317 result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_NEXT, &transition1, &status); 2318 if (U_FAILURE(status) || result != itemPtr->hasNext) { 2319 log_data_err("FAIL: %s ucal_getTimeZoneTransitionDate next status %s, expected result %d but got %d\n", 2320 itemPtr->descrip, u_errorName(status), itemPtr->hasNext, result); 2321 } else if (result) { 2322 ucal_setMillis(ucal, transition1, &status); 2323 result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_NEXT_INCLUSIVE, &transition2, &status); 2324 if (U_FAILURE(status) || !result || transition2 != transition1) { 2325 log_err("FAIL: %s ucal_getTimeZoneTransitionDate next_inc status %s, result %d, expected date %.1f but got %.1f\n", 2326 itemPtr->descrip, u_errorName(status), result, transition1, transition2); 2327 } 2328 } 2329 status = U_ZERO_ERROR; 2330 } else { 2331 log_data_err("FAIL setup: can't setup calendar for %s, status %s\n", 2332 itemPtr->descrip, u_errorName(status)); 2333 status = U_ZERO_ERROR; 2334 } 2335 } 2336 ucal_close(ucal); 2337 } else { 2338 log_data_err("FAIL setup: ucal_open status %s\n", u_errorName(status)); 2339 } 2340} 2341 2342#endif /* #if !UCONFIG_NO_FORMATTING */ 2343