/********************************************************************
- * 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"
// *****************************************************************************
// 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
CASE(14, TestJ186);
CASE(15, TestJ449);
CASE(16, TestJDK12API);
-
+ CASE(17, Test4176686);
+ CASE(18, Test4184229);
default: name = ""; break;
}
}
{
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);
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");
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);
* 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;
}
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;
}
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;
}
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);
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;
}
// 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");
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;
// 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
}
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;
}
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 [] = {
// 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 &&
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.
// 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);
// 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);
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<SimpleTimeZone *>(cst1);
if(pst->hasSameRules(*cst)) {
errln("FAILURE: PST and CST have same rules");
// 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");
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 */