在将经过的时间捕获为Duration
时,我只关心整个秒的分辨率。
如何从Duration
对象中删除分数秒?
java.time 框架中的其他类提供truncatedTo
方法。但是我在Duration
上看不到一个。
Java 9及以后
java 9带来了一些较小的功能和错误修复到 java.Time 类,该类别在Java 8中首次亮相。
这些功能之一是添加Duration::truncatedTo
方法,类似于其他类别上的此类方法。通过ChronoUnit
(TemporalUnit
接口的实现(以指定要截断的粒度。
Duration d = myDuration.truncatedTo( ChronoUnit.SECONDS ) ;
Java 8
如果您使用的是Java 8,并且无法移至Java 9、10、11或更高版本,请自己计算截断。
调用Duration
Java 8版本上的minusNanos
方法。在Duration
对象上获取纳秒数的数量,然后减去该纳秒数的数量。
Duration d = myDuration.minusNanos( myDuration.getNano() ) ;
java.Time 类使用不变的对象模式。因此,您可以在不更改("突变"(原件的情况下获得一个新的新对象。
我喜欢你自己的答案。我知道这不是您要求的,但我想在我们想截断为秒以外的单位的情况下为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
单位,而不是其他TemporalUnit
s。我没有考虑过将其推广到多么困难。