【发布时间】:2018-10-06 12:03:09
【问题描述】:
将经过时间捕获为Duration 时,我只关心整秒分辨率。
如何从Duration 对象中删除小数秒?
java.time 框架中的其他类提供了truncatedTo 方法。但我在Duration 上没有看到。
【问题讨论】:
-
亲爱的投票者,请在投票的同时留下批评意见。
标签: java truncate duration truncation
将经过时间捕获为Duration 时,我只关心整秒分辨率。
如何从Duration 对象中删除小数秒?
java.time 框架中的其他类提供了truncatedTo 方法。但我在Duration 上没有看到。
【问题讨论】:
标签: java truncate duration truncation
Java 9 为 Java 8 中首次亮相的 java.time 类带来了一些小功能和错误修复。
其中一个功能是添加Duration::truncatedTo 方法,类似于在其他类中看到的此类方法。传递一个ChronoUnit(TemporalUnit 接口的实现)来指定截断的粒度。
Duration d = myDuration.truncatedTo( ChronoUnit.SECONDS ) ;
如果您正在使用 Java 8 并且还不能迁移到 Java 9、10、11 或更高版本,请自行计算截断。
调用在 Java 8 版本的 Duration 上找到的 minusNanos 方法。获取Duration 对象的纳秒数,然后减去该纳秒数。
Duration d = myDuration.minusNanos( myDuration.getNano() ) ;
java.time 类使用immutable objects 模式。因此,您可以在不改变(“变异”)原始对象的情况下取回一个全新的对象。
【讨论】:
我喜欢your own answer。我知道这不是您问的问题,但我想为 Java 8 提供一两个选项,用于我们想要截断为秒以外的单位的情况。
如果我们在编写代码时知道单位,我们可以结合toXx 和ofXx 方法来形成截断的持续时间:
Duration d = Duration.ofMillis(myDuration.toMillis());
Duration d = Duration.ofSeconds(myDuration.toSeconds());
Duration d = Duration.ofMinutes(myDuration.toMinutes());
Duration d = Duration.ofHours(myDuration.toHours());
Duration d = Duration.ofDays(myDuration.toDays());
如果单位是可变的,我们可能会改编你提到的Java 9方法的实现代码truncatedTo:
Duration d;
if (unit.equals(ChronoUnit.SECONDS)
&& (myDuration.getSeconds() >= 0 || myDuration.getNano() == 0)) {
d = Duration.ofSeconds(myDuration.getSeconds());
} else if (unit == ChronoUnit.NANOS) {
d = myDuration;
}
Duration unitDur = unit.getDuration();
if (unitDur.getSeconds() > TimeUnit.DAYS.toSeconds(1)) {
throw new UnsupportedTemporalTypeException("Unit is too large to be used for truncation");
}
long dur = unitDur.toNanos();
if ((TimeUnit.DAYS.toNanos(1) % dur) != 0) {
throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
}
long nod = (myDuration.getSeconds() % TimeUnit.DAYS.toSeconds(1)) * TimeUnit.SECONDS.toNanos(1)
+ myDuration.getNano();
long result = (nod / dur) * dur;
d = myDuration.plusNanos(result - nod);
原始方法使用了Duration 类中的一些私有内容,因此需要进行一些更改。该代码仅接受ChronoUnit 单位,而不接受其他TemporalUnits。我没有考虑过推广它有多难。
【讨论】: