JetBrains/intellij-community · error · FormatDecode.IllegalFormatException

unknown conversion in ''{0}''

Error message

unknown conversion in ''{0}''

What it means

IllegalFormatException from FormatDecode's date/time branch: a '%t'/'%T' conversion whose date suffix character is not a known date/time conversion (getDateTimeConversionType returns UNKNOWN). Date suffixes are letters like H, M, S, Y, m, d, e, a, B, etc. (java.util.Formatter table); anything else, e.g. '%tq', is rejected. The message shows the dateSpec + conversion text.

Source

Thrown at java/java-analysis-impl/src/com/siyeh/ig/format/FormatDecode.java:310

        if (!previousAllowed) {
          throw new IllegalFormatException(InspectionGadgetsBundle.message("format.string.error.previous.element.not.found", specifier));
        }
      }
      else {
        previousAllowed = true;
        pos = implicit++;
      }

      final Validator allowed;
      if (isAllVerifier) {
        allowed = new AllValidatorWithRange(TextRange.create(matcher.start(), matcher.end()),
                                            new Spec(posSpec, flags, width, precision, dateSpec, conversion));
      }
      else if (dateSpec != null) {  // a t or T
        checkFlags(flagBits, LEFT_JUSTIFY | PREVIOUS, specifier);
        DateTimeConversionType dateTimeConversionType = getDateTimeConversionType(conversion.charAt(0));
        if (dateTimeConversionType == DateTimeConversionType.UNKNOWN) {
          throw new IllegalFormatException(
            InspectionGadgetsBundle.message("format.string.error.unknown.conversion", dateSpec + conversion));
        }
        checkNoPrecision(precision, specifier);
        allowed = new DateValidator(specifier, dateTimeConversionType);
      }
      else {
        switch (conversion.charAt(0)) {
          case 'b', 'B', 'h', 'H' -> { // boolean (general); Integer hex string (general)
            checkFlags(flagBits, LEFT_JUSTIFY | PREVIOUS, specifier);
            allowed = ALL_VALIDATOR;
          }
          case 's', 'S' -> { // formatted string (general)
            checkFlags(flagBits, LEFT_JUSTIFY | ALTERNATE | PREVIOUS, specifier);
            allowed = (flagBits & ALTERNATE) != 0 ? new FormattableValidator(specifier) : ALL_VALIDATOR;
          }
          case 'c', 'C' -> { // unicode character
            checkFlags(flagBits, LEFT_JUSTIFY | PREVIOUS, specifier);
            checkNoPrecision(precision, specifier);

View on GitHub (pinned to be881553f2)

Solutions

  1. Use a valid date/time suffix after %t (e.g. %tH hour, %tM minute, %tY year, %td day)
  2. Prefer DateTimeFormatter with converted patterns for complex time formatting
  3. Cross-check against the java.util.Formatter date/time table

Example fix

// before
String.format("%tq", cal)
// after
String.format("%tH", cal)
Defensive patterns

Strategy: validation

Validate before calling

private static final String DATE_SUFFIXES = "HIkMSsLNTzZAaBbCcdehjmGyYQqRstDFEux"; // java.util.Formatter date/time table
static boolean dateSuffixValid(char c) { return DATE_SUFFIXES.indexOf(c) >= 0; }

Try / catch

try { FormatDecode.decode(fmt, argc); } catch (IllegalFormatException e) { /* fix the character after %t */ }

Prevention

When it happens

Trigger: A specifier '%tX' or '%TX' where X is not in the date/time conversion table; occurs while decoding format strings used with Calendar/Date/Temporal arguments.

Common situations: Typos in time formatting ('%tS' seconds vs '%ts' epoch seconds confusion); porting strftime patterns (%H:%M) into java.util.Formatter syntax incorrectly.

Related errors


AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14). Data as JSON: /api/errors/24b6b6e8103014f9. Report an issue: GitHub.