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;
}