X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..151279e3792e85d0417b499c229886b3af724f55:/icuSources/test/intltest/tzregts.cpp?ds=sidebyside diff --git a/icuSources/test/intltest/tzregts.cpp b/icuSources/test/intltest/tzregts.cpp index dc07ddf1..274b3f56 100644 --- a/icuSources/test/intltest/tzregts.cpp +++ b/icuSources/test/intltest/tzregts.cpp @@ -1,7 +1,6 @@ /******************************************************************** - * COPYRIGHT: - * Copyright (c) 1997-2003, International Business Machines Corporation and - * others. All Rights Reserved. + * Copyright (c) 1997-2013, International Business Machines + * Corporation and others. All Rights Reserved. ********************************************************************/ #include "unicode/utypes.h" @@ -18,7 +17,8 @@ // ***************************************************************************** // class TimeZoneRegressionTest // ***************************************************************************** - +/* length of an array */ +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break void @@ -44,7 +44,8 @@ TimeZoneRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* & CASE(14, TestJ186); CASE(15, TestJ449); CASE(16, TestJDK12API); - + CASE(17, Test4176686); + CASE(18, Test4184229); default: name = ""; break; } } @@ -126,7 +127,7 @@ void TimeZoneRegressionTest:: Test4073215() { UErrorCode status = U_ZERO_ERROR; UnicodeString str, str2; - SimpleTimeZone *z = (SimpleTimeZone*) TimeZone::createTimeZone("GMT"); + SimpleTimeZone *z = new SimpleTimeZone(0, "GMT"); if (z->useDaylightTime()) errln("Fail: Fix test to start with non-DST zone"); z->setStartRule(UCAL_FEBRUARY, 1, UCAL_SUNDAY, 0, status); @@ -138,7 +139,7 @@ void TimeZoneRegressionTest:: Test4073215() GregorianCalendar cal(1997, UCAL_JANUARY, 31, status); if(U_FAILURE(status)) { - errln("Error creating calendar %s", u_errorName(status)); + dataerrln("Error creating calendar %s", u_errorName(status)); return; } failure(status, "new GregorianCalendar"); @@ -146,7 +147,7 @@ void TimeZoneRegressionTest:: Test4073215() SimpleDateFormat sdf((UnicodeString)"E d MMM yyyy G HH:mm", status); if(U_FAILURE(status)) { - errln("Error creating date format %s", u_errorName(status)); + dataerrln("Error creating date format %s", u_errorName(status)); return; } sdf.setCalendar(cal); @@ -221,25 +222,36 @@ void TimeZoneRegressionTest:: Test4084933() { * The following was added just for consistency. It shows that going *to* Daylight * Savings Time (PDT) does work at 2am. */ - int32_t offset5 = tz->getOffset(1, 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (2*60*60*1000), status); int32_t offset6 = tz->getOffset(1, 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (2*60*60*1000)-1, status); - + int32_t offset5a = tz->getOffset(1, + 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (3*60*60*1000), status); + int32_t offset6a = tz->getOffset(1, + 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (3*60*60*1000)-1, status); int32_t offset7 = tz->getOffset(1, 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (1*60*60*1000), status); int32_t offset8 = tz->getOffset(1, 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (1*60*60*1000)-1, status); - int32_t SToffset = (int32_t)(-8 * 60*60*1000L); int32_t DToffset = (int32_t)(-7 * 60*60*1000L); - if (offset1 != SToffset || offset2 != SToffset || - offset3 != SToffset || offset4 != DToffset || - offset5 != DToffset || offset6 != SToffset || - offset7 != SToffset || offset8 != SToffset - || U_FAILURE(status)) - errln("Fail: TimeZone misbehaving"); + +#define ERR_IF_FAIL(x) if(x) { dataerrln("FAIL: TimeZone misbehaving - %s", #x); } + + ERR_IF_FAIL(U_FAILURE(status)) + ERR_IF_FAIL(offset1 != SToffset) + ERR_IF_FAIL(offset2 != SToffset) + ERR_IF_FAIL(offset3 != SToffset) + ERR_IF_FAIL(offset4 != DToffset) + ERR_IF_FAIL(offset5 != DToffset) + ERR_IF_FAIL(offset6 != SToffset) + ERR_IF_FAIL(offset5a != DToffset) + ERR_IF_FAIL(offset6a != DToffset) + ERR_IF_FAIL(offset7 != SToffset) + ERR_IF_FAIL(offset8 != SToffset) + +#undef ERR_IF_FAIL delete tz; } @@ -298,7 +310,7 @@ void TimeZoneRegressionTest:: Test4109314() { UErrorCode status = U_ZERO_ERROR; GregorianCalendar *testCal = (GregorianCalendar*)Calendar::createInstance(status); if(U_FAILURE(status)) { - errln("Error creating calendar %s", u_errorName(status)); + dataerrln("Error creating calendar %s", u_errorName(status)); delete testCal; return; } @@ -440,7 +452,7 @@ void TimeZoneRegressionTest:: Test4126678() UErrorCode status = U_ZERO_ERROR; Calendar *cal = Calendar::createInstance(status); if(U_FAILURE(status)) { - errln("Error creating calendar %s", u_errorName(status)); + dataerrln("Error creating calendar %s", u_errorName(status)); delete cal; return; } @@ -448,11 +460,10 @@ void TimeZoneRegressionTest:: Test4126678() TimeZone *tz = TimeZone::createTimeZone("PST"); cal->adoptTimeZone(tz); - cal->set(1998 - 1900, UCAL_APRIL, 5, 10, 0); - //Date dt = new Date(1998-1900, Calendar::APRIL, 5, 10, 0); + cal->set(1998, UCAL_APRIL, 5, 10, 0); if (! tz->useDaylightTime() || U_FAILURE(status)) - errln("We're not in Daylight Savings Time and we should be.\n"); + dataerrln("We're not in Daylight Savings Time and we should be. - %s", u_errorName(status)); //cal.setTime(dt); int32_t era = cal->get(UCAL_ERA, status); @@ -469,8 +480,9 @@ void TimeZoneRegressionTest:: Test4126678() failure(status, "cal->get"); int32_t offset = tz->getOffset((uint8_t)era, year, month, day, (uint8_t)dayOfWeek, millis, status); int32_t raw_offset = tz->getRawOffset(); + if (offset == raw_offset) - errln("Offsets should not match when in DST"); + dataerrln("Offsets should match"); delete cal; } @@ -486,7 +498,7 @@ void TimeZoneRegressionTest:: Test4151406() { // h is in half-hours from GMT; rawoffset is in millis int32_t rawoffset = h * 1800000; int32_t hh = (h<0) ? -h : h; - UnicodeString hname = ((h<0) ? UnicodeString("GMT-") : UnicodeString("GMT+")) + + UnicodeString hname = UnicodeString((h<0) ? "GMT-" : "GMT+") + ((hh/2 < 10) ? "0" : "") + (hh/2) + ':' + ((hh%2==0) ? "00" : "30"); @@ -494,11 +506,18 @@ void TimeZoneRegressionTest:: Test4151406() { UErrorCode ec = U_ZERO_ERROR; int32_t count; StringEnumeration* ids = TimeZone::createEnumeration(rawoffset); + if (ids == NULL) { + dataerrln("Fail: TimeZone::createEnumeration(rawoffset)"); + continue; + } count = ids->count(ec); if (count> max) max = count; - logln(hname + ' ' + count + - ((count > 0) ? (" e.g. " + *ids->snext(ec)) : UnicodeString(""))); + if (count > 0) { + logln(hname + ' ' + (UnicodeString)count + (UnicodeString)" e.g. " + *ids->snext(ec)); + } else { + logln(hname + ' ' + count); + } // weiv 11/27/2002: why uprv_free? This should be a delete delete ids; //delete [] ids; @@ -795,10 +814,17 @@ TimeZoneRegressionTest::Test4154650() // e = ex; //} if(good != U_SUCCESS(status)) { + UnicodeString errMsg; + if (good) { + errMsg = (UnicodeString(") threw ") + u_errorName(status)); + } + else { + errMsg = UnicodeString(") accepts invalid args", ""); + } errln(UnicodeString("Fail: getOffset(") + DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " + DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] + - (good ? (UnicodeString(") threw ") + u_errorName(status)) : UnicodeString(") accepts invalid args"))); + errMsg); } status = U_ZERO_ERROR; // reset } @@ -816,7 +842,7 @@ TimeZoneRegressionTest::Test4162593() UErrorCode status = U_ZERO_ERROR; SimpleDateFormat *fmt = new SimpleDateFormat("z", Locale::getUS(), status); if(U_FAILURE(status)) { - errln("Error creating calendar %s", u_errorName(status)); + dataerrln("Error creating calendar %s", u_errorName(status)); delete fmt; return; } @@ -834,9 +860,10 @@ TimeZoneRegressionTest::Test4162593() 0, 0, 0 }; int32_t DATA_INT [] [5] = { - {98, UCAL_SEPTEMBER, 30, 22, 0}, - {100, UCAL_FEBRUARY, 28, 22, 0}, - {100, UCAL_FEBRUARY, 29, 22, 0}, + // These years must be AFTER the Gregorian cutover + {1998, UCAL_SEPTEMBER, 30, 22, 0}, + {2000, UCAL_FEBRUARY, 28, 22, 0}, + {2000, UCAL_FEBRUARY, 29, 22, 0}, }; UBool DATA_BOOL [] = { @@ -860,16 +887,16 @@ TimeZoneRegressionTest::Test4162593() // Must construct the Date object AFTER setting the default zone int32_t *p = (int32_t*)DATA_INT[j]; UDate d = CalendarRegressionTest::makeDate(p[0], p[1], p[2], p[3], p[4]); - UBool transitionExpected = DATA_BOOL[j]; + UBool transitionExpected = DATA_BOOL[j]; UnicodeString temp; logln(tz->getID(temp) + ":"); for (int32_t i = 0; i < 4; ++i) { FieldPosition pos(0); zone[i].remove(); - zone[i] = fmt->format(d, zone[i], pos); + zone[i] = fmt->format(d+ i*ONE_HOUR, zone[i], pos); logln(UnicodeString("") + i + ": " + d + " / " + zone[i]); - d += (double) ONE_HOUR; + //d += (double) ONE_HOUR; } if(zone[0] == zone[1] && (zone[1] == zone[2]) != transitionExpected && @@ -885,6 +912,77 @@ TimeZoneRegressionTest::Test4162593() delete DATA_TZ[0]; } + /** + * getDisplayName doesn't work with unusual savings/offsets. + */ +void TimeZoneRegressionTest::Test4176686() { + // Construct a zone that does not observe DST but + // that does have a DST savings (which should be ignored). + UErrorCode status = U_ZERO_ERROR; + int32_t offset = 90 * 60000; // 1:30 + SimpleTimeZone* z1 = new SimpleTimeZone(offset, "_std_zone_"); + z1->setDSTSavings(45 * 60000, status); // 0:45 + + // Construct a zone that observes DST for the first 6 months. + SimpleTimeZone* z2 = new SimpleTimeZone(offset, "_dst_zone_"); + z2->setDSTSavings(45 * 60000, status); // 0:45 + z2->setStartRule(UCAL_JANUARY, 1, 0, status); + z2->setEndRule(UCAL_JULY, 1, 0, status); + + // Also check DateFormat + DateFormat* fmt1 = new SimpleDateFormat(UnicodeString("z"), status); + if (U_FAILURE(status)) { + dataerrln("Failure trying to construct: %s", u_errorName(status)); + return; + } + fmt1->setTimeZone(*z1); // Format uses standard zone + DateFormat* fmt2 = new SimpleDateFormat(UnicodeString("z"), status); + if(!assertSuccess("trying to construct", status))return; + fmt2->setTimeZone(*z2); // Format uses DST zone + Calendar* tempcal = Calendar::createInstance(status); + tempcal->clear(); + tempcal->set(1970, UCAL_FEBRUARY, 1); + UDate dst = tempcal->getTime(status); // Time in DST + tempcal->set(1970, UCAL_AUGUST, 1); + UDate std = tempcal->getTime(status); // Time in standard + + // Description, Result, Expected Result + UnicodeString a,b,c,d,e,f,g,h,i,j,k,l; + UnicodeString DATA[] = { + "z1->getDisplayName(false, SHORT)/std zone", + z1->getDisplayName(FALSE, TimeZone::SHORT, a), "GMT+1:30", + "z1->getDisplayName(false, LONG)/std zone", + z1->getDisplayName(FALSE, TimeZone::LONG, b), "GMT+01:30", + "z1->getDisplayName(true, SHORT)/std zone", + z1->getDisplayName(TRUE, TimeZone::SHORT, c), "GMT+1:30", + "z1->getDisplayName(true, LONG)/std zone", + z1->getDisplayName(TRUE, TimeZone::LONG, d ), "GMT+01:30", + "z2->getDisplayName(false, SHORT)/dst zone", + z2->getDisplayName(FALSE, TimeZone::SHORT, e), "GMT+1:30", + "z2->getDisplayName(false, LONG)/dst zone", + z2->getDisplayName(FALSE, TimeZone::LONG, f ), "GMT+01:30", + "z2->getDisplayName(true, SHORT)/dst zone", + z2->getDisplayName(TRUE, TimeZone::SHORT, g), "GMT+2:15", + "z2->getDisplayName(true, LONG)/dst zone", + z2->getDisplayName(TRUE, TimeZone::LONG, h ), "GMT+02:15", + "DateFormat.format(std)/std zone", fmt1->format(std, i), "GMT+1:30", + "DateFormat.format(dst)/std zone", fmt1->format(dst, j), "GMT+1:30", + "DateFormat.format(std)/dst zone", fmt2->format(std, k), "GMT+1:30", + "DateFormat.format(dst)/dst zone", fmt2->format(dst, l), "GMT+2:15", + }; + + for (int32_t idx=0; idx<(int32_t)ARRAY_LENGTH(DATA); idx+=3) { + if (DATA[idx+1]!=(DATA[idx+2])) { + errln("FAIL: " + DATA[idx] + " -> " + DATA[idx+1] + ", exp " + DATA[idx+2]); + } + } + delete z1; + delete z2; + delete fmt1; + delete fmt2; + delete tempcal; +} + /** * Make sure setStartRule and setEndRule set the DST savings to nonzero * if it was zero. @@ -933,7 +1031,7 @@ void TimeZoneRegressionTest::TestJ449() { // specify two zones in the same equivalency group. One must have // locale data in 'loc'; the other must not. const char* idWithLocaleData = "America/Los_Angeles"; - const char* idWithoutLocaleData = "America/Vancouver"; + const char* idWithoutLocaleData = "US/Pacific"; const Locale loc("en", "", ""); TimeZone *zoneWith = TimeZone::createTimeZone(idWithLocaleData); @@ -941,7 +1039,7 @@ void TimeZoneRegressionTest::TestJ449() { // Make sure we got valid zones if (zoneWith->getID(str) != UnicodeString(idWithLocaleData) || zoneWithout->getID(str) != UnicodeString(idWithoutLocaleData)) { - errln("Fail: Unable to create zones"); + dataerrln(UnicodeString("Fail: Unable to create zones - wanted ") + idWithLocaleData + ", got " + zoneWith->getID(str) + ", and wanted " + idWithoutLocaleData + " but got " + zoneWithout->getID(str)); } else { GregorianCalendar calWith(*zoneWith, status); GregorianCalendar calWithout(*zoneWithout, status); @@ -975,13 +1073,31 @@ void TimeZoneRegressionTest::TestJ449() { void TimeZoneRegressionTest::TestJDK12API() { - TimeZone *pst = TimeZone::createTimeZone("PST"); - TimeZone *cst1 = TimeZone::createTimeZone("CST"); - - SimpleTimeZone *cst = 0; + // TimeZone *pst = TimeZone::createTimeZone("PST"); + // TimeZone *cst1 = TimeZone::createTimeZone("CST"); + UErrorCode ec = U_ZERO_ERROR; + //d,-28800,3,1,-1,120,w,9,-1,1,120,w,60 + TimeZone *pst = new SimpleTimeZone(-28800*U_MILLIS_PER_SECOND, + "PST", + 3,1,-1,120*U_MILLIS_PER_MINUTE, + SimpleTimeZone::WALL_TIME, + 9,-1,1,120*U_MILLIS_PER_MINUTE, + SimpleTimeZone::WALL_TIME, + 60*U_MILLIS_PER_MINUTE,ec); + //d,-21600,3,1,-1,120,w,9,-1,1,120,w,60 + TimeZone *cst1 = new SimpleTimeZone(-21600*U_MILLIS_PER_SECOND, + "CST", + 3,1,-1,120*U_MILLIS_PER_MINUTE, + SimpleTimeZone::WALL_TIME, + 9,-1,1,120*U_MILLIS_PER_MINUTE, + SimpleTimeZone::WALL_TIME, + 60*U_MILLIS_PER_MINUTE,ec); + if (U_FAILURE(ec)) { + errln("FAIL: SimpleTimeZone constructor"); + return; + } - if(cst1->getDynamicClassID() == SimpleTimeZone::getStaticClassID()) - cst = (SimpleTimeZone*) cst1; + SimpleTimeZone *cst = dynamic_cast(cst1); if(pst->hasSameRules(*cst)) { errln("FAILURE: PST and CST have same rules"); @@ -1002,7 +1118,7 @@ TimeZoneRegressionTest::TestJDK12API() // verify error checking pst->getOffset(1, - 1997, (UCalendarDateFields)-1, 26, UCAL_SUNDAY, (2*60*60*1000), status); + 1997, UCAL_FIELD_COUNT+1, 26, UCAL_SUNDAY, (2*60*60*1000), status); if(U_SUCCESS(status)) errln("FAILURE: getOffset() succeeded with -1 for month"); @@ -1018,5 +1134,76 @@ TimeZoneRegressionTest::TestJDK12API() delete pst; delete cst; } +/** + * SimpleTimeZone allows invalid DOM values. + */ +void TimeZoneRegressionTest::Test4184229() { + SimpleTimeZone* zone = NULL; + UErrorCode status = U_ZERO_ERROR; + zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 startDay"); + }else{ + logln("(a) " + UnicodeString( u_errorName(status))); + } + status = U_ZERO_ERROR; + delete zone; + + zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 endDay"); + }else{ + logln("(b) " + UnicodeString(u_errorName(status))); + } + status = U_ZERO_ERROR; + delete zone; + + zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 1000, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 startDay+savings"); + }else{ + logln("(c) " + UnicodeString(u_errorName(status))); + } + status = U_ZERO_ERROR; + delete zone; + zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 endDay+ savings"); + }else{ + logln("(d) " + UnicodeString(u_errorName(status))); + } + status = U_ZERO_ERROR; + delete zone; + // Make a valid constructor call for subsequent tests. + zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0, status); + + zone->setStartRule(0, -1, 0, 0, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings"); + } else{ + logln("(e) " + UnicodeString(u_errorName(status))); + } + zone->setStartRule(0, -1, 0, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 setStartRule"); + } else{ + logln("(f) " + UnicodeString(u_errorName(status))); + } + + zone->setEndRule(0, -1, 0, 0, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 setEndRule+savings"); + } else{ + logln("(g) " + UnicodeString(u_errorName(status))); + } + + zone->setEndRule(0, -1, 0, status); + if(U_SUCCESS(status)){ + errln("Failed. No exception has been thrown for DOM -1 setEndRule"); + } else{ + logln("(h) " + UnicodeString(u_errorName(status))); + } + delete zone; +} #endif /* #if !UCONFIG_NO_FORMATTING */