1

My objective is to store dates into a database. To do this app I use Springboot, JPA, H2, ...

I use LocalDate and the format wished is yyyy-MM-dd.

Entity

@Entity
public class MyObject {

    @Id
    private String id;
    private LocalDate startdate;
    private LocalDate enddate;

    public MyObject() {}

    public MyObject(LocalDate enddate) {
        this.startdate = LocalDate.now();
        this.enddate = enddate;
    }

    ...
}

Main

private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
MyObject myObject = new MyObject(LocalDate.parse("2019-03-01", formatter));
myObject.setId(UUID.randomUUID().toString());
myObjectResource.save(myObject);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
System.out.println(myObject.getStartdate()); // 2019-02-23
System.out.println(myObject.getEnddate()); // 2019-03-01
HttpEntity<String> entity = new HttpEntity<>(this.toJsonString(myObject), headers);
System.out.println(entity.toString()); // <{"id":"ba6649e4-6e65-4f54-8f1a-f8fc7143b05a","startdate":{"year":2019,"month":"FEBRUARY","dayOfMonth":23,"dayOfWeek":"SATURDAY","era":"CE","dayOfYear":54,"leapYear":false,"monthValue":2,"chronology":{"id":"ISO","calendarType":"iso8601"}},"enddate":{"year":2019,"month":"MARCH","dayOfMonth":1,"dayOfWeek":"FRIDAY","era":"CE","dayOfYear":60,"leapYear":false,"monthValue":3,"chronology":{"id":"ISO","calendarType":"iso8601"}}},[Content-Type:"application/json"]>

private String toJsonString(Object o) throws Exception {
    ObjectMapper om = new ObjectMapper();
    return om.writeValueAsString(o);
}

Can you help me to understand why dates in entity.toString() are not the same as before with getMethods() ?

Thanks for help!

Royce
  • 1,557
  • 5
  • 19
  • 44
  • 1
    Because Jackson doesn't know how else to format and parse LocalDate unless you add a module to do so. https://github.com/FasterXML/jackson-modules-java8/tree/master/datetime – JB Nizet Feb 23 '19 at 12:11
  • One option is that you can store the date as a string in your database, but by this, you'll lose the capability to perform operations on the date. However, you'll have to convert date back to localDate object to perform these operations. – Akash Chandwani Feb 23 '19 at 12:16

1 Answers1

1

LocalDate.parse returns a new LocalDate object. The formatting options specified in the DateTimeFormatter get lost aftwerward.

Jackson (the JSON library you're using) doesn't know how you previously "formatted" the LocalDate, so it uses its own formatting.

You can register the JavaTimeModule

final ObjectMapper om = new ObjectMapper();
om.registerModule(new JavaTimeModule());

Or you can provide your custom JsonSerializer<T>.

LppEdd
  • 20,274
  • 11
  • 84
  • 139
  • So used `LocalDate` is not the good choice? Used `Date` is a better idea? – Royce Feb 23 '19 at 12:14
  • @N.Lamblin continue using the new Java 8 API (Date should never be used again), but choose one of the alternatives I provided above. – LppEdd Feb 23 '19 at 12:16
  • 1
    No, not at all. Date is basically deprecated. Both don't have a format. A Date is just a number of milliseconds. a LocalDate i just a year, a month and a day. **You** choose which format to use when parsing a String to a Date or LocalDate, and when transforming a LocalDate or a Date to a String. – JB Nizet Feb 23 '19 at 12:16
  • @LppEdd thanks a lot! However the Jackson documentation suggests using `com.fasterxml.jackson.datatype.jsr310.JavaTimeModule` because `JSR310Module()` is deprecated. – Royce Feb 23 '19 at 12:21