在Java中截断持续时间

时间:2018-04-25 22:02:28

标签: java truncate duration truncation

当将经过的时间捕获为Duration时,我只关心整秒的分辨率。

如何从Duration对象中删除小数秒?

java.time 框架中的其他类提供truncatedTo方法。但我在Duration上没有看到一个。

2 个答案:

答案 0 :(得分:3)

Java 9及更高版本

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

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

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

Java 8

如果您正在使用Java 8但尚未转移到Java 9,10,11或更高版本,请自行计算截断。

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

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

java.time 类使用Duration模式。所以你得到一个新的新对象而不改变(“改变”)原始对象。

答案 1 :(得分:2)

我喜欢your own answer。我知道这不是你提出的问题,但是我想为我们想要截断到秒以外的单位的情况提供一个或两个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个单位。我没想到要概括它有多难。