Java Duration Class

The Duration class is an important class in the date-time API (java.time package) introduced in Java 8, used to represent time intervals or durations.

The Duration class is mainly used to calculate the difference between two time points, or to represent a specific length of time.


Basic Concepts

The time interval represented by the Duration class can be accurate to the nanosecond level. It is mainly used to handle time-based quantities (hours, minutes, seconds, and nanoseconds), without involving the concepts of dates or time zones.

Main Features:

  1. Immutability - Once a Duration object is created, it cannot be modified
  2. Thread Safety - Can be safely used in multi-threaded environments
  3. High Precision - Can be accurate to the nanosecond level
  4. Chained Calls - Supports method chaining

Creating Duration Objects

The Duration class provides multiple static methods to create Duration instances:

1. Creating via Time Units

Example

// Create a Duration lasting 2 hours
Duration twoHours = Duration.ofHours(2);

// Create a Duration lasting 30 minutes
Duration thirtyMinutes = Duration.ofMinutes(30);

// Create a Duration lasting 45 seconds
Duration fortyFiveSeconds = Duration.ofSeconds(45);

// Create a Duration lasting 500 milliseconds
Duration fiveHundredMillis = Duration.ofMillis(500);

// Create a Duration lasting 1,000,000 nanoseconds
Duration oneMillionNanos = Duration.ofNanos(1_000_000);

2. Creating via Time Amount

Example

// Create a Duration lasting 1 day, 2 hours, and 3 minutes
Duration customDuration = Duration.ofDays(1).plusHours(2).plusMinutes(3);

3. Calculating via Two Time Points

Example

Instant start = Instant.now();
// Perform some operations...
Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);

4. Creating by Parsing a String

Example

// Create from an ISO-8601 format string
Duration parsedDuration = Duration.parse("PT2H30M15S"); // 2 hours, 30 minutes, 15 seconds

Common Methods

The Duration class provides rich methods to handle time intervals:

1. Getting Time Values

Example

Duration duration = Duration.ofHours(2).plusMinutes(30);

long hours = duration.toHours();      // 2
long minutes = duration.toMinutes();  // 150
long seconds = duration.getSeconds(); // 9000
int nanos = duration.getNano();      // 0

2. Time Operations

Example

Duration d1 = Duration.ofHours(2);
Duration d2 = Duration.ofMinutes(30);

// Addition
Duration sum = d1.plus(d2);  // 2 hours 30 minutes

// Subtraction
Duration diff = d1.minus(d2); // 1 hour 30 minutes

// Multiplication
Duration multiplied = d1.multipliedBy(3); // 6 hours

// Division
Duration divided = d1.dividedBy(2); // 1 hour

3. Comparison Operations

Example

Duration d1 = Duration.ofHours(1);
Duration d2 = Duration.ofMinutes(90);

boolean isEqual = d1.equals(d2);      // false
int comparison = d1.compareTo(d2);    // -1 (d1 < d2)
boolean isNegative = d1.isNegative(); // false
boolean isZero = d1.isZero();         // false

4. Other Practical Methods

Example

Duration duration = Duration.ofMinutes(90);

// Convert to other units
long hours = duration.toHours();      // 1
long minutes = duration.toMinutes();  // 90
long seconds = duration.toSeconds();  // 5400
long millis = duration.toMillis();    // 5400000
long nanos = duration.toNanos();      // 5400000000000

// Get each part
long secondsPart = duration.getSeconds(); // 5400
int nanoPart = duration.getNano();       // 0

// Get absolute value
Duration absDuration = duration.abs();

// Get negative value
Duration negated = duration.negated();

Practical Application Examples

Example 1: Calculating Code Execution Time

Example

Instant start = Instant.now();

// Simulate a time-consuming operation
try {
    Thread.sleep(1500);
} catch (InterruptedException e) {
    e.printStackTrace();
}

Instant end = Instant.now();
Duration elapsed = Duration.between(start, end);

System.out.println("Code execution time: " + elapsed.toMillis() + " milliseconds");

Example 2: Time Format Conversion

Example

Duration duration = Duration.ofMinutes(135);

// Convert to "HH:MM:SS" format
long hours = duration.toHours();
long minutes = duration.minusHours(hours).toMinutes();
long seconds = duration.minusHours(hours).minusMinutes(minutes).getSeconds();

String formatted = String.format("%02d:%02d:%02d", hours, minutes, seconds);
System.out.println(formatted); // Output: 02:15:00

Example 3: Timeout Control

Example

Duration timeout = Duration.ofSeconds(30);
Instant startTime = Instant.now();

while (true) {
    // Check if timeout occurred
    if (Duration.between(startTime, Instant.now()).compareTo(timeout) > 0) {
        System.out.println("Operation timed out");
        break;
    }
   
    // Perform other operations...
}

Example

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

public class DurationDemo {
    public static void main(String[] args) {
        // Several ways to create Duration objects
       
        // 1. Use the of...() method
        Duration duration1 = Duration.ofHours(2); // 2 hours
        Duration duration2 = Duration.ofMinutes(90); // 90 minutes
        System.out.println("Duration 1: " + duration1);
        System.out.println("Duration 2: " + duration2);
       
        // 2. Use the between() method to calculate the duration between two time points
        LocalTime startTime = LocalTime.of(9, 0);
        LocalTime endTime = LocalTime.of(11, 30);
        Duration duration3 = Duration.between(startTime, endTime);
        System.out.println("Duration between times: " + duration3);
       
        // 3. Use the parse() method to create from a string
        Duration duration4 = Duration.parse("PT2H30M"); // ISO-8601 format
        System.out.println("Parsed Duration: " + duration4);
       
        // 4. Use Instant to calculate the time difference
        Instant startInstant = Instant.now();
        // Simulate a time-consuming operation
        try { Thread.sleep(1500); } catch (InterruptedException e) {}
        Instant endInstant = Instant.now();
        Duration duration5 = Duration.between(startInstant, endInstant);
        System.out.println("Execution duration: " + duration5.toMillis() + "ms");
    }
}

The output result is:

Duration 1: PT2H
Duration 2: PT1H30M
Duration between times: PT2H30M
Parsed Duration: PT2H30M
Execution duration: 1501ms

Notes

  1. Precision Issue: The Duration can be accurate to the nanosecond level, but the actual precision depends on the support of the operating system and hardware.

  2. Difference from Period:

    • Duration is used to measure time-based hours, minutes, seconds, and nanoseconds
    • Period is used to measure date-based years, months, and days
  3. Immutability: All Duration objects are immutable; any modification operation returns a new Duration instance.

  4. Negative Value Handling: Duration can represent negative time intervals, which may be encountered when calculating time differences.

  5. String Format: Uses the ISO-8601 duration formatPnDTnHnMn.nS, where:

    • P is the duration designator
    • D is the number of days
    • T is the separator for the time part
    • H is the number of hours
    • M is the number of minutes
    • S is the number of seconds (can have a fractional part)

Summary

Java's Duration class provides powerful and flexible tools for handling time intervals. By mastering the use of the Duration class, developers can more easily handle various time-calculation-related requirements, such as performance measurement, timeout control, task scheduling, etc. Used together with other date-time classes introduced in Java 8 (such as Instant, LocalDateTime, etc.), the Duration class can build more robust and readable time-handling code.

Other Extensions