std::string IntervalValue::ToISO8601()

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;
}