Back to Blog
Java

Java Duration: Measuring Time Intervals

java duration: Learn how to use java.time.Duration to represent and manipulate time-based amounts in Java, including parsing, formatting, and conversion.

java.timeDurationtime measurementJava 8date-time API
A clock and a stopwatch representing java.time.Duration for measuring time intervals in Java applications.

When working with time in Java, you often need to represent a span of time, not a specific point. The java.time.Duration class, introduced in Java 8, models a time-based amount of seconds and nanoseconds. This article explains how to use java duration for measuring and manipulating time intervals.

Creating Duration Instances

Duration provides static factory methods for common time units. The simplest way is to use ofSeconds, ofMinutes, ofHours, or ofDays:

Duration fiveMinutes = Duration.ofMinutes(5); Duration twoHours = Duration.ofHours(2); Duration oneDay = Duration.ofDays(1);

For finer granularity, use ofMillis or ofNanos:

Duration halfSecond = Duration.ofMillis(500); Duration tenNanos = Duration.ofNanos(10);

You can also create a Duration from two Instant values using Duration.between. This is useful when measuring how long an operation took:

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

Duration.between returns a positive value if the second instant is after the first, and a negative value otherwise. The result captures both seconds and nanoseconds, so sub-millisecond precision is preserved.

Parsing ISO-8601 Duration Strings

Duration implements parse, which accepts the ISO-8601 duration format. The format begins with PT (period of time) followed by hours, minutes, and seconds. For example, PT1H30M represents 1 hour and 30 minutes. The parse method is strict: it rejects strings that omit the PT prefix or use unsupported units like days or months.

Duration parsed = Duration.parse("PT1H30M"); System.out.println(parsed.toMinutes()); // 90

You can also parse negative durations, such as -PT5M. The toString method produces the same ISO-8601 format, which is useful for logging or storing durations in a database.

Accessing Duration Components

A Duration stores seconds and nanoseconds. The getSeconds method returns the total seconds, and getNano returns the nanosecond adjustment within the current second. For convenience, Duration provides conversion methods that return the whole number of a given unit, truncating any remainder:

Duration duration = Duration.ofSeconds(90, 500_000_000); // 90.5 seconds long wholeMinutes = duration.toMinutes(); // 1 (truncated) long wholeSeconds = duration.toSeconds(); // 90 (truncated) long wholeMillis = duration.toMillis(); // 90500 (truncated)

Be aware that toHours, toMinutes, and toSeconds truncate toward zero. If you need the exact value with fractional parts, you must compute it manually from getSeconds and getNano. For example, to get the total number of minutes as a double:

double totalMinutes = duration.getSeconds() / 60.0 + duration.getNano() / 60_000_000_000.0;

Arithmetic Operations on Durations

Duration is immutable, so all arithmetic methods return a new instance. You can add or subtract durations, multiply or divide by a scalar, and negate or take the absolute value:

Duration base = Duration.ofMinutes(10); Duration added = base.plus(Duration.ofMinutes(5)); // 15 minutes Duration subtracted = base.minus(Duration.ofSeconds(30)); // 9 minutes 30 seconds Duration doubled = base.multipliedBy(2); // 20 minutes Duration halved = base.dividedBy(4); // 2 minutes 30 seconds Duration negated = base.negated(); // -10 minutes Duration absolute = negated.abs(); // 10 minutes

The plus and minus methods also accept a long amount and a TemporalUnit, such as ChronoUnit.SECONDS. However, the Duration-based overloads are usually clearer and avoid unit conversion mistakes.

Comparing Durations

To compare two durations, use compareTo, which returns a negative, zero, or positive value. The equals method checks for exact equality of seconds and nanoseconds. isZero and isNegative are convenience predicates:

Duration a = Duration.ofSeconds(10); Duration b = Duration.ofSeconds(20); boolean isAfter = a.compareTo(b) > 0; // false boolean isSame = a.equals(Duration.ofSeconds(10)); // true boolean isNegative = a.isNegative(); // false

These methods are useful in validation logic, such as checking that a timeout is positive before scheduling a task.

Converting Between Duration and Other Time Units

Duration can be converted to a long value in a specific unit using toMillis, toNanos, toDays, and similar methods. These conversions truncate toward zero, so they may lose precision. For example, converting a duration of 1.5 seconds to milliseconds yields 1500, but converting to seconds yields 1, losing the fractional part.

MethodReturnsPrecision Loss
toDays()Whole daysSub-day part truncated
toHours()Whole hoursSub-hour part truncated
toMinutes()Whole minutesSub-minute part truncated
toSeconds()Whole secondsSub-second part truncated
toMillis()Whole millisecondsSub-millisecond truncated
toNanos()Whole nanosecondsNone, but may overflow

When you need to pass a duration to an API that expects milliseconds, such as Thread.sleep or an HTTP client timeout, use toMillis(). Be mindful that toNanos() can overflow for durations longer than about 292 years, because it stores nanoseconds in a long. In such cases, toMillis() is safer.

Common Pitfalls and Production Considerations

Duration is immutable and thread-safe, so it can be shared across threads without synchronization. However, creating a new Duration for every operation in a hot loop adds allocation overhead. If you frequently need the same constant duration, define it as a static final field:

private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(30);

Another common mistake is using Duration for calendar-based periods like months or years. Duration assumes a fixed 24-hour day, so it cannot represent "one month" accurately. For that, use java.time.Period, which works with dates.

When parsing user-supplied duration strings, always handle DateTimeParseException. A malformed string like "10 minutes" will throw, and you should decide whether to reject it or fall back to a default.

Finally, be careful with negative durations. Some APIs, such as Thread.sleep, reject negative values. Check isNegative() before passing a duration to such methods, or use abs() if a negative value is not meaningful in your context.

Choosing Between Duration, Period, and Instant

Duration measures time-based amounts in seconds and nanoseconds. Period measures date-based amounts in years, months, and days. Instant represents a point on the timeline. The decision depends on what you need:

  • Use Duration for elapsed time, timeouts, and intervals that are independent of the calendar.
  • Use Period for age, scheduling on a calendar, or any span that must respect months and years.
  • Use Instant for timestamps, not for measuring a length of time.

A common pattern is to capture Instant values before and after an operation and then compute a Duration with between. This gives you a precise, immutable result that you can log or compare against a threshold.

java duration: Practical Usage and Code Examples | RYUSLOG DEV