在Java中截断持续时间

3
当将经过的时间捕获为 Duration 时,我只关心整秒。如何从 Duration 对象中删除小数秒?java.time 框架中的其他类提供了 truncatedTo 方法。但我在 Duration 中没有看到这个方法。

2
亲爱的投反对票者,请在您的投票中留下批评意见。 - Basil Bourque
2个回答

7

Java 9及以后版本

Java 9java.time类带来了一些小的功能和错误修复,这些类在Java 8中首次亮相。

其中之一是添加了Duration::truncatedTo方法,类似于其他类中看到的方法。传递一个ChronoUnitTemporalUnit接口的实现)以指定要截断的粒度。

Duration d = myDuration.truncatedTo( ChronoUnit.SECONDS ) ;

Java 8

如果您正在使用Java 8,但还不能升级到Java 9、10、11或更高版本,则需要自己计算截断。

调用Java 8版本的Duration上找到的minusNanos方法。获取Duration对象上的纳秒数,然后减去该纳秒数。

Duration d = myDuration.minusNanos( myDuration.getNano() ) ;

java.time类使用不可变对象模式。因此,您将获得一个全新的对象,而不会更改(“突变”)原始对象。


2

我喜欢你自己的回答。我知道这不是你要求的,但我想为Java 8提供一两个选项,以便在我们想截断到除秒以外的单位的情况下使用。

如果我们在编写代码时知道单位,我们可以结合toXxofXx方法来形成被截断的持续时间:

    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。我还没有考虑将其泛化的难度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接