You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17迁移:OffsetDateTime无withZone及print适配问题求助

Joda Time 迁移至 Java 17 OffsetDateTime 问题解决方案

问题分析

你遇到的两个错误本质是Joda Time 与 Java 标准库时间类不兼容导致的:

  1. OffsetDateTime 是 Java 标准库类型,没有 Joda DateTime 的 withZone 方法
  2. 你仍在使用 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:50:21