1

Summary

I am attempting to parse dates such as 25/Sep/17 hence the SimpleDateFormat annotation seems to be @JsonFormat(pattern = "dd/MMM/yy"). However, when I try to parse this, I get an InvalidFormatException where the essence is (full exception below after example):

Text '25/Sep/17' could not be parsed at index 3

What is wrong with my date format string? I can't see any issues. It looks like it doesn't like the Sep paired with MMM.

I am using Amazon Corretto Java version "11.0.5" 2019-10-15 LTS

Example to reproduce

package example;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.time.LocalDate;

public class HelloMapperApp {
  private static final ObjectMapper MAPPER = new ObjectMapper();

  public static void main(String[] args) {
    MAPPER.registerModule(new JavaTimeModule());
    try {
      Example example = MAPPER.readValue("{ \"name\": \"example\", \"date\": \"25/Sep/17\"", Example.class);
      System.out.println("Deserialised is: " + example);
    } catch (Exception e) {
      throw new RuntimeException("Could not parse JSON: " + e);
    }
  }

  static class Example {
    @JsonProperty
    String name;
    @JsonProperty
    @JsonFormat(pattern = "dd/MMM/yy")
    LocalDate date;

    @Override
    public String toString() {
      return String.format("name: %s%ndate: %s", name, date);
    }
  }
}

Full Exception

Exception in thread "main" java.lang.RuntimeException: Could not parse JSON: com.fasterxml.jackson.databind.exc.InvalidFormatException: 
Cannot deserialize value of type 
`java.time.LocalDate` from String "25/Sep/17": Failed to deserialize java.time.LocalDate: 
(java.time.format.DateTimeParseException) Text '25/Sep/17' could not be parsed at index 3
 at [Source: (String)"{ "name": "example", "date": "25/Sep/17""; line: 1, column: 30] (through reference chain: example.HelloMapperApp$Example["date"])
        at example.HelloMapperApp.main(HelloMapperApp.java:19)
Friedrich 'Fred' Clausen
  • 3,321
  • 8
  • 39
  • 70
  • I just tried that with the usual ```java.time``` stuff and this pattern works with the given input. – akuzminykh Mar 20 '20 at 01:41
  • 1
    Since it works for you this gave me an idea. I tried the above example in Java 8 and it worked fine. However in Java 11 it fails with the above error. So it seems *Java 11* specific. At least the Corretto JDK 11 does not work with the above example. If you have time/inclination could you share which Java version you tried with? – Friedrich 'Fred' Clausen Mar 20 '20 at 01:49
  • I've used Java 11.0.3 (Oracle). I'm having a look [here](https://stackoverflow.com/questions/12463049/date-format-mapping-to-json-jackson) right now. Maybe this is something. Try out ```@JsonFormat(locale = "en", shape = JsonFormat.Shape.STRING, pattern = "dd/MMM/yy")```. – akuzminykh Mar 20 '20 at 01:51
  • Ah that works so, in this case anyway, having the `locale = "en"` is probably key. I could leave off the shape and just use `@JsonFormat(locale = "en", pattern = "dd/MMM/yy")` and it worked. A previous answer, since deleted, suggested using `LLL` since it is a local date. So using `dd/LLL/yy` is also working when specifying locale. Feel free to add an answer. – Friedrich 'Fred' Clausen Mar 20 '20 at 01:55

1 Answers1

2

It could be the case that the given input has a wrong format for the locale used by the formatter. Here is a similar post where someone had a problem with Sep where the formatter expected Sep. for Locale.CANADA.

Here and here you can check out how to set the locale for the formatter. E.g.:

@JsonFormat(locale = "en", pattern = "dd/MMM/yy")

FYI: You don't need to use LLL for months as a text. Have a look on DateTimeFormatter.

Number/Text: If the count of pattern letters is 3 or greater, use the Text rules above. Otherwise use the Number rules above.

When you use MMM, i.e. three times M, the formatter will implicitly use the text format.

akuzminykh
  • 4,522
  • 4
  • 15
  • 36