Search code examples
javadateparser

DateTimeParseException on java 11 but not on java 8


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)

Solution

  • 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.