static BOOL interval2istruct()

in sql-odbc/src/sqlodbc/convert.c [404:511]


static BOOL interval2istruct(SQLSMALLINT ctype, int precision, const char *str,
                             SQL_INTERVAL_STRUCT *st) {
    char lit1[64], lit2[64];
    int scnt, years, mons, days, hours, minutes, seconds;
    SQLSMALLINT sign;
    SQLINTERVAL itype = interval2itype(ctype);

    memset(st, 0, sizeof(SQL_INTERVAL_STRUCT));
    if ((scnt = sscanf(str, "%d-%d", &years, &mons)) >= 2) {
        if (SQL_IS_YEAR_TO_MONTH == itype) {
            sign = years < 0 ? SQL_TRUE : SQL_FALSE;
            st->interval_type = itype;
            st->interval_sign = sign;
            st->intval.year_month.year = sign ? (-years) : years;
            st->intval.year_month.month = mons;
            return TRUE;
        }
        return FALSE;
    } else if (scnt = sscanf(str, "%d %02d:%02d:%02d.%09s", &days, &hours,
                             &minutes, &seconds, lit2),
               5 == scnt || 4 == scnt) {
        sign = days < 0 ? SQL_TRUE : SQL_FALSE;
        st->interval_type = itype;
        st->interval_sign = sign;
        st->intval.day_second.day = sign ? (-days) : days;
        st->intval.day_second.hour = hours;
        st->intval.day_second.minute = minutes;
        st->intval.day_second.second = seconds;
        if (scnt > 4)
            st->intval.day_second.fraction = getPrecisionPart(precision, lit2);
        return TRUE;
    } else if ((scnt =
                    sscanf(str, "%d %10s %d %10s", &years, lit1, &mons, lit2))
               >= 4) {
        if (strnicmp(lit1, "year", 4) == 0 && strnicmp(lit2, "mon", 2) == 0
            && (SQL_IS_MONTH == itype || SQL_IS_YEAR_TO_MONTH == itype)) {
            sign = years < 0 ? SQL_TRUE : SQL_FALSE;
            st->interval_type = itype;
            st->interval_sign = sign;
            st->intval.year_month.year = sign ? (-years) : years;
            st->intval.year_month.month = sign ? (-mons) : mons;
            return TRUE;
        }
        return FALSE;
    }
    if ((scnt = sscanf(str, "%d %10s %d", &years, lit1, &days)) == 2) {
        sign = years < 0 ? SQL_TRUE : SQL_FALSE;
        if (SQL_IS_YEAR == itype
            && (stricmp(lit1, "year") == 0 || stricmp(lit1, "years") == 0)) {
            st->interval_type = itype;
            st->interval_sign = sign;
            st->intval.year_month.year = sign ? (-years) : years;
            return TRUE;
        }
        if (SQL_IS_MONTH == itype
            && (stricmp(lit1, "mon") == 0 || stricmp(lit1, "mons") == 0)) {
            st->interval_type = itype;
            st->interval_sign = sign;
            st->intval.year_month.month = sign ? (-years) : years;
            return TRUE;
        }
        if (SQL_IS_DAY == itype
            && (stricmp(lit1, "day") == 0 || stricmp(lit1, "days") == 0)) {
            st->interval_type = itype;
            st->interval_sign = sign;
            st->intval.day_second.day = sign ? (-years) : years;
            return TRUE;
        }
        return FALSE;
    }
    if (itype == SQL_IS_YEAR || itype == SQL_IS_MONTH
        || itype == SQL_IS_YEAR_TO_MONTH) {
        /* these formats should've been handled above already */
        return FALSE;
    }
    scnt = sscanf(str, "%d %10s %02d:%02d:%02d.%09s", &days, lit1, &hours,
                  &minutes, &seconds, lit2);
    if (scnt == 5 || scnt == 6) {
        if (strnicmp(lit1, "day", 3) != 0)
            return FALSE;
        sign = days < 0 ? SQL_TRUE : SQL_FALSE;

        st->interval_type = itype;
        st->interval_sign = sign;
        st->intval.day_second.day = sign ? (-days) : days;
        st->intval.day_second.hour = sign ? (-hours) : hours;
        st->intval.day_second.minute = minutes;
        st->intval.day_second.second = seconds;
        if (scnt > 5)
            st->intval.day_second.fraction = getPrecisionPart(precision, lit2);
        return TRUE;
    }
    scnt = sscanf(str, "%02d:%02d:%02d.%09s", &hours, &minutes, &seconds, lit2);
    if (scnt == 3 || scnt == 4) {
        sign = hours < 0 ? SQL_TRUE : SQL_FALSE;

        st->interval_type = itype;
        st->interval_sign = sign;
        st->intval.day_second.hour = sign ? (-hours) : hours;
        st->intval.day_second.minute = minutes;
        st->intval.day_second.second = seconds;
        if (scnt > 3)
            st->intval.day_second.fraction = getPrecisionPart(precision, lit2);
        return TRUE;
    }

    return FALSE;
}