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

无法使用dividedBy(long)时java.time.Duration带余数除法实现方案

Duration除法精确实现方案

完全符合你的限制要求:无需调用受限的Duration#dividedBy(long)方法、不会丢弃精度、也不需要将Duration转换为毫秒等单序数值。
核心思路是直接操作Duration原生存储的两个字段:秒部分(long)和纳秒部分(int,范围0~999999999),分别做除法运算后重新组装结果,全程精度无损。

场景1:Duration除以long,返回精确Duration结果

实现代码如下:

public static Duration divideByLong(Duration dividend, long divisor) {
    if (divisor == 0) {
        throw new ArithmeticException("除数不能为0");
    }
    // 计算秒部分的商和余数
    long secQuotient = dividend.getSeconds() / divisor;
    long secRemainder = dividend.getSeconds() % divisor;
    // 剩余秒转换为纳秒,叠加原有纳秒部分后计算纳秒商
    long totalNano = secRemainder * 1_000_000_000L + dividend.getNano();
    long nanoQuotient = totalNano / divisor;
    // 组装结果,无需处理纳秒进位,总纳秒小于divisor*1e9,商必然小于1e9
    return Duration.ofSeconds(secQuotient, nanoQuotient);
}

测试验证:
divideByLong(Duration.ofHours(1), 7L)返回结果为PT8M34.285714285S,和预期结果完全一致。

场景2:两个Duration相除,返回带余数的精确结果

可以自定义结果类同时返回整数商和余数Duration,也可以按需计算浮点商:

// 自定义除法结果类
public class DurationDivideResult {
    // 整数商
    private final long quotient;
    // 余数部分
    private final Duration remainder;

    public DurationDivideResult(long quotient, Duration remainder) {
        this.quotient = quotient;
        this.remainder = remainder;
    }

    public long getQuotient() {
        return quotient;
    }

    public Duration getRemainder() {
        return remainder;
    }

    // 按需获取精确浮点商
    public BigDecimal getDecimalQuotient(Duration divisor) {
        BigDecimal divisorTotal = BigDecimal.valueOf(divisor.getSeconds())
                .multiply(BigDecimal.valueOf(1_000_000_000L))
                .add(BigDecimal.valueOf(divisor.getNano()));
        BigDecimal remainderTotal = BigDecimal.valueOf(remainder.getSeconds())
                .multiply(BigDecimal.valueOf(1_000_000_000L))
                .add(BigDecimal.valueOf(remainder.getNano()));
        return BigDecimal.valueOf(quotient)
                .add(remainderTotal.divide(divisorTotal, 9, RoundingMode.HALF_UP));
    }
}

// 除法实现方法
public static DurationDivideResult divideByDuration(Duration dividend, Duration divisor) {
    if (divisor.isZero()) {
        throw new ArithmeticException("除数不能为0");
    }
    // 先计算最大整数商
    long quotient = 0;
    Duration temp = Duration.ZERO;
    while (temp.plus(divisor).compareTo(dividend) <= 0) {
        temp = temp.plus(divisor);
        quotient++;
    }
    Duration remainder = dividend.minus(temp);
    return new DurationDivideResult(quotient, remainder);
}

测试验证:
divideByDuration(Duration.ofHours(1), Duration.ofSeconds(7))返回的整数商为514,余数为PT2S,完全保留精度没有丢失。

提示:如果需要处理超大时长的除法场景,可将上述循环改为二分法计算最大整数商,性能会有明显提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:18:03