ZetCode

Java Duration 类

最后修改时间:2025 年 4 月 16 日

java.time.Duration 类表示以秒和纳秒为单位的基于时间的时长。它以秒和纳秒为单位对时间的量或数量进行建模。 Duration 用于测量两个时刻之间经过的时间。

Duration 是不可变的且线程安全的。它常用于测量时间间隔,从时间对象中添加/减去时间,以及计算时间对象之间的差异。 Duration 使用机器时间而不是基于日历的时间。

Duration 类概述

Duration 提供了创建持续时间、执行计算以及在不同单位之间转换的方法。关键操作包括添加到时间对象、比较持续时间以及提取组件。该类以秒和纳秒为单位处理时间。

public final class Duration implements TemporalAmount, Comparable<Duration>, 
    Serializable {
    public static Duration ofDays(long days);
    public static Duration ofHours(long hours);
    public static Duration ofMinutes(long minutes);
    public static Duration ofSeconds(long seconds);
    public static Duration ofMillis(long millis);
    public static Duration ofNanos(long nanos);
    public static Duration between(Temporal startInclusive, Temporal endExclusive);
    public long getSeconds();
    public int getNano();
    public Duration plus(Duration duration);
    public Duration minus(Duration duration);
    public Duration multipliedBy(long multiplicand);
    public Duration dividedBy(long divisor);
    public long toDays();
    public long toHours();
    public long toMinutes();
    public long toMillis();
    public long toNanos();
}

上面的代码展示了 Duration 提供的主要方法。这些方法允许创建、比较和操作持续时间。该类提供高达纳秒的精度,同时支持转换为各种时间单位。

创建 Duration 对象

可以使用特定时间单位的工厂方法或通过计算时间对象之间的差异来创建 Duration 对象。该类支持从天到纳秒创建持续时间。

Main.java
package com.zetcode; 

import java.time.Duration;
import java.time.Instant;
import java.time.LocalTime;

public class Main {

    public static void main(String[] args) {
        
        // Create from hours
        Duration hours = Duration.ofHours(2);
        System.out.println("2 hours: " + hours);
        
        // Create from minutes
        Duration minutes = Duration.ofMinutes(30);
        System.out.println("30 minutes: " + minutes);
        
        // Create from seconds and nanos
        Duration seconds = Duration.ofSeconds(45, 500_000_000);
        System.out.println("45.5 seconds: " + seconds);
        
        // Create from between two temporals
        Instant start = Instant.now();
        Instant end = start.plusSeconds(60);
        Duration between = Duration.between(start, end);
        System.out.println("Between instants: " + between);
        
        // From LocalTime
        Duration timeDiff = Duration.between(
            LocalTime.of(9, 0), 
            LocalTime.of(17, 30)
        );
        System.out.println("Workday duration: " + timeDiff);
    }
}

此示例演示了创建 Duration 对象的不同方法。输出显示以 ISO-8601 持续时间格式 (PTnHnMnS) 显示的持续时间。请注意,从之间操作创建的持续时间是时间对象的精确差异。

获取 Duration 组件

Duration 可以分解为其秒和纳秒组件,或转换为各种时间单位。这些方法对于与其他 API 的互操作性或以特定单位显示持续时间非常有用。

Main.java
package com.zetcode; 

import java.time.Duration;

public class Main {

    public static void main(String[] args) {

        Duration duration = Duration.ofHours(2).plusMinutes(30).plusSeconds(15);
        
        // Get seconds and nanos
        long seconds = duration.getSeconds();
        int nanos = duration.getNano();
        System.out.println("Seconds: " + seconds);
        System.out.println("Nanoseconds: " + nanos);
        
        // Convert to various units
        System.out.println("To days: " + duration.toDays());
        System.out.println("To hours: " + duration.toHours());
        System.out.println("To minutes: " + duration.toMinutes());
        System.out.println("To milliseconds: " + duration.toMillis());
        System.out.println("To nanoseconds: " + duration.toNanos());
    }
}

此示例展示了如何从 Duration 中提取组件。请注意,诸如 toHours 之类的转换方法会以该单位返回总持续时间,可能会损失精度。秒和纳秒一起提供了完整的精度。

Duration 算术运算

Duration 支持算术运算,例如加法、减法、乘法和除法。这些操作对于修改持续时间同时保持精度非常有用。所有操作都返回新的 Duration 对象。

Main.java
package com.zetcode; 

import java.time.Duration;

public class Main {

    public static void main(String[] args) {

        Duration duration1 = Duration.ofHours(2);
        Duration duration2 = Duration.ofMinutes(30);
        
        // Addition
        Duration sum = duration1.plus(duration2);
        System.out.println("Sum: " + sum);
        
        // Subtraction
        Duration diff = duration1.minus(duration2);
        System.out.println("Difference: " + diff);
        
        // Multiplication
        Duration multiplied = duration1.multipliedBy(3);
        System.out.println("Multiplied by 3: " + multiplied);
        
        // Division
        Duration divided = duration1.dividedBy(2);
        System.out.println("Divided by 2: " + divided);
        
        // Negation
        Duration negated = duration1.negated();
        System.out.println("Negated: " + negated);
    }
}

此示例演示了使用 Duration 对象的各种算术运算。所有操作都保持纳秒精度并自动处理溢出/下溢。请注意,由于该类是不可变的,因此操作将返回新的 Duration 实例。

比较 Duration

可以比较持续时间以确定哪个更长或它们是否相等。该类提供了 compareToequalsisZero 方法。这些比较对于应用程序中基于时间的逻辑至关重要。

Main.java
package com.zetcode; 

import java.time.Duration;

public class Main {

    public static void main(String[] args) {

        Duration shortDur = Duration.ofMinutes(15);
        Duration mediumDur = Duration.ofHours(1);
        Duration longDur = Duration.ofHours(2);
        
        // Comparison
        System.out.println("short < medium: " + 
            (shortDur.compareTo(mediumDur) < 0));
        System.out.println("medium == 1 hour: " + 
            mediumDur.equals(Duration.ofHours(1)));
        System.out.println("long > medium: " + 
            (longDur.compareTo(mediumDur) > 0));
        
        // Zero check
        System.out.println("Is zero: " + Duration.ZERO.isZero());
        
        // Negative duration
        Duration negative = Duration.ofHours(-1);
        System.out.println("Is negative: " + (negative.getSeconds() < 0));
    }
}

此示例演示了比较 Duration 对象的各种方法。比较方法同时考虑了秒和纳秒组件。请注意,相等性需要两个组件完全匹配,而比较则考虑总持续时间。

将 Duration 与时间对象一起使用

Duration 可以添加到或从时间对象(如 Instant 或 LocalDateTime)中减去。这对于计算相对于给定时间对象的未来或过去的时间点非常有用。

Main.java
package com.zetcode; 

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class Main {

    public static void main(String[] args) {

        Instant now = Instant.now();
        Duration twoHours = Duration.ofHours(2);
        
        // Add to Instant
        Instant future = now.plus(twoHours);
        System.out.println("Now plus 2 hours: " + future);
        
        // Subtract from Instant
        Instant past = now.minus(twoHours);
        System.out.println("Now minus 2 hours: " + past);
        
        // With LocalDateTime
        LocalDateTime ldt = LocalDateTime.now();
        LocalDateTime ldtFuture = ldt.plus(twoHours);
        System.out.println("LocalDateTime plus 2 hours: " + ldtFuture);
        
        // Convert between time zones
        Instant utc = Instant.now();
        Instant est = utc.atZone(ZoneId.of("America/New_York")).toInstant();
        Duration zoneDiff = Duration.between(utc, est);
        System.out.println("UTC to EST difference: " + zoneDiff);
    }
}

此示例展示了如何将 Duration 与各种时间对象一起使用。操作会保持精度并在需要时处理时区转换。请注意,Duration 表示确切的时间量,不受时区或夏令时的影响。

格式化和解析 Duration

Duration 可以使用 ISO-8601 格式转换为字符串和从字符串转换。 toString 方法生成字符串表示形式,而 parse 从字符串创建 Duration。

Main.java
package com.zetcode; 

import java.time.Duration;

public class Main {

    public static void main(String[] args) {

        // Formatting to string
        Duration duration = Duration.ofHours(2).plusMinutes(30).plusSeconds(15);
        String durationStr = duration.toString();
        System.out.println("Formatted: " + durationStr);
        
        // Parsing from string
        Duration parsed = Duration.parse("PT1H30M15S");
        System.out.println("Parsed: " + parsed);
        System.out.println("Hours in parsed: " + parsed.toHours());
        
        // Edge cases
        Duration zero = Duration.parse("PT0S");
        System.out.println("Zero duration: " + zero);
        
        Duration large = Duration.parse("P2DT3H4M");
        System.out.println("Large duration: " + large);
    }
}

此示例演示了 Duration 对象的格式化和解析。 ISO-8601 格式使用 'P' 表示周期,'T' 表示时间,字母表示单位 (H=小时, M=分钟, S=秒)。请注意,解析是严格的,需要正确的格式。

来源

Java Duration 类文档

在本文中,我们介绍了 Java Duration 类的基本方法和特性。理解这些概念对于在现代 Java 应用程序中准确处理时间间隔至关重要。

作者

我的名字是 Jan Bodnar,我是一位经验丰富的程序员,在该领域拥有多年经验。我于 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和八本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助其他人掌握编程概念。

列出所有Java教程