Java 17迁移:OffsetDateTime无withZone及print适配问题求助
Joda Time 迁移至 Java 17 OffsetDateTime 问题解决方案
问题分析
你遇到的两个错误本质是Joda Time 与 Java 标准库时间类不兼容导致的:
OffsetDateTime是 Java 标准库类型,没有 JodaDateTime的withZone方法- 你仍在使用 Joda 的
DateTimeFormatter,它只能处理 Joda 时间类型,无法识别 Java 标准库的ZonedDateTime
完整解决方案
1. 移除无用依赖
首先删除 Gradle 中 Joda 相关的 usertype 依赖,JPA 2.2+(Java 17 配套的 JPA 版本已支持)原生支持 Java 8+ 时间类型,无需第三方类型转换:
// 删除此行 // implementation 'org.jadira.usertype:usertype.core:7.0.0.CR1'
2. 调整实体类代码
移除 Joda 相关注解,直接使用 Java 标准库的 OffsetDateTime:
import java.time.OffsetDateTime; import jakarta.persistence.Entity; import jakarta.persistence.Table; import jakarta.persistence.Column; @Entity @Table(name = "logs") public class Log { @Column(name = "inserted_date") private OffsetDateTime insertedDate; // getter 和 setter 保持不变 }
3. 替换日期格式化逻辑
将 Joda 的 DateTimeFormatter 替换为 Java 标准库的 java.time.format.DateTimeFormatter,并调整时区转换和格式化代码:
import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; // 注意:原模式中的 mm 是分钟,若要表示月份需改成 MM(大写),此处保留原模式格式 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yy-MM-dd'T'HH:mm:ss'Z'") .withZone(ZoneOffset.UTC); // 设置当前时间(默认带系统偏移量,也可直接指定UTC) log.setInsertedDate(OffsetDateTime.now()); // 格式化时直接传入 OffsetDateTime,Formatter 会自动转成 UTC 时区 String formattedDate = dateFormatter.format(log.getInsertedDate()); log.setTimestamp(formattedDate);
关键细节说明
- 时区转换:Java 标准库的
DateTimeFormatter可通过withZone直接指定输出时区,无需手动转换时间对象 - 模式注意事项:原模式中的
yy-mm-dd里的mm代表分钟,若实际需求是月份,需改成MM(大写),避免日期解析/格式化错误 - JPA 兼容性:确保你的 JPA 版本(如 Hibernate 5.3+)支持 Java 8+ 时间类型,Java 17 搭配的主流 ORM 框架均已原生支持
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

