I know that's presumptuous to image found a bug in a library used every day by thousands of developpers. So I think the answer to my title question is "NO !!!", but ...
I have an object containing a date that I receive from my front end (JS), and I store it into a MongoDB database. I use Spring to get this object (with a REST Controller), and Spring to perform persistance (with a MongoDBRepository). My computer is configured with a CEST clock, so GMT+2 (UTC +0200).
The date in my POJO is stored in a LocalDateTime.
Here is my object :
class Test{
LocalDateTime when;
String data;
// getter setters...
}
The following unit test show that Spring (which use jackson-jsr310) fill my LocalDateTime with an UTC Date Time.
mockMvc.perform(post("/test")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content("{\"when\":\"2017-03-31T14:20:28.000Z\",\"data\":\"toto\"}")).andExpect(status().isOk());
List<com.robopec.models.Test> tests = testRepository.findAll();
Assert.assertEquals(14, tests.get(0).getWhen().getHour());
We can see in the jackson source code LocalDateTimeDeserializer.java line 74 :
return LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC);
But when I save in my database, spring use spring-data-commons to convert my LocalDateTime to a Date before storing the date in the database. We can read in spring-data-commons/../Jsr310Converters.java this :
public static enum LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
INSTANCE;
@Override
public Date convert(LocalDateTime source) {
return source == null ? null : Date.from(source.atZone(systemDefault()).toInstant());
}
}
So, spring-data JSR310 Converters interpret a localdatetime as an instant in the default system zone.
The problem is that when my front end send "2017-04-03T20:00:00Z", the REST controller store it in a LocalDateTime with the following time : 20:00:00. And when the mongo-data converter convert it into a date, the resulting time is 20:00:00+0200 (because my computer is in CEST time zone).
My conclusion is that I shouldn't store my date in a LocalDateTime but rather in a Date (java.util) or in an Instant.
But, is there a bug in one of the converters ?