Niko
Niko

Reputation: 4448

Java/Kotlin: Why does Jackson parse dates differently from SimpleDateFormat?

I'm sure this is some form of user error, but I can't puzzle out what I'm doing incorrectly.

I have a Kotlin data class that with a constructor field like this:

data class CronEvent(
    @JsonFormat(
            shape = JsonFormat.Shape.STRING,
            pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'"
    )
    @JsonProperty("time")
    val time: Date
 )

This gets populated by ObjectMapper that accepts a json string as a payload. For my unit test, I have a SimpleDateFormat object that I instantiate with the same pattern.

val jsonStream = CronEventTests::class.java.classLoader.getResourceAsStream("CronEventPayload.json")
val cronEvent = jsonStreamToCronEvent(jsonStream)
// ...
val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
val expectedDate = simpleDateFormat.parse("2018-01-15T00:48:43Z")
cronEvent.time shouldBe expectedDate

The json file (CronEventPayload.json) that I load in my unit test has the exact same date string (2018-01-15T00:48:43Z) yet my test fails.

java.lang.AssertionError: expected: Mon Jan 15 00:48:43 MST 2018 but was: Sun Jan 14 17:48:43 MST 2018
Expected :Mon Jan 15 00:48:43 MST 2018 
Actual   :Sun Jan 14 17:48:43 MST 2018

They have the same input and are utilizing the same date format string, but they're clearly different. Why are these two dates not the same?

Upvotes: 4

Views: 2413

Answers (1)

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31269

The default timezone for @JsonFormat is UTC. You can override with the timezone attribute of the annotation.

The default timezone for SimpleDateFormat is your local timezone (MST, reading from your output)

Make sure that the timezones match. You can add the line:

simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

just below the construction of your SimpleDateFormat.

Although your dates in their text format contains the timezone (the Z at the end, meaning UTC), you're using a format that just treats the Z as a literal character, you're not interpreting it as a timezone.

Upvotes: 1

Related Questions