【问题标题】:Truncate a Duration in Java在 Java 中截断持续时间
【发布时间】:2018-10-06 12:03:09
【问题描述】:

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

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

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

【问题讨论】:

  • 亲爱的投票者,请在投票的同时留下批评意见。

标签: java truncate duration truncation


【解决方案1】:

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 或更高版本,请自行计算截断。

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

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

java.time 类使用immutable objects 模式。因此,您可以在不改变(“变异”)原始对象的情况下取回一个全新的对象。

【讨论】:

    【解决方案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 单位,而不接受其他TemporalUnits。我没有考虑过推广它有多难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2019-06-23
      • 2012-12-12
      • 2011-04-09
      • 2014-01-16
      • 2020-02-10
      相关资源
      最近更新 更多