]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/tzbdtest.cpp
ICU-511.25.tar.gz
[apple/icu.git] / icuSources / test / intltest / tzbdtest.cpp
index 887226cec161d72eb8b726bbff1c820ab7f56e3e..5df0f4b856a4fde155aec3256c6a4bfdeb98c14f 100644 (file)
@@ -1,8 +1,8 @@
-/********************************************************************
+/***********************************************************************
  * 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"
 
@@ -12,6 +12,7 @@
 #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*/ )
 {
@@ -96,7 +97,7 @@ TimeZoneBoundaryTest::findDaylightBoundaryUsingDate(UDate d, const char* startMo
         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);
 }
  
 // -------------------------------------
@@ -119,12 +120,12 @@ TimeZoneBoundaryTest::findDaylightBoundaryUsingTimeZone(UDate d, UBool startsInD
     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;
@@ -175,7 +176,11 @@ TimeZoneBoundaryTest::showDate(UDate d)
 UnicodeString
 TimeZoneBoundaryTest::showNN(int32_t n)
 {
-    return ((n < 10) ? UnicodeString("0"): UnicodeString("")) + n;
+    UnicodeString nStr;
+    if (n < 10) {
+        nStr += UnicodeString("0", "");
+    }
+    return nStr + n;
 }
  
 // -------------------------------------
@@ -188,13 +193,19 @@ TimeZoneBoundaryTest::verifyDST(UDate d, TimeZone* time_zone, UBool expUseDaylig
     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;
@@ -205,12 +216,57 @@ TimeZoneBoundaryTest::verifyDST(UDate d, TimeZone* time_zone, UBool expUseDaylig
         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.
@@ -218,6 +274,50 @@ TimeZoneBoundaryTest::verifyDST(UDate d, TimeZone* time_zone, UBool expUseDaylig
 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 ---");
@@ -285,9 +385,9 @@ TimeZoneBoundaryTest::testUsingBinarySearch(SimpleTimeZone* tz, UDate d, UDate e
     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) {
@@ -354,7 +454,7 @@ TimeZoneBoundaryTest::findBoundariesStepwise(int32_t year, UDate interval, TimeZ
     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"));
@@ -380,7 +480,7 @@ TimeZoneBoundaryTest::findBoundariesStepwise(int32_t year, UDate interval, TimeZ
         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);
     }
 }
  
@@ -401,7 +501,7 @@ TimeZoneBoundaryTest::findBoundariesStepwise(int32_t year, UDate interval, TimeZ
 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