Java / Kotlin:为什么Jackson解析日期与SimpleDateFormat不同?

时间:2018-01-15 04:37:48

标签: java jackson kotlin simpledateformat

我确定这是某种形式的用户错误,但我无法弄清楚我做错了什么。

我有一个Kotlin数据类,其构造函数字段如下:

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

这由ObjectMapper填充,它接受json字符串作为有效负载。对于我的单元测试,我有一个SimpleDateFormat对象,我使用相同的模式进行实例化。

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

我在单元测试中加载的json文件(CronEventPayload.json)具有完全相同的日期字符串(2018-01-15T00:48:43Z)但我的测试失败。

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

它们具有相同的输入并且使用相同的日期格式字符串,但它们明显不同。为什么这两个日期不一样?

1 个答案:

答案 0 :(得分:1)

@JsonFormat的默认时区为UTC。您可以使用注释的timezone属性覆盖。

SimpleDateFormat的默认时区是您当地的时区(MST,从您的输出读取)

确保时区匹配。您可以添加以下行:

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

正好位于SimpleDateFormat

的构建之下

虽然您的文字格式的日期包含时区(最后为Z,意为UTC),但您使用的格式只是将Z视为文字字符,你不是把它解释为时区。