Java TemporalAmount Interface
Last modified: April 16, 2025
The java.time.temporal.TemporalAmount
interface represents an amount
of time. It can be used to define quantities like "2 hours" or "5 days". This
interface is implemented by classes like Duration and Period.
TemporalAmount
provides methods to add or subtract time amounts from
temporal objects. It works with both date-based and time-based amounts. The
interface is part of Java's modern date-time API introduced in Java 8.
TemporalAmount Interface Overview
The TemporalAmount
interface defines methods for time manipulation.
Key implementations are Duration (time-based) and Period (date-based). The
interface enables flexible time calculations across different temporal types.
public interface TemporalAmount { long get(TemporalUnit unit); List<TemporalUnit> getUnits(); Temporal addTo(Temporal temporal); Temporal subtractFrom(Temporal temporal); }
The code above shows the methods defined by TemporalAmount
. These
methods allow querying units, getting values, and performing temporal arithmetic.
Implementations must handle unit conversions and boundary conditions.
Using Duration with TemporalAmount
Duration is a time-based implementation of TemporalAmount. It represents an amount of time in seconds and nanoseconds. Duration is ideal for precise time measurements.
package com.zetcode; import java.time.Duration; import java.time.LocalTime; public class Main { public static void main(String[] args) { Duration duration = Duration.ofHours(2).plusMinutes(30); // Get units System.out.println("Units: " + duration.getUnits()); // Get value in seconds System.out.println("Seconds: " + duration.getSeconds()); // Add to temporal object LocalTime time = LocalTime.of(10, 0); LocalTime newTime = (LocalTime) duration.addTo(time); System.out.println("New time: " + newTime); // Subtract from temporal object LocalTime earlierTime = (LocalTime) duration.subtractFrom(time); System.out.println("Earlier time: " + earlierTime); } }
This example demonstrates using Duration as a TemporalAmount. We create a duration of 2.5 hours, then add and subtract it from a LocalTime. The getUnits() method shows which time units the duration contains.
Using Period with TemporalAmount
Period is a date-based implementation of TemporalAmount. It represents an amount of time in years, months, and days. Period is useful for calendar-based date calculations.
package com.zetcode; import java.time.LocalDate; import java.time.Period; public class Main { public static void main(String[] args) { Period period = Period.ofYears(1).plusMonths(2).plusDays(3); // Get units System.out.println("Units: " + period.getUnits()); // Get values System.out.println("Years: " + period.getYears()); System.out.println("Months: " + period.getMonths()); System.out.println("Days: " + period.getDays()); // Add to temporal object LocalDate date = LocalDate.of(2025, 1, 1); LocalDate newDate = (LocalDate) period.addTo(date); System.out.println("New date: " + newDate); } }
This example shows Period being used as a TemporalAmount. We create a period of 1 year, 2 months, and 3 days, then add it to a LocalDate. Period handles calendar-aware date arithmetic automatically.
Custom TemporalAmount Implementation
We can create custom implementations of TemporalAmount for specialized time calculations. This example shows a simple implementation representing business days only.
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalUnit; import java.util.Collections; import java.util.List; public class Main { static class BusinessDays implements TemporalAmount { private final long days; public BusinessDays(long days) { this.days = days; } @Override public Temporal addTo(Temporal temporal) { LocalDate date = LocalDate.from(temporal); long added = 0; while (added < days) { date = date.plus(1, ChronoUnit.DAYS); if (date.getDayOfWeek().getValue() < 6) { added++; } } return temporal.with(date); } @Override public Temporal subtractFrom(Temporal temporal) { return addTo(temporal).minus(days * 2, ChronoUnit.DAYS); } @Override public long get(TemporalUnit unit) { if (unit == ChronoUnit.DAYS) { return days; } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } @Override public ListgetUnits() { return Collections.singletonList(ChronoUnit.DAYS); } } public static void main(String[] args) { BusinessDays businessDays = new BusinessDays(5); LocalDate startDate = LocalDate.of(2025, 4, 1); // Tuesday LocalDate endDate = (LocalDate) businessDays.addTo(startDate); System.out.println("Start date: " + startDate); System.out.println("End date (5 business days later): " + endDate); } }
This example demonstrates a custom TemporalAmount that skips weekends. The BusinessDays class adds only weekdays when performing date arithmetic. This shows how to create specialized time calculations for business applications.
Combining TemporalAmount Implementations
We can combine different TemporalAmount implementations for complex time calculations. This example mixes Period and Duration for a complete time span.
package com.zetcode; import java.time.Duration; import java.time.LocalDateTime; import java.time.Period; import java.time.temporal.TemporalAmount; public class Main { public static void main(String[] args) { // Date-based amount Period period = Period.of(1, 2, 3); // 1 year, 2 months, 3 days // Time-based amount Duration duration = Duration.ofHours(4).plusMinutes(30); LocalDateTime dateTime = LocalDateTime.of(2025, 1, 1, 10, 0); System.out.println("Original: " + dateTime); // Apply period first (date-based) LocalDateTime afterPeriod = (LocalDateTime) period.addTo(dateTime); System.out.println("After period: " + afterPeriod); // Then apply duration (time-based) LocalDateTime afterBoth = (LocalDateTime) duration.addTo(afterPeriod); System.out.println("After both: " + afterBoth); // Combined operation LocalDateTime combined = dateTime .plus(period) .plus(duration); System.out.println("Combined result: " + combined); } }
This example shows how to combine Period and Duration operations. We first add a period (date-based) then a duration (time-based) to a LocalDateTime. The result demonstrates complex temporal arithmetic using multiple TemporalAmounts.
Querying TemporalAmount Values
The TemporalAmount interface provides methods to query its component values. This example shows how to examine the units and values of different amounts.
package com.zetcode; import java.time.Duration; import java.time.Period; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalUnit; public class Main { public static void main(String[] args) { TemporalAmount[] amounts = { Period.of(1, 2, 3), Duration.ofHours(2).plusMinutes(30), Duration.ofDays(1).plusHours(6) }; for (TemporalAmount amount : amounts) { System.out.println("\nAmount: " + amount); System.out.println("Units: " + amount.getUnits()); for (TemporalUnit unit : amount.getUnits()) { System.out.println(unit + ": " + amount.get(unit)); } } // Custom query for specific unit Duration duration = Duration.ofMinutes(90); long hours = duration.get(ChronoUnit.HOURS); long minutes = duration.get(ChronoUnit.MINUTES); System.out.println("\n90 minutes = " + hours + " hours " + (minutes - hours * 60) + " minutes"); } }
This example demonstrates how to query the components of TemporalAmount objects. We examine both Period and Duration instances, showing their units and values. The get() method allows accessing specific unit values from the amount.
Using TemporalAmount with TemporalAdjuster
TemporalAmount can be used with TemporalAdjuster for more complex date manipulations. This example shows combining these interfaces for flexible date calculations.
package com.zetcode; import java.time.LocalDate; import java.time.Period; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAmount; public class Main { static class NextBusinessDayAdjuster implements TemporalAdjuster { private final TemporalAmount amount; public NextBusinessDayAdjuster(TemporalAmount amount) { this.amount = amount; } @Override public Temporal adjustInto(Temporal temporal) { Temporal adjusted = amount.addTo(temporal); LocalDate date = LocalDate.from(adjusted); // Adjust to next business day if needed while (date.getDayOfWeek().getValue() >= 6) { date = date.plusDays(1); } return temporal.with(date); } } public static void main(String[] args) { TemporalAmount twoDays = Period.ofDays(2); TemporalAdjuster adjuster = new NextBusinessDayAdjuster(twoDays); LocalDate friday = LocalDate.of(2025, 4, 4); // Friday LocalDate nextBusinessDay = friday.with(adjuster); System.out.println("Friday: " + friday); System.out.println("Two business days later: " + nextBusinessDay); // Using with Period Period period = Period.ofWeeks(1); LocalDate inOneWeek = friday.with(new NextBusinessDayAdjuster(period)); System.out.println("One business week later: " + inOneWeek); } }
This example combines TemporalAmount with TemporalAdjuster to create business-day aware date calculations. The adjuster ensures results land on business days, even when adding standard time amounts. This demonstrates powerful temporal manipulation.
Source
Java TemporalAmount Interface Documentation
In this article, we've covered the essential methods and features of the Java TemporalAmount interface. Understanding these concepts is crucial for flexible time handling in modern Java applications.
Author
List all Java tutorials.