in cpp-ch/local-engine/Functions/SparkFunctionToDate.cpp [46:97]
bool checkAndGetDate32(DB::ReadBuffer & buf, DB::DataTypeDate32::FieldType &x, const DateLUTImpl & date_lut) const
{
auto checkNumbericASCII = [&](DB::ReadBuffer & rb, size_t start, size_t length) -> bool
{
for (size_t i = start; i < start + length; ++i)
{
if (!isNumericASCII(*(rb.position() + i)))
return false;
}
return true;
};
auto checkDelimiter = [&](DB::ReadBuffer & rb, size_t pos) -> bool
{
if (*(rb.position() + pos) != '-')
return false;
else
return true;
};
if (!checkNumbericASCII(buf, 0, 4)
|| !checkDelimiter(buf, 4)
|| !checkNumbericASCII(buf, 5, 2)
|| !checkDelimiter(buf, 7)
|| !checkNumbericASCII(buf, 8, 2))
return false;
else
{
UInt8 month = (*(buf.position() + 5) - '0') * 10 + (*(buf.position() + 6) - '0');
if (month <= 0 || month > 12)
return false;
UInt8 day = (*(buf.position() + 8) - '0') * 10 + (*(buf.position() + 9) - '0');
if (day <= 0 || day > 31)
return false;
else if (day == 31 && (month == 2 || month == 4 || month == 6 || month == 9 || month == 11))
return false;
else if (day == 30 && month == 2)
return false;
else
{
Int16 year = (*(buf.position() + 0) - '0') * 1000 +
(*(buf.position() + 1) - '0') * 100 +
(*(buf.position() + 2) - '0') * 10 +
(*(buf.position() + 3) - '0');
if (day == 29 && month == 2 && year % 4 != 0)
return false;
else
{
x = date_lut.makeDayNum(year, month, day, -static_cast<Int32>(date_lut.getDayNumOffsetEpoch()));
return true;
}
}
}
}