absl::StatusOr FromDateTimeFormatElementToFormatString()

in sql_utils/public/functions/cast_date_time.cc [1732:1833]


absl::StatusOr<std::string> FromDateTimeFormatElementToFormatString(
    const DateTimeFormatElement& format_element,
    const absl::TimeZone::CivilInfo info) {
  switch (format_element.type) {
    case FormatElementType::kSimpleLiteral:
    case FormatElementType::kDoubleQuotedLiteral:
      return format_element.literal_value;
    case FormatElementType::kWhitespace: {
      std::string res = "";
      for (int i = 0; i < format_element.len_in_format_str; ++i) {
        res.push_back(' ');
      }
      return res;
    }
    case FormatElementType::kYYYY:
    case FormatElementType::kYYY:
    case FormatElementType::kYY:
    case FormatElementType::kY:
    case FormatElementType::kRRRR:
    case FormatElementType::kRR: {
      int element_length = format_element.len_in_format_str;
      // YYYY will output the whole year regardless of how many digits are in
      // the year.
      // FormatTime does not support the year with the last 3 digits.
      int trunc_year =
          static_cast<int>(info.cs.year()) % powers_of_ten[element_length];
      return absl::StrFormat(
          "%0*d", format_element.len_in_format_str,
          (element_length == 4 ? info.cs.year() : trunc_year));
      break;
    }
    case FormatElementType::kMM:
      return "%m";
    case FormatElementType::kMON:
      return "%b";
    case FormatElementType::kMONTH:
      return "%B";
    case FormatElementType::kD:
      return std::to_string(internal_functions::DayOfWeekIntegerSunToSat1To7(
          absl::GetWeekday(info.cs)));
    case FormatElementType::kDD:
      return "%d";
    case FormatElementType::kDDD:
      return "%j";
    case FormatElementType::kDAY:
      return "%A";
    case FormatElementType::kDY:
      return "%a";
    case FormatElementType::kHH:
    case FormatElementType::kHH12:
      return "%I";
    case FormatElementType::kHH24:
      return "%H";
    case FormatElementType::kMI:
      return "%M";
    case FormatElementType::kSS:
      return "%S";
    case FormatElementType::kSSSSS: {
      // FormatTime does not support having 5 digit second of the day.
      int second_of_day = info.cs.hour() * kNaiveNumSecondsPerHour +
                          info.cs.minute() * kNaiveNumSecondsPerMinute +
                          info.cs.second();
      return absl::StrFormat("%05d", second_of_day);
    }
    case FormatElementType::kFFN: {
      return absl::StrCat("%E", format_element.subsecond_digit_count, "f");
    }
    case FormatElementType::kAM:
    case FormatElementType::kPM: {
      if (info.cs.hour() >= 12) {
        return "PM";
      } else {
        return "AM";
      }
    }
    case FormatElementType::kAMWithDots:
    case FormatElementType::kPMWithDots: {
      if (info.cs.hour() >= 12) {
        return "P.M.";
      } else {
        return "A.M.";
      }
    }
    case FormatElementType::kTZH:
    case FormatElementType::kTZM: {
      bool positive_offset;
      int32_t hour_offset;
      int32_t minute_offset;
      internal_functions::GetSignHourAndMinuteTimeZoneOffset(
          info, &positive_offset, &hour_offset, &minute_offset);
      if (format_element.type == FormatElementType::kTZH) {
        return absl::StrFormat("%c%02d", positive_offset ? '+' : '-',
                               hour_offset);
      } else {
        return absl::StrFormat("%02d", minute_offset);
      }
    }
    default:
      return MakeEvalError()
             << "Unsupported format element " << format_element.ToString();
  }
}