Example #1
0
U_CAPI int32_t U_EXPORT2
ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) {
    int32_t result = 0;
    TimeZone* zone = _createTimeZone(zoneID, -1, ec);
    if (U_SUCCESS(*ec)) {
        SimpleTimeZone* stz = dynamic_cast<SimpleTimeZone*>(zone);
        if (stz != NULL) {
            result = stz->getDSTSavings();
        } else {
            // Since there is no getDSTSavings on TimeZone, we use a
            // heuristic: Starting with the current time, march
            // forwards for one year, looking for DST savings.
            // Stepping by weeks is sufficient.
            UDate d = Calendar::getNow();
            for (int32_t i=0; i<53; ++i, d+=U_MILLIS_PER_DAY*7.0) {
                int32_t raw, dst;
                zone->getOffset(d, FALSE, raw, dst, *ec);
                if (U_FAILURE(*ec)) {
                    break;
                } else if (dst != 0) {
                    result = dst;
                    break;
                }
            }
        }
    }
    delete zone;
    return result;
}
Example #2
0
void
SimpleTimeZone::checkTransitionRules(UErrorCode& status) const {
    if (U_FAILURE(status)) {
        return;
    }
    umtx_lock(&gLock);
    if (!transitionRulesInitialized) {
        SimpleTimeZone *ncThis = const_cast<SimpleTimeZone*>(this);
        ncThis->initTransitionRules(status);
    }
    umtx_unlock(&gLock);
}
UDate TimeZoneRegressionTest::findTransitionStepwise(const SimpleTimeZone& tz, UDate min, UDate max) {
    UErrorCode status = U_ZERO_ERROR;
    UBool startsInDST = tz.inDaylightTime(min, status);
    if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0;
    while (min < max) {
        if (tz.inDaylightTime(min, status) != startsInDST) {
            return min;
        }
        if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0;
        min += (UDate)24*60*60*1000; // one day
    }
    return 0;
}
/**
 * @bug 4154537
 * SimpleTimeZone::hasSameRules() doesn't work for zones with no DST
 * and different DST parameters.
 */
void TimeZoneRegressionTest:: Test4154537() {
    UErrorCode status = U_ZERO_ERROR;
    // tz1 and tz2 have no DST and different rule parameters
    SimpleTimeZone *tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0, status);
    SimpleTimeZone *tz2 = new SimpleTimeZone(0, "2", 1, 0, 0, 0, 3, 0, 0, 0, status);
    // tza and tzA have the same rule params
    SimpleTimeZone *tza = new SimpleTimeZone(0, "a", 0, 1, 0, 0, 3, 2, 0, 0, status);
    SimpleTimeZone *tzA = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 3, 2, 0, 0, status);
    // tzb differs from tza
    SimpleTimeZone *tzb = new SimpleTimeZone(0, "b", 0, 1, 0, 0, 3, 1, 0, 0, status);
    
    if(U_FAILURE(status))
        errln("Couldn't create TimeZones");

    if (tz1->useDaylightTime() || tz2->useDaylightTime() ||
        !tza->useDaylightTime() || !tzA->useDaylightTime() ||
        !tzb->useDaylightTime()) {
        errln("Test is broken -- rewrite it");
    }
    if (!tza->hasSameRules(*tzA) || tza->hasSameRules(*tzb)) {
        errln("Fail: hasSameRules() broken for zones with rules");
    }
    if (!tz1->hasSameRules(*tz2)) {
        errln("Fail: hasSameRules() returns false for zones without rules");
        //errln("zone 1 = " + tz1);
        //errln("zone 2 = " + tz2);
    }

    delete tz1;
    delete tz2;
    delete tza;
    delete tzA;
    delete tzb;
}
UDate TimeZoneRegressionTest::findTransitionBinary(const SimpleTimeZone& tz, UDate min, UDate max) {
    UErrorCode status = U_ZERO_ERROR;
    UBool startsInDST = tz.inDaylightTime(min, status);
    if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0;
    if (tz.inDaylightTime(max, status) == startsInDST) {
        logln((UnicodeString)"Error: inDaylightTime() != " + ((!startsInDST)?"TRUE":"FALSE"));
        return 0;
    }
    if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0;
    while ((max - min) > 100) { // Min accuracy in ms
        UDate mid = (min + max) / 2;
        if (tz.inDaylightTime(mid, status) == startsInDST) {
            min = mid;
        } else {
            max = mid;
        }
        if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0;
    }
    return (min + max) / 2;
}
/**
 * @bug 4154542
 * SimpleTimeZOne constructors, setStartRule(), and setEndRule() don't
 * check for out-of-range arguments.
 */
void TimeZoneRegressionTest:: Test4154542() 
{
    const int32_t GOOD = 1;
    const int32_t BAD  = 0;

    const int32_t GOOD_MONTH       = UCAL_JANUARY;
    const int32_t GOOD_DAY         = 1;
    const int32_t GOOD_DAY_OF_WEEK = UCAL_SUNDAY;
    const int32_t GOOD_TIME        = 0;

    int32_t DATA [] = {
        GOOD, INT32_MIN,    0,  INT32_MAX,   INT32_MIN,
        GOOD, UCAL_JANUARY,    -5,  UCAL_SUNDAY,     0,
        GOOD, UCAL_DECEMBER,    5,  UCAL_SATURDAY,   24*60*60*1000,
        BAD,  UCAL_DECEMBER,    5,  UCAL_SATURDAY,   24*60*60*1000+1,
        BAD,  UCAL_DECEMBER,    5,  UCAL_SATURDAY,  -1,
        BAD,  UCAL_JANUARY,    -6,  UCAL_SUNDAY,     0,
        BAD,  UCAL_DECEMBER,    6,  UCAL_SATURDAY,   24*60*60*1000,
        GOOD, UCAL_DECEMBER,    1,  0,                   0,
        GOOD, UCAL_DECEMBER,   31,  0,                   0,
        BAD,  UCAL_APRIL,      31,  0,                   0,
        BAD,  UCAL_DECEMBER,   32,  0,                   0,
        BAD,  UCAL_JANUARY-1,   1,  UCAL_SUNDAY,     0,
        BAD,  UCAL_DECEMBER+1,  1,  UCAL_SUNDAY,     0,
        GOOD, UCAL_DECEMBER,   31, -UCAL_SUNDAY,     0,
        GOOD, UCAL_DECEMBER,   31, -UCAL_SATURDAY,   0,
        BAD,  UCAL_DECEMBER,   32, -UCAL_SATURDAY,   0,
        BAD,  UCAL_DECEMBER,  -32, -UCAL_SATURDAY,   0,
        BAD,  UCAL_DECEMBER,   31, -UCAL_SATURDAY-1, 0,
    };
    SimpleTimeZone *zone = new SimpleTimeZone(0, "Z");
    for (int32_t i=0; i < 18*5; i+=5) {
        UBool shouldBeGood = (DATA[i] == GOOD);
        int32_t month     = DATA[i+1];
        int32_t day       = DATA[i+2];
        int32_t dayOfWeek = DATA[i+3];
        int32_t time      = DATA[i+4];

        UErrorCode status = U_ZERO_ERROR;

        //Exception ex = null;
        //try {
            zone->setStartRule(month, day, dayOfWeek, time, status);
        //} catch (IllegalArgumentException e) {
        //    ex = e;
        //}
        if (U_SUCCESS(status) != shouldBeGood) {
            errln(UnicodeString("setStartRule(month=") + month + ", day=" + day +
                  ", dayOfWeek=" + dayOfWeek + ", time=" + time +
                  (shouldBeGood ? (") should work")
                   : ") should fail but doesn't"));
        }

        //ex = null;
        //try {
        status = U_ZERO_ERROR;
            zone->setEndRule(month, day, dayOfWeek, time, status);
        //} catch (IllegalArgumentException e) {
        //   ex = e;
        //}
        if (U_SUCCESS(status) != shouldBeGood) {
            errln(UnicodeString("setEndRule(month=") + month + ", day=" + day +
                  ", dayOfWeek=" + dayOfWeek + ", time=" + time +
                  (shouldBeGood ? (") should work")
                   : ") should fail but doesn't"));
        }

        //ex = null;
        //try {
        // {sfb} need to look into ctor problems! (UErrorCode vs. dst signature confusion)
        status = U_ZERO_ERROR;
            SimpleTimeZone *temp = new SimpleTimeZone(0, "Z",
                    (int8_t)month, (int8_t)day, (int8_t)dayOfWeek, time,
                    (int8_t)GOOD_MONTH, (int8_t)GOOD_DAY, (int8_t)GOOD_DAY_OF_WEEK, 
                    GOOD_TIME,status);
        //} catch (IllegalArgumentException e) {
        //    ex = e;
        //}
        if (U_SUCCESS(status) != shouldBeGood) {
            errln(UnicodeString("SimpleTimeZone(month=") + month + ", day=" + day +
                  ", dayOfWeek=" + dayOfWeek + ", time=" + time +
                  (shouldBeGood ? (", <end>) should work")// + ex)
                   : ", <end>) should fail but doesn't"));
        }
  
        delete temp;
        //ex = null;
        //try {
        status = U_ZERO_ERROR;
            temp = new SimpleTimeZone(0, "Z",
                    (int8_t)GOOD_MONTH, (int8_t)GOOD_DAY, (int8_t)GOOD_DAY_OF_WEEK, 
                    GOOD_TIME,
                    (int8_t)month, (int8_t)day, (int8_t)dayOfWeek, time,status);
        //} catch (IllegalArgumentException e) {
        //    ex = e;
        //}
        if (U_SUCCESS(status) != shouldBeGood) {
            errln(UnicodeString("SimpleTimeZone(<start>, month=") + month + ", day=" + day +
                  ", dayOfWeek=" + dayOfWeek + ", time=" + time +
                  (shouldBeGood ? (") should work")// + ex)
                   : ") should fail but doesn't"));
        }            
        delete temp;
    }
    delete zone;
}
// {sfb} will this work using a Calendar?
void TimeZoneRegressionTest:: Test4073215() 
{
    UErrorCode status = U_ZERO_ERROR;
    UnicodeString str, str2;
    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);
    failure(status, "z->setStartRule()");
    z->setEndRule(UCAL_MARCH, -1, UCAL_SUNDAY, 0, status);
    failure(status, "z->setStartRule()");
    if (!z->useDaylightTime())
        errln("Fail: DST not active");

    GregorianCalendar cal(1997, UCAL_JANUARY, 31, status);
    if(U_FAILURE(status)) {
      dataerrln("Error creating calendar %s", u_errorName(status));
      return;
    }
    failure(status, "new GregorianCalendar");
    cal.adoptTimeZone(z);

    SimpleDateFormat sdf((UnicodeString)"E d MMM yyyy G HH:mm", status); 
    if(U_FAILURE(status)) {
      dataerrln("Error creating date format %s", u_errorName(status));
      return;
    }
    sdf.setCalendar(cal); 
    failure(status, "new SimpleDateFormat");

    UDate jan31, mar1, mar31;

    UBool indt = z->inDaylightTime(jan31=cal.getTime(status), status);
    failure(status, "inDaylightTime or getTime call on Jan 31");
    if (indt) {
        errln("Fail: Jan 31 inDaylightTime=TRUE, exp FALSE");
    }
    cal.set(1997, UCAL_MARCH, 1);
    indt = z->inDaylightTime(mar1=cal.getTime(status), status);
    failure(status, "inDaylightTime or getTime call on Mar 1");
    if (!indt) {
        UnicodeString str;
        sdf.format(cal.getTime(status), str);
        failure(status, "getTime");
        errln((UnicodeString)"Fail: " + str + " inDaylightTime=FALSE, exp TRUE");
    }
    cal.set(1997, UCAL_MARCH, 31);
    indt = z->inDaylightTime(mar31=cal.getTime(status), status);
    failure(status, "inDaylightTime or getTime call on Mar 31");
    if (indt) {
        errln("Fail: Mar 31 inDaylightTime=TRUE, exp FALSE");
    }

    /*
    cal.set(1997, Calendar::DECEMBER, 31);
    UDate dec31 = cal.getTime(status);
    failure(status, "getTime");
    UDate trans = findTransitionStepwise(*z, jan31, dec31);
    logln((UnicodeString)"Stepwise from " +
          sdf.format(jan31, str.remove()) + "; transition at " +
          (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE"));
    trans = findTransitionStepwise(*z, mar1, dec31);
    logln((UnicodeString)"Stepwise from " +
          sdf.format(mar1, str.remove()) + "; transition at " +
          (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE"));
    trans = findTransitionStepwise(*z, mar31, dec31);
    logln((UnicodeString)"Stepwise from " +
          sdf.format(mar31, str.remove()) + "; transition at " +
          (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE"));
    */
}
/**
 * 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;
}
// test new API for JDK 1.2 8/31 putback
void
TimeZoneRegressionTest::TestJDK12API()
{
    // 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;
    }

    SimpleTimeZone *cst = dynamic_cast<SimpleTimeZone *>(cst1);

    if(pst->hasSameRules(*cst)) {
        errln("FAILURE: PST and CST have same rules");
    }

    UErrorCode status = U_ZERO_ERROR;
    int32_t offset1 = pst->getOffset(1,
        1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), status);
    failure(status, "getOffset() failed");


    int32_t offset2 = cst->getOffset(1,
        1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), 31, status);
    failure(status, "getOffset() failed");

    if(offset1 == offset2)
        errln("FAILURE: Sunday Oct. 26 1997 2:00 has same offset for PST and CST");

    // verify error checking
    pst->getOffset(1,
        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");

    status = U_ZERO_ERROR;
    cst->setDSTSavings(60*60*1000, status);
    failure(status, "setDSTSavings() failed");

    int32_t savings = cst->getDSTSavings();
    if(savings != 60*60*1000) {
        errln("setDSTSavings() failed");
    }

    delete pst;
    delete cst;
}