2

I have a date object like this:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
@get:JsonProperty("date") val date: Date

The problem is, when my app is setting this date object to Fri Nov 30 00:00:00 CET 2018, Jackson is setting this date to 2018-11-29 during deserialization. Can somebody give me a hint where the problem is hiding?

My minimum API level is 21.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
davidOhara
  • 1,008
  • 5
  • 17
  • 39
  • 1
    Probably a time zone issue. For example, Fri Nov 30 00:00:00 CET 2018 is the same point in time as 2018-11-29T23:00:00 UTC. – Ole V.V. Nov 30 '18 at 10:49
  • 1
    Without Jackson experience it would seem to me that the good solution lies in [`LocalDate`](https://docs.oracle.com/javase/10/docs/api/java/time/LocalDate.html) and [jackson-modules-java8](https://github.com/FasterXML/jackson-modules-java8). A `LocalDate`is a date without time of day and without time zone, so should eliminate any time zone problem. – Ole V.V. Nov 30 '18 at 10:52
  • Yes, its definitely a timezone issue. But how can I avoid this? – davidOhara Nov 30 '18 at 10:58
  • 1
    Can you use the Java 8 Data API instead? As @Ole V.V said, you can register the jackson-module-java8 and then use LocalDate to solve your problem. – Dean Nov 30 '18 at 11:01
  • Possible duplicate of [lost one day for a date](https://stackoverflow.com/questions/31622254/lost-one-day-for-a-date) – Ole V.V. Nov 30 '18 at 11:19
  • 1
    @OleV.V.I cannot use LocalDate as my min API is 21... – davidOhara Nov 30 '18 at 11:57
  • Thx for reporting your min level. I found the information important enough to include in the question, so I added it there. – Ole V.V. Nov 30 '18 at 12:28

3 Answers3

1

I suggest you use LocalDate instead of Date. This is a date without a timezone, so you can avoid any timezone problems.

For proper (de)serialization of LocalDate you need an additional dependency for Jackson:

implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.5")
Patric
  • 1,489
  • 13
  • 28
1

Given that discussion and answers have indicated that the Java 8 LocalDate would solve the issue, but that this is not an option for you given that your minimum API level is 21, an alternative solution is joda-time.

It provides a LocalDateTime class which holds no time zone information. It can be integrated with jackson using the jackson-datatype-joda module. You will have to register the module like so:

val objectMapper = ObjectMapper().apply { 
      registerModule(JodaModule())
}
Dean
  • 1,833
  • 10
  • 28
0

You need to configure the timezone on your ObjectMapper:

    val mapper = ObjectMapper().apply {
        setTimeZone(TimeZone.getDefault())
    }
Dean
  • 1,833
  • 10
  • 28
  • Is this problem occurring on the client or on the Server? – Dean Nov 30 '18 at 13:01
  • My other answer suggests using joda-time, the precursor to the Java8 data API to have a date object that does not have time-zone information. However, generally speaking you would want to have timezone information preserved, and to store as UTC on the server, and adjusted on the client. TimeZone.getDefault() should get the timezone for the client. – Dean Dec 03 '18 at 11:19