public String format(Timestamp ts) {
    StringBuilder fullOutputSb = new StringBuilder();
    String outputString = null;
    int value;
    LocalDateTime localDateTime =
        LocalDateTime.ofEpochSecond(ts.toEpochSecond(), ts.getNanos(), ZoneOffset.UTC);
    for (Token token : tokens) {
      switch (token.type) {
      case NUMERIC_TEMPORAL:
      case CHARACTER_TEMPORAL:
        try {
          value = localDateTime.get(token.temporalField);
          if (token.type == TokenType.NUMERIC_TEMPORAL) {
            outputString = formatNumericTemporal(value, token);
          } else {
            outputString = formatCharacterTemporal(value, token);
          }
        } catch (DateTimeException e) {
          throw new IllegalArgumentException(token.temporalField + " couldn't be obtained from "
              + "LocalDateTime " + localDateTime, e);
        }
        break;
      case TIMEZONE: //invalid for timestamp and date
        throw new IllegalArgumentException(token.string.toUpperCase() + " not a valid format for "
            + "timestamp or date.");
      case SEPARATOR:
      case TEXT:
        outputString = token.string;
        break;
      case ISO_8601_DELIMITER:
        outputString = token.string.toUpperCase();
        break;
      default:
        // won't happen
      }
      fullOutputSb.append(outputString);
    }
    return fullOutputSb.toString();
  }
Make sure the generated list of tokens is valid for formatting datetime objects to strings.
common/src/java/org/apache/hadoop/hive/common/format/datetime/HiveSqlDateTimeFormatter.java