java.util.Illegalformatconversionexception: d != java.lang.Integer

Asked

Viewed 292 times

1

What’s going on here? I don’t think I can read the documentation from String format.(). For me this date/time conversion %td When receiving an integer within the interval of the day of the month it should work.

class Main {  
    public static void main(String args[]) { 
            System.out.println(String.format("%td", 30));
    }
}

Exit:

Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.Integer
    at java.base/java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4426)
    at java.base/java.util.Formatter$FormatSpecifier.printDateTime(Formatter.java:2980)
    at java.base/java.util.Formatter$FormatSpecifier.print(Formatter.java:2885)
    at java.base/java.util.Formatter.format(Formatter.java:2673)
    at java.base/java.util.Formatter.format(Formatter.java:2609)
    at java.base/java.lang.String.format(String.java:2897)
    at Main.main(Main.java:5)

Edit: It seems to me that the error is in being passing a whole and not a date. I was working with LocalDateTime to display in format %td/%tm/%ty %tH:%tM:%tS, does it work to pass a?

2 answers

1

I changed the way I did it, actually that’s basically what I wanted:

private static final DateTimeFormatter DATE_TIME_FORMATTER =
        DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");

LocalDateTime localDateTime = LocalDateTime.parse("2021-01-30T09:51:38");
String formattedDateTime = DATE_TIME_FORMATTER.format(localDateTime);
System.out.println(formattedDateTime);

Exit:

30/01/2021 09:51:38

Is a "solution XY" (that does not solve the original problem), but I will leave here because it should meet some other cases where it happens.

1


In the documentation of String.format there is a link to the format string syntax. And there is said the following:

The format specifiers for types which are used to represent Dates and times have the following syntax:

%[argument_index$][flags][width]conversion

About argument_index, we’ll talk further down.

flags and width are those options for alignment, fill with zeros, number of columns, etc. As you did not use, this is not the case. What matters to this case is conversion.

Still in the same section about dates and times, it is said that:

The required Conversion is a two Character Sequence. The first Character is’t' or’T'. The Second Character indicates the format to be used.

That is, if you have a "t" or "T", it is because we are formatting a date/time, and therefore the value to be passed should be a long, Long, java.util.Calendar, java.util.Date or java.time.temporal.TemporalAccessor (interface implemented by all date and time types of the java.time).

That’s why when using the format %td, he makes a mistake when you pass one int. The t indicates that the parameter should be one of the types mentioned above (and d follows the specific table of "Date/Time conversions", which in this case indicates the day of the month).

That is, if you pass one LocalDateTime (implementing TemporalAccessor), that would work:

// imprime o dia correspondente à data atual
System.out.println(String.format("%td", LocalDateTime.now()));

For the day is taken from the informed date.

To print more than one field of the same date, it’s kind of boring. So it doesn’t work:

System.out.println(String.format("%td/%tm/%ty %tH:%tM:%tS", LocalDateTime.now())); // exception!

For the %td corresponds to the LocalDateTime informed, but %tm refers to the next argument (which has not been informed). In order for all fields to refer to the same date, you must use the argument_index, whose syntax is N$, whereas N corresponds to the umpteenth date reported. So it should actually be this "beautiful thing":

System.out.println(String.format("%1$td/%1$tm/%1$ty %1$tH:%1$tM:%1$tS", LocalDateTime.now()));

But how you yourself have answered, the best way to format dates and times is to use the date API itself:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss");
System.out.println(formatter.format(LocalDateTime.now()));

About the use of uuuu instead of yyyy next year, see here.

  • Quick game, in the documentation speaks of using < in the format string, you know if it would have any use in this case or has nothing to do? When I looked over I thought it was something about repeating the previous parameter, something like that. If you can’t answer, no problem (I know, my laziness, but they say the important thing is not to know, is to have the phone of who knows kkk).

  • @Piovezan This I never used, but from what I understood, it would also work, because it serves to indicate that it is to use the same argument of the previous - ie, %1$td/%<tm/%<ty would be the same as %1$td/%1$tm/%1$ty

Browser other questions tagged

You are not signed in. Login or sign up in order to post.