-/********************************************************************
+/***********************************************************************
* COPYRIGHT:
- * Copyright (c) 1997-2003, International Business Machines Corporation and
- * others. All Rights Reserved.
- ********************************************************************/
+ * Copyright (c) 1997-2010, International Business Machines Corporation
+ * and others. All Rights Reserved.
+ ***********************************************************************/
#include "unicode/utypes.h"
#include "unicode/timezone.h"
#include "unicode/simpletz.h"
#include "unicode/gregocal.h"
+#include "putilimp.h"
void TimeZoneBoundaryTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
mindelta <= INTERVAL &&
maxdelta >= 0 &&
maxdelta <= INTERVAL) logln(UnicodeString("PASS: Expected boundary at ") + expectedBoundary);
- else errln(UnicodeString("FAIL: Expected boundary at ") + expectedBoundary);
+ else dataerrln(UnicodeString("FAIL: Expected boundary at ") + expectedBoundary);
}
// -------------------------------------
UDate min = d;
UDate max = min + SIX_MONTHS;
if (tz->inDaylightTime(d, status) != startsInDST) {
- errln("FAIL: " + tz->getID(str) + " inDaylightTime(" + dateToString(d) + ") != " + (startsInDST ? "true" : "false"));
+ dataerrln("FAIL: " + tz->getID(str) + " inDaylightTime(" + dateToString(d) + ") != " + (startsInDST ? "true" : "false"));
startsInDST = !startsInDST;
}
- if (failure(status, "TimeZone::inDaylightTime")) return;
+ if (failure(status, "TimeZone::inDaylightTime", TRUE)) return;
if (tz->inDaylightTime(max, status) == startsInDST) {
- errln("FAIL: " + tz->getID(str) + " inDaylightTime(" + dateToString(max) + ") != " + (startsInDST ? "false" : "true"));
+ dataerrln("FAIL: " + tz->getID(str) + " inDaylightTime(" + dateToString(max) + ") != " + (startsInDST ? "false" : "true"));
return;
}
if (failure(status, "TimeZone::inDaylightTime")) return;
UnicodeString
TimeZoneBoundaryTest::showNN(int32_t n)
{
- return ((n < 10) ? UnicodeString("0"): UnicodeString("")) + n;
+ UnicodeString nStr;
+ if (n < 10) {
+ nStr += UnicodeString("0", "");
+ }
+ return nStr + n;
}
// -------------------------------------
logln("-- Verifying time " + dateToString(d) + " in zone " + time_zone->getID(str));
if (time_zone->inDaylightTime(d, status) == expInDaylightTime)
logln(UnicodeString("PASS: inDaylightTime = ") + (time_zone->inDaylightTime(d, status)?"true":"false"));
- else errln(UnicodeString("FAIL: inDaylightTime = ") + (time_zone->inDaylightTime(d, status)?"true":"false"));
- if (failure(status, "TimeZone::inDaylightTime")) return;
+ else
+ dataerrln(UnicodeString("FAIL: inDaylightTime = ") + (time_zone->inDaylightTime(d, status)?"true":"false"));
+ if (failure(status, "TimeZone::inDaylightTime", TRUE))
+ return;
if (time_zone->useDaylightTime() == expUseDaylightTime)
logln(UnicodeString("PASS: useDaylightTime = ") + (time_zone->useDaylightTime()?"true":"false"));
- else errln(UnicodeString("FAIL: useDaylightTime = ") + (time_zone->useDaylightTime()?"true":"false"));
- if (time_zone->getRawOffset() == expZoneOffset) logln(UnicodeString("PASS: getRawOffset() = ") + (expZoneOffset / ONE_HOUR));
- else errln(UnicodeString("FAIL: getRawOffset() = ") + (time_zone->getRawOffset() / ONE_HOUR) + "; expected " + (expZoneOffset / ONE_HOUR));
+ else
+ dataerrln(UnicodeString("FAIL: useDaylightTime = ") + (time_zone->useDaylightTime()?"true":"false"));
+ if (time_zone->getRawOffset() == expZoneOffset)
+ logln(UnicodeString("PASS: getRawOffset() = ") + (expZoneOffset / ONE_HOUR));
+ else
+ dataerrln(UnicodeString("FAIL: getRawOffset() = ") + (time_zone->getRawOffset() / ONE_HOUR) + "; expected " + (expZoneOffset / ONE_HOUR));
+
GregorianCalendar *gc = new GregorianCalendar(time_zone->clone(), status);
gc->setTime(d, status);
if (failure(status, "GregorianCalendar::setTime")) return;
status);
if (failure(status, "GregorianCalendar::get")) return;
if (offset == expDSTOffset) logln(UnicodeString("PASS: getOffset() = ") + (offset / ONE_HOUR));
- else errln(UnicodeString("FAIL: getOffset() = ") + (offset / ONE_HOUR) + "; expected " + (expDSTOffset / ONE_HOUR));
+ else dataerrln(UnicodeString("FAIL: getOffset() = ") + (offset / ONE_HOUR) + "; expected " + (expDSTOffset / ONE_HOUR));
delete gc;
}
// -------------------------------------
-
+/**
+ * Check that the given year/month/dom/hour maps to and from the
+ * given epochHours. This verifies the functioning of the
+ * calendar and time zone in conjunction with one another,
+ * including the calendar time->fields and fields->time and
+ * the time zone getOffset method.
+ *
+ * @param epochHours hours after Jan 1 1970 0:00 GMT.
+ */
+void TimeZoneBoundaryTest::verifyMapping(Calendar& cal, int year, int month, int dom, int hour,
+ double epochHours) {
+ double H = 3600000.0;
+ UErrorCode status = U_ZERO_ERROR;
+ cal.clear();
+ cal.set(year, month, dom, hour, 0, 0);
+ UDate e = cal.getTime(status)/ H;
+ UDate ed = (epochHours * H);
+ if (e == epochHours) {
+ logln(UnicodeString("Ok: ") + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
+ e + " (" + ed + ")");
+ } else {
+ dataerrln(UnicodeString("FAIL: ") + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
+ e + " (" + (e * H) + ")" +
+ ", expected " + epochHours + " (" + ed + ")");
+ }
+ cal.setTime(ed, status);
+ if (cal.get(UCAL_YEAR, status) == year &&
+ cal.get(UCAL_MONTH, status) == month &&
+ cal.get(UCAL_DATE, status) == dom &&
+ cal.get(UCAL_MILLISECONDS_IN_DAY, status) == hour * 3600000) {
+ logln(UnicodeString("Ok: ") + epochHours + " (" + ed + ") => " +
+ cal.get(UCAL_YEAR, status) + "/" +
+ (cal.get(UCAL_MONTH, status)+1) + "/" +
+ cal.get(UCAL_DATE, status) + " " +
+ cal.get(UCAL_MILLISECOND, status)/H);
+ } else {
+ dataerrln(UnicodeString("FAIL: ") + epochHours + " (" + ed + ") => " +
+ cal.get(UCAL_YEAR, status) + "/" +
+ (cal.get(UCAL_MONTH, status)+1) + "/" +
+ cal.get(UCAL_DATE, status) + " " +
+ cal.get(UCAL_MILLISECOND, status)/H +
+ ", expected " + year + "/" + (month+1) + "/" + dom +
+ " " + hour);
+ }
+}
+
/**
* Test the behavior of SimpleTimeZone at the transition into and out of DST.
* Use a binary search to find boundaries.
void
TimeZoneBoundaryTest::TestBoundaries()
{
+ UErrorCode status = U_ZERO_ERROR;
+ TimeZone* pst = TimeZone::createTimeZone("PST");
+ Calendar* tempcal = Calendar::createInstance(pst, status);
+ if(U_SUCCESS(status)){
+ verifyMapping(*tempcal, 1997, Calendar::APRIL, 3, 0, 238904.0);
+ verifyMapping(*tempcal, 1997, Calendar::APRIL, 4, 0, 238928.0);
+ verifyMapping(*tempcal, 1997, Calendar::APRIL, 5, 0, 238952.0);
+ verifyMapping(*tempcal, 1997, Calendar::APRIL, 5, 23, 238975.0);
+ verifyMapping(*tempcal, 1997, Calendar::APRIL, 6, 0, 238976.0);
+ verifyMapping(*tempcal, 1997, Calendar::APRIL, 6, 1, 238977.0);
+ verifyMapping(*tempcal, 1997, Calendar::APRIL, 6, 3, 238978.0);
+ }else{
+ dataerrln("Could not create calendar. Error: %s", u_errorName(status));
+ }
+ TimeZone* utc = TimeZone::createTimeZone("UTC");
+ Calendar* utccal = Calendar::createInstance(utc, status);
+ if(U_SUCCESS(status)){
+ verifyMapping(*utccal, 1997, Calendar::APRIL, 6, 0, 238968.0);
+ }else{
+ dataerrln("Could not create calendar. Error: %s", u_errorName(status));
+ }
+ TimeZone* save = TimeZone::createDefault();
+ TimeZone::setDefault(*pst);
+
+ if (tempcal != NULL) {
+ // DST changeover for PST is 4/6/1997 at 2 hours past midnight
+ // at 238978.0 epoch hours.
+ tempcal->clear();
+ tempcal->set(1997, Calendar::APRIL, 6);
+ UDate d = tempcal->getTime(status);
+
+ // i is minutes past midnight standard time
+ for (int i=-120; i<=180; i+=60)
+ {
+ UBool inDST = (i >= 120);
+ tempcal->setTime(d + i*60*1000, status);
+ verifyDST(tempcal->getTime(status),pst, TRUE, inDST, -8*ONE_HOUR,inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
+ }
+ }
+ TimeZone::setDefault(*save);
+ delete save;
+ delete utccal;
+ delete tempcal;
+
#if 1
{
logln("--- Test a ---");
UDate min = d;
UDate max = min + SIX_MONTHS;
UBool startsInDST = tz->inDaylightTime(d, status);
- if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
+ if (failure(status, "SimpleTimeZone::inDaylightTime", TRUE)) return;
if (tz->inDaylightTime(max, status) == startsInDST) {
- logln("Error: inDaylightTime(" + dateToString(max) + ") != " + ((!startsInDST)?"true":"false"));
+ errln("Error: inDaylightTime(" + dateToString(max) + ") != " + ((!startsInDST)?"true":"false"));
}
if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
while ((max - min) > INTERVAL) {
UDate time = d;
UDate limit = time + ONE_YEAR + ONE_DAY;
UBool lastState = z->inDaylightTime(d, status);
- if (failure(status, "TimeZone::inDaylightTime")) return;
+ if (failure(status, "TimeZone::inDaylightTime", TRUE)) return;
int32_t changes = 0;
logln(UnicodeString("-- Zone ") + z->getID(str) + " starts in " + year + " with DST = " + (lastState?"true":"false"));
logln(UnicodeString("useDaylightTime = ") + (z->useDaylightTime()?"true":"false"));
errln("FAIL: useDaylightTime false but 2 changes seen");
}
if (changes != expectedChanges) {
- errln(UnicodeString("FAIL: ") + changes + " changes seen; expected " + expectedChanges);
+ dataerrln(UnicodeString("FAIL: ") + changes + " changes seen; expected " + expectedChanges);
}
}
void
TimeZoneBoundaryTest::TestStepwise()
{
- TimeZone *zone = TimeZone::createTimeZone("EST");
+ TimeZone *zone = TimeZone::createTimeZone("America/New_York");
findBoundariesStepwise(1997, ONE_DAY, zone, 2);
delete zone;
zone = TimeZone::createTimeZone("UTC"); // updated 12/3/99 aliu