in velox/type/TimestampConversion.cpp [148:263]
bool tryParseDateString(
const char* buf,
size_t len,
size_t& pos,
int32_t& daysSinceEpoch,
bool strict) {
pos = 0;
if (len == 0) {
return false;
}
int32_t day = 0;
int32_t month = -1;
int32_t year = 0;
bool yearneg = false;
int sep;
// Skip leading spaces.
while (pos < len && characterIsSpace(buf[pos])) {
pos++;
}
if (pos >= len) {
return false;
}
if (buf[pos] == '-') {
yearneg = true;
pos++;
if (pos >= len) {
return false;
}
}
if (!characterIsDigit(buf[pos])) {
return false;
}
// First parse the year.
for (; pos < len && characterIsDigit(buf[pos]); pos++) {
year = (buf[pos] - '0') + year * 10;
if (year > kMaxYear) {
break;
}
}
if (yearneg) {
year = -year;
if (year < kMinYear) {
return false;
}
}
if (pos >= len) {
return false;
}
// Fetch the separator.
sep = buf[pos++];
if (sep != ' ' && sep != '-' && sep != '/' && sep != '\\') {
// Invalid separator.
return false;
}
// Parse the month.
if (!parseDoubleDigit(buf, len, pos, month)) {
return false;
}
if (pos >= len) {
return false;
}
if (buf[pos++] != sep) {
return false;
}
if (pos >= len) {
return false;
}
// Now parse the day.
if (!parseDoubleDigit(buf, len, pos, day)) {
return false;
}
// Check for an optional trailing " (BC)".
if (len - pos >= 5 && characterIsSpace(buf[pos]) && buf[pos + 1] == '(' &&
buf[pos + 2] == 'B' && buf[pos + 3] == 'C' && buf[pos + 4] == ')') {
if (yearneg || year == 0) {
return false;
}
year = -year + 1;
pos += 5;
if (year < kMinYear) {
return false;
}
}
// In strict mode, check remaining string for non-space characters.
if (strict) {
// Skip trailing spaces.
while (pos < len && characterIsSpace(buf[pos])) {
pos++;
}
// Check position. if end was not reached, non-space chars remaining.
if (pos < len) {
return false;
}
} else {
// In non-strict mode, check for any direct trailing digits.
if (pos < len && characterIsDigit(buf[pos])) {
return false;
}
}
daysSinceEpoch = fromDate(year, month, day);
return true;
}