【问题标题】:What is the best way to convert a org.joda.time.DateTime to a java.time.OffsetDateTime?将 org.joda.time.DateTime 转换为 java.time.OffsetDateTime 的最佳方法是什么?
【发布时间】:2016-09-27 11:15:26
【问题描述】:

以下工作,但将时间转换为long,然后是Instant,以及将时区转换为TimeZone,然后是ZoneId,似乎有点笨拙。有没有更清洁的方法来做到这一点?

java.time.Instant instant = java.time.Instant.ofEpochMilli(jodaDateTime.getMillis());
OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(instant,
        jodaDateTime.getZone().toTimeZone().toZoneId());

【问题讨论】:

  • 这看起来是解决方案的预期复杂性
  • 它看起来不错 - 如果性能不是问题,您可以通过字符串来实现:OffsetDateTime.parse(ISODateTimeFormat.dateTime().fmt(jodaDateTime), DateTimeFormatter.ISO_OFFSET_DATE_TIME); - 不确定它是否不那么笨拙......
  • 我建议您在代码中只使用其中一种。同时使用 joda.time 和 java-time 您可能会在代码中陷入复杂和混乱。您可以做的另一个解决方案是使用格式化程序将您的时间从 joda 输出到字符串,然后使用不同的 JavaTime 格式化程序对其进行反序列化。

标签: java jodatime java-time datetime-conversion


【解决方案1】:

这似乎是进行这种转换的一般方式。

由于两个 API 中的类不能相互操作(你不能使用 Joda 的 DateTime 和 Java Time 的 DateTimeFormatter 等等),它们之间的共同因素似乎是 long epochMilli 值。

所以我认为没有比创建 java.time.Instant 并使用 Joda 对象中的时区将其转换为 OffsetDateTime 更好的方法了。

嗯,我认为有一件事可以稍微改进。这段代码:

jodaDateTime.getZone().toTimeZone().toZoneId()

toTimeZone() 方法创建一个java.util.Timezone 实例,该实例用于通过toZoneId() 方法创建一个java.time.ZoneId

您可以通过执行以下操作来避免创建此临时 TimeZone 对象:

ZoneId.of(jodaDateTime.getZone().getID())

此代码不会创建临时的TimeZone 对象,而是直接创建ZoneId。作为 Joda 的DateTimeZone doesn't work with short IDs(如ISTPST),我们可以假设ID 可以被ZoneId 类识别(因为它也适用于长ID 名称,例如Europe/London)。如果 Joda 的 DateTimeZone ID 是偏移量(例如 +01:00),它也可以工作。

不确定避免创建一个临时对象是否足够干净,但无论如何这是一种改进(很小,但它仍然是)。

因此,最终代码将与您的非常相似,只是上面提出的更改:

// java.time.Instant
Instant instant = Instant.ofEpochMilli(jodaDateTime.getMillis());

// create the OffsetDateTime
OffsetDateTime.ofInstant(instant, ZoneId.of(jodaDateTime.getZone().getID()));

还有另一种选择(非常相似,但不确定是否更简洁):获取总偏移量(而不是时区)并使用它来创建java.time.ZoneOffset

long millis = jodaDateTime.getMillis();
// java.time.Instant
Instant instant = Instant.ofEpochMilli(millis);

// get total offset (joda returns milliseconds, java.time takes seconds)
int offsetSeconds = jodaDateTime.getZone().getOffset(millis) / 1000;
OffsetDateTime.ofInstant(instant, ZoneOffset.ofTotalSeconds(offsetSeconds));

您也可以使用@assylias' comment 提出的建议,但我不确定格式化为String 然后将其解析为OffsetDateTime 是否比这更干净(尽管它也有效)。

【讨论】:

    猜你喜欢
    • 2016-05-29
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多