Java Temporal Interface
Last modified: April 16, 2025
The java.time.temporal.Temporal
interface is a framework-level
interface that represents date-time objects. It provides access to date-time
fields and allows date-time arithmetic. Classes like LocalDate and ZonedDateTime
implement this interface.
Temporal
defines operations for querying and manipulating temporal
objects. It supports adding or subtracting time units, comparing dates, and
accessing temporal fields. The interface enables polymorphic handling of
different date-time types.
Temporal Interface Overview
The Temporal interface provides methods for temporal arithmetic and field access. Key operations include adding/subtracting time, querying fields, and adjusting values. It works with TemporalUnit and TemporalField for flexible operations.
public interface Temporal extends TemporalAccessor { boolean isSupported(TemporalUnit unit); Temporal with(TemporalField field, long newValue); Temporal plus(long amountToAdd, TemporalUnit unit); Temporal minus(long amountToSubtract, TemporalUnit unit); long until(Temporal endExclusive, TemporalUnit unit); }
The code above shows key methods of the Temporal
interface. These
methods enable manipulation of temporal objects while maintaining immutability.
Implementing classes provide concrete behavior for these operations.
Basic Temporal Operations
This example demonstrates basic operations available through the Temporal interface. We'll use LocalDate which implements Temporal to show common methods. The operations include adding time and querying fields.
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.of(2025, 4, 15); // Add 2 weeks Temporal futureDate = date.plus(2, ChronoUnit.WEEKS); System.out.println("Date in 2 weeks: " + futureDate); // Subtract 3 months Temporal pastDate = date.minus(3, ChronoUnit.MONTHS); System.out.println("Date 3 months ago: " + pastDate); // Check if unit is supported boolean supported = date.isSupported(ChronoUnit.DAYS); System.out.println("Days supported: " + supported); } }
This example shows basic Temporal operations using LocalDate. The plus and minus methods return new Temporal objects. The isSupported method checks if a time unit can be used with the temporal object.
Field Adjustments with Temporal
The Temporal interface allows modifying specific fields of date-time objects.
This is done using the with
method which returns a new adjusted
object. Field adjustments are precise and handle edge cases automatically.
package com.zetcode; import java.time.LocalDateTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDateTime dateTime = LocalDateTime.now(); System.out.println("Original: " + dateTime); // Change year Temporal newYear = dateTime.with(ChronoField.YEAR, 2030); System.out.println("Year changed: " + newYear); // Change hour Temporal newHour = dateTime.with(ChronoField.HOUR_OF_DAY, 15); System.out.println("Hour changed: " + newHour); // Chain adjustments Temporal adjusted = dateTime .with(ChronoField.MONTH_OF_YEAR, 12) .with(ChronoField.DAY_OF_MONTH, 25); System.out.println("Christmas date: " + adjusted); } }
This example demonstrates field adjustments using the Temporal interface. Each
with
operation returns a new Temporal object. Multiple adjustments
can be chained together to create complex transformations.
Calculating Time Between Temporals
The until
method calculates time between two temporal objects in
specified units. This is useful for determining durations between dates or
times. The method handles different temporal types automatically.
package com.zetcode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; public class Main { public static void main(String[] args) { LocalDate today = LocalDate.now(); LocalDate futureDate = today.plusMonths(3).plusDays(5); // Days between dates long daysBetween = today.until(futureDate, ChronoUnit.DAYS); System.out.println("Days between: " + daysBetween); // Months between dates long monthsBetween = today.until(futureDate, ChronoUnit.MONTHS); System.out.println("Months between: " + monthsBetween); // Mixed types calculation LocalDateTime now = LocalDateTime.now(); LocalDateTime later = now.plusHours(5).plusMinutes(30); long minutesBetween = now.until(later, ChronoUnit.MINUTES); System.out.println("Minutes between: " + minutesBetween); } }
This example shows how to calculate time between temporal objects. The until method works with different temporal types and units. Note that calculations are exact and respect calendar rules.
Temporal with TemporalAdjuster
Temporal objects can work with TemporalAdjusters for complex date adjustments. Adjusters provide pre-built operations like "next Tuesday" or "last day of month". This demonstrates the flexibility of the Temporal interface.
package com.zetcode; import java.time.LocalDate; import java.time.DayOfWeek; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.of(2025, 4, 15); // Next Friday Temporal nextFriday = date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)); System.out.println("Next Friday: " + nextFriday); // Last day of month Temporal monthEnd = date.with(TemporalAdjusters.lastDayOfMonth()); System.out.println("Month end: " + monthEnd); // First day of next year Temporal yearStart = date.with(TemporalAdjusters.firstDayOfNextYear()); System.out.println("Next year start: " + yearStart); // Custom adjuster (add 2 weeks) Temporal custom = date.with(temporal -> temporal.plus(2, ChronoUnit.WEEKS)); System.out.println("Custom adjusted: " + custom); } }
This example demonstrates using TemporalAdjusters with Temporal objects. The adjusters provide common date operations through a functional interface. Custom adjusters can also be created using lambda expressions.
Working with TemporalQueries
Temporal objects support queries for extracting information. The query method allows flexible extraction of data from temporal objects. This is useful for generic date-time processing code.
package com.zetcode; import java.time.LocalDateTime; import java.time.temporal.TemporalQueries; import java.time.temporal.TemporalQuery; public class Main { public static void main(String[] args) { LocalDateTime dateTime = LocalDateTime.now(); // Query for LocalDate TemporalQuery<java.time.LocalDate> dateQuery = TemporalQueries.localDate(); java.time.LocalDate datePart = dateTime.query(dateQuery); System.out.println("Date part: " + datePart); // Query for time precision TemporalQuery<java.time.temporal.ChronoUnit> precisionQuery = TemporalQueries.precision(); java.time.temporal.ChronoUnit precision = dateTime.query(precisionQuery); System.out.println("Precision: " + precision); // Custom query (get day of week) TemporalQuery<String> dayQuery = temporal -> temporal.query(TemporalQueries.localDate()) .getDayOfWeek().toString(); String dayOfWeek = dateTime.query(dayQuery); System.out.println("Day of week: " + dayOfWeek); } }
This example shows how to query temporal objects for information. Built-in queries are available through TemporalQueries, and custom queries can be created. The query method enables polymorphic handling of different temporal types.
Combining Temporal Operations
This example demonstrates combining multiple Temporal operations for complex date-time calculations. We'll chain operations to create a business logic scenario involving date calculations.
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { LocalDate projectStart = LocalDate.of(2025, 4, 15); // Calculate project timeline Temporal milestone1 = projectStart .plus(2, ChronoUnit.WEEKS) .with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY)); Temporal milestone2 = ((LocalDate) milestone1) .plus(3, ChronoUnit.WEEKS) .with(TemporalAdjusters.lastDayOfMonth()); Temporal projectEnd = ((LocalDate) milestone2) .plus(1, ChronoUnit.MONTHS) .with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.FRIDAY)); System.out.println("Project start: " + projectStart); System.out.println("Milestone 1: " + milestone1); System.out.println("Milestone 2: " + milestone2); System.out.println("Project end: " + projectEnd); // Calculate total duration long totalDays = projectStart.until(projectEnd, ChronoUnit.DAYS); System.out.println("Total project days: " + totalDays); } }
This example combines multiple Temporal operations to model a project timeline. We use plus operations, adjusters, and duration calculations. Note the casting needed when specific methods from LocalDate are required.
Source
Java Temporal Interface Documentation
In this article, we've covered the essential methods and features of the Java Temporal interface. Understanding these concepts is crucial for working with date and time in modern Java applications.
Author
List all Java tutorials.