docs: public void setValue(String value) throws SQLException {
      final boolean ISOFormat = !value.startsWith("@");
  
      // Just a simple '0'
      if (!ISOFormat && value.length() == 3 && value.charAt(2) == '0') {
        setValue(0, 0, 0, 0, 0, 0.0);
        return;
      }
  
      int years = 0;
      int months = 0;
      int days = 0;
      int hours = 0;
      int minutes = 0;
      double seconds = 0;
  
      try {
        String valueToken = null;
  
        value = value.replace('+', ' ').replace('@', ' ');
        final StringTokenizer st = new StringTokenizer(value);
        for (int i = 1; st.hasMoreTokens(); i++) {
          String token = st.nextToken();
  
          if ((i & 1) == 1) {
            int endHours = token.indexOf(':');
            if (endHours == -1) {
              valueToken = token;
              continue;
            }
  
            // This handles hours, minutes, seconds and microseconds for
            // ISO intervals
            int offset = (token.charAt(0) == '-') ? 1 : 0;
  
            hours = nullSafeIntGet(token.substring(offset + 0, endHours));
            minutes = nullSafeIntGet(token.substring(endHours + 1, endHours + 3));
  
            // Pre 7.4 servers do not put second information into the results
            // unless it is non-zero.
            int endMinutes = token.indexOf(':', endHours + 1);
            if (endMinutes != -1) {
              seconds = nullSafeDoubleGet(token.substring(endMinutes + 1));
            }
  
            if (offset == 1) {
              hours = -hours;
              minutes = -minutes;
              seconds = -seconds;
            }
  
            valueToken = null;
          } else {
            // This handles years, months, days for both, ISO and
            // Non-ISO intervals. Hours, minutes, seconds and microseconds
            // are handled for Non-ISO intervals here.
  
            if (token.startsWith("year")) {
              years = nullSafeIntGet(valueToken);
            } else if (token.startsWith("mon")) {
              months = nullSafeIntGet(valueToken);
            } else if (token.startsWith("day")) {
              days = nullSafeIntGet(valueToken);
            } else if (token.startsWith("hour")) {
              hours = nullSafeIntGet(valueToken);
            } else if (token.startsWith("min")) {
              minutes = nullSafeIntGet(valueToken);
            } else if (token.startsWith("sec")) {
              seconds = nullSafeDoubleGet(valueToken);
            }
          }
        }
      } catch (NumberFormatException e) {
        throw new PSQLException(GT.tr("Conversion of interval failed"),
            PSQLState.NUMERIC_CONSTANT_OUT_OF_RANGE, e);
      }
  
      if (!ISOFormat && value.endsWith("ago")) {
        // Inverse the leading sign
        setValue(-years, -months, -days, -hours, -minutes, -seconds);
      } else {
        setValue(years, months, days, hours, minutes, seconds);
      }
    }