代码之家  ›  专栏  ›  技术社区  ›  Neer1009

默认情况下,Json反序列化导致UTC到达本地时间

  •  0
  • Neer1009  · 技术社区  · 6 年前

    我正在尝试使用对象映射器反序列化侦听器通过IBM MQ接收的消息。

    我的POJO课程是:-

    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonProperty;
    
    /**
     * This class is used for JSON placeholder for gate out message from YMS
     *
     */
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class OutMessage {
    
        @JsonProperty("routeNbr")
        private Integer routeNbr;
    
        @JsonProperty("tNbr")
        private String tNbr;
    
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss.SSS ZZZ")
        @JsonProperty("tDepartedTS")
        private Date tDepartedTS;
    
        @JsonProperty("dcNbr")
        private String dcNbr;
    
        @JsonProperty("userID")
        private String userID;
    }
    

    我没有把盖特和塞特放在这里。

    当JMS消息侦听器收到以下JSON消息时:-

    {
      "routeNbr": "661",
      "dcNbr": "7390",
      "tNbr": "700159",
      "userID": "CLB003V",
      "tDepartedTS": "2018-07-13 12:01:02.417 UTC"
    }
    

    当它试图在消息侦听器中使用objectMapper(com.fasterxml.jackson.databind.objectMapper)进行反序列化时,如下所示:-

    OutMessage outMsg = new ObjectMapper().readValue(gateOutMessageString,
                    OutMessage.class);
    System.out.println(outMsg.gettDepartedTS());
    

    反序列化成功。唯一的问题是在反序列化之后,当应用程序试图获取 t分离 ,它不会打印给定的UTC时间(“2018-07-13 12:01:02.417 UTC”),但它会自动将+05:30添加到该时间并打印 2018年7月13日17:31:02

    原因是我正在运行来自印度的应用程序,即(UTC+05:30)。我的要求是,在反序列化之后获得tDepartedTS的操作时,应该 2018年7月13日12:01:02 . 它不应该在任何其他时区转换。

    1 回复  |  直到 6 年前
        1
  •  0
  •   kumesana    6 年前

    类java.util.Date不包含时区信息。

    就其而言,2018年7月13日17:31:02印度时间与2018-07-13 12:01:02.417 UTC时间完全相同。因为当你不在乎时区的时候,它实际上是同时发生的。它没有任何能力来区别两者。

    因此,当您将日期UTC解析为java.util.date类型的对象时,您可以获得它所表示的时间的正确信息,但会丢失它被读取为UTC这一事实的所有信息。

    如果你要求System.out.println()写出这个日期,它需要找出一种人性化的方法来写出它,而通常的方法是根据选定的时区写出日期。由于java.util.Date没有时区信息,System.out.println()选择一个自己的时区,并选择计算机的默认时区,因为这是唯一的逻辑选择。您可以使用日期格式来指定您希望如何写出此日期,包括但不限于哪个时区。

    但实际上,java.util.Date类和相关的类已经过时。您需要升级到java 8的新java.time包。在您的例子中,由于您对保留时区信息感兴趣,因此需要将时间存储在类对象中 java.time.ZonedDateTime