DateTimeParseException on java 11 but not on java 8

130 views Asked by At

Hello when I run the following code using java 8 all works fine

public class Main {
    public static void main(String[] args) {
       LocalDate date =  LocalDate.parse("24ENE1982", new DateTimeFormatterBuilder().parseCaseInsensitive()
                .appendPattern("ddMMMyyyy")
                .toFormatter(new Locale("es", "ES")));
        System.out.println("Hello world! " + date);
    }

but fail with java 11

More specific

java 11.0.19 2023-04-18 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.19+9-LTS-224) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.19+9-LTS-224, mixed mode)

If I use java 18 works too.

Any idea to solve this issue without upgrade or downgrade the java version

I have tried to set the Locale using

Locale.forLanguageTag("es-ES")

and

new Locale("es", "ES")

But with no changes

Expected value

Hello world! 1982-01-24

but an exception sin thrown

Exception in thread "main" java.time.format.DateTimeParseException: Text '24ENE1982' could not be parsed at index 2
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
    at java.base/java.time.LocalDate.parse(LocalDate.java:428)
    at Main.main(Main.java:7)
1

There are 1 answers

0
Pino On BEST ANSWER

As noted in the comments, in Java 11 the short month names have a trailing dot in Spanish. This is the cause of the problem, as a solution you could use a DateTimeFormatter with custom month names derived from the "official" ones but without any dot. The following example works with Java 8, Java 11 and Java 17.

import java.time.LocalDate;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Locale locale = new Locale("es", "ES");

        Map<Long, String> months = new HashMap<>();
        for (Month m : Month.values()) {
            months.put(Long.valueOf(m.getValue()),
                       m.getDisplayName(TextStyle.SHORT, locale).replace(".", ""));
        }                         

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .appendPattern("dd")
                .appendText(ChronoField.MONTH_OF_YEAR, months)
                .appendPattern("yyyy")
                .toFormatter(locale);
        
        LocalDate date = LocalDate.parse("24ENE1982", formatter);
        System.out.println("Hello world! " + date);
    }

}

Read also about Locale Data Providers at oracle.com.