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

如何将Joda-Time Period API迁移至java.time?寻求日期时间统一处理方案

Joda-Time Period 迁移至 java.time 的解决方案

Joda-Time 的 Period API 可同时处理日期(年、月、日)与时间(时、分、秒、毫秒),但 java.time 将该能力拆分为两个独立类:

  • Period:仅处理日期维度(年、月、日),基于日历规则动态计算(比如2月会按实际天数处理)
  • Duration:仅处理时间维度(时、分、秒、毫秒),基于固定毫秒数计算

单独使用任一 API 都会有局限,比如用 Duration 处理月份时会默认按30天计算,不符合实际日历规则。以下是可行的解决方案:

方案1:组合使用 Period + Duration

将原 Joda-Time Period 拆分为日期部分(用 Period)和时间部分(用 Duration),操作时依次应用两者,既保留日历维度的动态计算,又能正确处理时间部分。

示例代码:

// 原 Joda-Time 代码
// Period jodaPeriod = new Period(1, 2, 3, 4, 5, 6, 7, 8); // 1年2月3日4时5分6秒8毫秒
// LocalDateTime dt = LocalDateTime.now().plus(jodaPeriod);

// 迁移后的 java.time 代码
Period datePeriod = Period.of(1, 2, 3); // 1年2月3日
Duration timeDuration = Duration.ofHours(4)
        .plusMinutes(5)
        .plusSeconds(6)
        .plusMillis(8); // 4时5分6秒8毫秒

LocalDateTime dt = LocalDateTime.now();
dt = dt.plus(datePeriod).plus(timeDuration);

方案2:自定义组合类封装日期+时间

如果需要一个单一对象同时管理日期和时间维度,可以自定义实现 TemporalAdjuster 接口,内部封装 Period 和 Duration,统一对外提供操作入口。

示例代码:

public class CombinedPeriod implements TemporalAdjuster {
    private final Period datePeriod;
    private final Duration timeDuration;

    public CombinedPeriod(Period datePeriod, Duration timeDuration) {
        this.datePeriod = datePeriod;
        this.timeDuration = timeDuration;
    }

    @Override
    public Temporal adjustInto(Temporal temporal) {
        // 先调整日期,再调整时间
        return temporal.plus(datePeriod).plus(timeDuration);
    }

    // 静态工厂方法,简化实例创建
    public static CombinedPeriod of(int years, int months, int days, 
                                   long hours, long minutes, long seconds, long millis) {
        Period p = Period.of(years, months, days);
        Duration d = Duration.ofHours(hours)
                .plusMinutes(minutes)
                .plusSeconds(seconds)
                .plusMillis(millis);
        return new CombinedPeriod(p, d);
    }
}

使用方式:

CombinedPeriod combined = CombinedPeriod.of(1, 2, 3, 4, 5, 6, 8);
LocalDateTime dt = LocalDateTime.now().with(combined);

注意事项

  • 禁止用 Duration 处理年、月维度:Duration 基于固定毫秒数计算,无法适配不同月份的天数差异,必须用 Period 处理日期维度。
  • 自定义类需兼容不同 Temporal 类型:如果需要支持 LocalDate(仅日期)或 LocalTime(仅时间),可在 adjustInto 方法中添加类型判断,避免抛出异常。

内容的提问来源于stack exchange,提问作者Saurabh Sole

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:30:24