保留时区信息的ISO8601到DateTime

时间:2013-09-22 16:52:54

标签: java datetime deserialization jodatime

以下是包含时区信息的ISO8601日期字符串的反序列化。请注意,时区信息丢失了:

scala> val date1 = new DateTime().withZone(DateTimeZone.forID("Europe/Berlin"))
date1: org.joda.time.DateTime = 2013-09-22T18:42:15.348+02:00

scala> date1.getZone()
res45: org.joda.time.DateTimeZone = Europe/Berlin

scala> val date2 = new DateTime(date1.toString())
date2: org.joda.time.DateTime = 2013-09-22T19:42:15.348+03:00

scala> date2.getZone()
res46: org.joda.time.DateTimeZone = Europe/Vilnius

scala> date1.getZone() == date2.getZone()
res47: Boolean = false

时区信息(UTC偏移)被序列化,如ISO8601字符串末尾的+03:00+02:00,但在反序列化后丢失。正如您所看到的date2 DateTime对象,我期望它是date1的副本,其系统的UTC偏移量而不是+02:00date1

如何对ISO8601字符串进行反序列化以保留UTC偏移?

1 个答案:

答案 0 :(得分:7)

您正在使用的构造函数new DateTime(Object instant)(实际传递给BaseDateTime)不会解析,而是转换给定的对象(在您的情况下,是String)。

长话短说,它使用默认时区:

  1. 构造函数将传递的参数视为Instant并从InstantConverter
  2. 请求ConverterManager
  3. 构造函数在StringConverter
  4. 上调用getInstantMillis()
  5. 该方法确实使用标准ISO 8601 DateTimeFormatter,而不是parse it calls parseMillis()
  6. parseMillis,您可以在javadocs中看到,在默认时区中返回日期。
  7. 改为使用DateTime.parse

    DateTime date2 = DateTime.parse(date1.toString());
    // 2013-09-22T19:21:48.461+02:00