in velox/functions/lib/JodaDateTime.cpp [278:367]
void parseFromPattern(
JodaFormatSpecifier curPattern,
const std::string& input,
const char*& cur,
const char* end,
JodaDate& jodaDate) {
// For now, timezone offset is the only non-numeric token supported.
if (curPattern != JodaFormatSpecifier::TIMEZONE_OFFSET_ID) {
int64_t number = 0;
bool negative = false;
if (cur < end && specAllowsNegative(curPattern) && *cur == '-') {
negative = true;
++cur;
}
auto startPos = cur;
while (cur < end && characterIsDigit(*cur)) {
number = number * 10 + (*cur - '0');
++cur;
}
// Need to have read at least one digit.
if (cur <= startPos) {
parseFail(input, cur, end);
}
if (negative) {
number *= -1L;
}
switch (curPattern) {
case JodaFormatSpecifier::YEAR:
case JodaFormatSpecifier::YEAR_OF_ERA:
jodaDate.isYearOfEra = (curPattern == JodaFormatSpecifier::YEAR_OF_ERA);
jodaDate.hasYear = true;
jodaDate.year = number;
break;
case JodaFormatSpecifier::MONTH_OF_YEAR:
jodaDate.month = number;
// Joda has this weird behavior where it returns 1970 as the year by
// default (if no year is specified), but if either day or month are
// specified, it fallsback to 2000.
if (!jodaDate.hasYear) {
jodaDate.hasYear = true;
jodaDate.year = 2000;
}
break;
case JodaFormatSpecifier::DAY_OF_MONTH:
jodaDate.day = number;
if (!jodaDate.hasYear) {
jodaDate.hasYear = true;
jodaDate.year = 2000;
}
break;
case JodaFormatSpecifier::HOUR_OF_DAY:
jodaDate.hour = number;
break;
case JodaFormatSpecifier::MINUTE_OF_HOUR:
jodaDate.minute = number;
break;
case JodaFormatSpecifier::SECOND_OF_MINUTE:
jodaDate.second = number;
break;
case JodaFormatSpecifier::FRACTION_OF_SECOND:
jodaDate.microsecond = number * util::kMicrosPerMsec;
break;
default:
VELOX_NYI(
"Numeric Joda specifier JodaFormatSpecifier::" +
getSpecifierName(static_cast<int>(curPattern)) +
" not implemented yet.");
}
} else {
try {
cur += parseTimezoneOffset(cur, end, jodaDate);
} catch (...) {
parseFail(input, cur, end);
}
}
}