将org.joda.time迁移至java.time:Duration.getSeconds转int的更佳方法
从Joda-Time迁移到java.time:将Duration秒数转为int的最优方法
问题背景
原基于Joda-Time的代码:
private int calculate(OffsetDateTime expirationDate) { return Seconds.secondsBetween(DateTime.now(), expirationDate).getSeconds(); }
迁移到java.time后的代码:
private int calculate(OffsetDateTime expirationDate) { return Duration.between(OffsetDateTime.now(), expirationDate).getSeconds(); }
这里的核心问题是:java.time中Duration.getSeconds()返回long类型,而我们需要保持方法返回int类型,以下是几种可行的转换方案:
1. 直接强制转换(适合明确秒数范围的场景)
如果能确定业务中过期时间与当前时间的秒差不会超出int的取值区间(-2147483648到2147483647秒,约±68年),可以直接强转,和原Joda-Time逻辑完全对齐:
private int calculate(OffsetDateTime expirationDate) { return (int) Duration.between(OffsetDateTime.now(), expirationDate).getSeconds(); }
注意:如果实际秒数超出范围,强转会导致静默溢出,产生错误结果。
2. 安全转换+溢出处理(通用安全方案)
若无法确定秒数范围,建议先判断值是否在int区间内,再转换,溢出时抛出异常或返回预设默认值:
private int calculate(OffsetDateTime expirationDate) { long totalSeconds = Duration.between(OffsetDateTime.now(), expirationDate).getSeconds(); if (totalSeconds < Integer.MIN_VALUE || totalSeconds > Integer.MAX_VALUE) { throw new IllegalArgumentException("计算的秒数超出int类型范围: " + totalSeconds); // 也可根据业务需求返回默认值,例如: // return Integer.MAX_VALUE; } return (int) totalSeconds; }
这种方式能提前发现溢出风险,避免隐性bug。
3. 注意避坑:别用toSecondsPart()
不要混淆getSeconds()和toSecondsPart():toSecondsPart()返回的是Duration中不足1分钟的秒数部分(取值0-59),并非总秒数,完全不适合替代getSeconds()的作用。
额外说明
原Joda-Time的Seconds.secondsBetween().getSeconds()本身返回int,说明原逻辑默认秒差在int范围内。迁移时优先评估业务场景:
- 若过期时间跨度不会超过±68年,直接强转即可;
- 若存在超长跨度的可能,必须添加溢出处理。
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

