【问题标题】:ISO8601 to DateTime with time zone information preservedISO8601 到 DateTime,保留时区信息
【发布时间】:2013-09-27 14:03:14
【问题描述】:

下面是包含时区信息的 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 偏移量?

【问题讨论】:

    标签: java datetime deserialization jodatime


    【解决方案1】:

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

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

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

    改用DateTime.parse

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

    【讨论】:

    • 太棒了!我已经找到了一种使用ISODateTimeFormat.dateTimeParser().withOffsetParsed().parseDateTime(dateTimeString) 的方法,但这对眼睛来说要好得多。干杯。
    • @DominykasMostauskis 太棒了!我花了最后 20 分钟来解析代码,并用解释更新了我的答案。知道为什么它是这样工作的总是好的。希望这可以帮助。如果它有帮助,请不要忘记投票:)
    猜你喜欢
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多