如何从 ZonedDateTime 转换为 Joda DateTime

how to convert from ZonedDateTime to Joda DateTime

我已经将日期时间切换到 threeten,但我仍然有一个第 3 方工具使用 joda 将带时区的时间戳写入数据库,我需要从一个转换为另一个。 最好的方法是什么? 作为一种解决方法,我尝试了 DateTime.parse(zdt.toString) 但它失败了,因为 joda 不喜欢区域格式

格式无效:“2015-01-25T23:35:07.684Z[Europe/London]”在“[Europe/London]”

处格式错误
ZonedDateTime zdt = 
  ZonedDateTime.of(
    2015, 1, 25, 23, 35, 7, 684000000, 
    ZoneId.of("Europe/London"));

System.out.println(zdt); // 2015-01-25T23:35:07.684Z[Europe/London]
System.out.println(zdt.getZone().getId()); // Europe/London
System.out.println(zdt.toInstant().toEpochMilli()); // 1422228907684

DateTimeZone london = DateTimeZone.forID(zdt.getZone().getId());
DateTime dt = new DateTime(zdt.toInstant().toEpochMilli(), london);
System.out.println(dt); // 2015-01-25T23:35:07.684Z

如果区域 ID 转换可能因任何不受支持或无法识别的 ID 而崩溃,我建议

  • 捕获并记录它,
  • 更新 tz 存储库(对于 Joda:更新到最新版本,对于 JDK:使用 tz-updater-tool)

这通常是比默默地回退到任何任意 tz 偏移(如 UTC)更好的策略。

请注意,使用 DateTimeZone.forID(...) 是不安全的,这可能会引发 DateTimeParseException,因为通常 ZoneOffset.UTC 的 ID "Z" 无法被 DateTimeZone 识别。

为了将 ZonedDateTime 转换为 DateTime,我推荐的是:

return new DateTime(
    zonedDateTime.toInstant().toEpochMilli(),
    DateTimeZone.forTimeZone(TimeZone.getTimeZone(zonedDateTime.getZone())));

这里有一个 kotlin 扩展来做同样的事情(以防你这样编码)

fun ZonedDateTime.toDateTime(): DateTime =
    DateTime(this.toInstant().toEpochMilli(), 
        DateTimeZone.forTimeZone(TimeZone.getTimeZone(this.zone)))