in sql_utils/public/functions/parse_date_time.cc [403:471]
absl::Status CanonicalizeDateParseContext(
DateParseContext* date_parse_context) {
if (date_parse_context->elements.empty()) {
// If there are no entries then there is nothing to canonicalize.
// Note that if there is 1 entry we still might need to canonicalize it,
// for example in the case where the only element present is day of week,
// which should be removed/ignored.
return absl::OkStatus();
}
int64_t weekday_idx = -1;
int64_t iso_year_idx = -1;
int64_t non_iso_dayofyear_idx = -1;
int64_t non_iso_week_idx = -1;
int64_t iso_week_idx = -1;
int64_t iso_dayofyear_idx = -1;
// Loop through the elements and record the last position of each of
// the elements.
for (int64_t idx = 0; idx < date_parse_context->elements.size(); ++idx) {
switch (date_parse_context->elements[idx].fmt) {
case 'A': // Full weekday name
case 'a': // Abbreviated weekday name
case 'u': // weekday number 1-7, starting Monday
case 'w': // weekday number 0-6, starting Sunday
weekday_idx = idx;
break;
case 'G': // ISO 8601 year with century, e.g., 2019
case 'g': // ISO 8601 year without century, e.g., 19
iso_year_idx = idx;
break;
case 'J': // ISO day of year
// We ignore ISO elements if non-ISO elements are present.
iso_dayofyear_idx = idx;
break;
case 'j': // Non-ISO day of year
non_iso_dayofyear_idx = idx;
break;
case 'U': // Non-ISO week number of the year (starting Sunday) 00-53
case 'W': // Non-ISO week number of the year (starting Monday) 00-53
non_iso_week_idx = idx;
break;
case 'V': // ISO 8601 week number of the ISO YEAR
// We ignore ISO elements if non-ISO elements are present.
iso_week_idx = idx;
break;
default:
SQL_RET_CHECK_FAIL() << "Unexpected format element: '"
<< date_parse_context->elements[idx].fmt << "'";
}
}
// Ignore ISO parts if non-ISO parts are present.
if (date_parse_context->non_iso_date_part_present) {
iso_year_idx = -1;
iso_week_idx = -1;
iso_dayofyear_idx = -1;
}
if (iso_year_idx >= 0) {
// We have an ISO date.
return CanonicalizeISODateParseContext(iso_year_idx, iso_week_idx,
iso_dayofyear_idx, weekday_idx,
date_parse_context);
}
// Otherise we have a non-ISO date.
return CanonicalizeNonISODateParseContext(
non_iso_week_idx, non_iso_dayofyear_idx, weekday_idx, date_parse_context);
}