in sql_utils/public/interval_value.cc [367:411]
std::string IntervalValue::ToISO8601() const {
int64_t years = get_months() / 12;
int64_t months = get_months() % 12;
int64_t days = get_days();
__int128 total_nanos = get_nanos();
int64_t hours = total_nanos / kNanosInHour;
int64_t minutes = (total_nanos % kNanosInHour) / kNanosInMinute;
int64_t seconds = (total_nanos % kNanosInMinute) / kNanosInSecond;
int64_t subseconds = total_nanos % kNanosInSecond;
std::string result("P");
if (years != 0) absl::StrAppend(&result, years, "Y");
if (months != 0) absl::StrAppend(&result, months, "M");
if (days != 0) absl::StrAppend(&result, days, "D");
if (total_nanos != 0) absl::StrAppend(&result, "T");
if (hours != 0) absl::StrAppend(&result, hours, "H");
if (minutes != 0) absl::StrAppend(&result, minutes, "M");
if (seconds != 0 || subseconds != 0) {
if (subseconds == 0) {
absl::StrAppend(&result, seconds, "S");
} else {
if (seconds != 0) {
absl::StrAppend(&result, seconds, ".");
} else if (total_nanos < 0) {
absl::StrAppend(&result, "-0.");
} else {
absl::StrAppend(&result, "0.");
}
// Print fractions of a second without trailing zeros
if (subseconds < 0) subseconds = -subseconds;
for (int64_t factor :
{100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1}) {
int64_t digit = subseconds / factor;
absl::StrAppend(&result, digit);
subseconds %= factor;
if (subseconds == 0) {
break;
}
}
absl::StrAppend(&result, "S");
}
}
if (result.size() == 1) absl::StrAppend(&result, "0Y");
return result;
}