o7planning

Java Temporal Tutorial with Examples

  1. Temporal
  2. Temporal methods
  3. isSupported(TemporalUnit)
  4. with(TemporalAdjuster)
  5. with(TemporalField, long)
  6. plus(TemporalAmount)
  7. plus(long, TemporalUnit)
  8. minus(TemporalAmount)
  9. minus(long, TemporalUnit)
  10. until(Temporal, TemporalUnit)

1. Temporal

The Temporal interface simulates a common concept between the concepts of date, time and time-offset. It provides basic methods to get information from these objects.
public interface Temporal extends TemporalAccessor
The Temporal interface extends from the TemporalAccessor interface, and they are a bit different:
TemporalAccessor
Simulate a common concept between the concepts of date, time, time-offset, time-zone offset and era.
Temporal
Simulate a common concept between the concepts of date, time time-offset
As such, Interface Temporal reduces the number of concepts it represents compared to TemporalAccessor. It provides more detailed methods of these concepts.
List of subclasses or enum(s) that implement the Temporal interface:

2. Temporal methods

public boolean isSupported(TemporalUnit unit);

public default Temporal with(TemporalAdjuster adjuster)

public Temporal with(TemporalField field, long newValue);

public default Temporal plus(TemporalAmount amount)  

public Temporal plus(long amountToAdd, TemporalUnit unit);

public default Temporal minus(TemporalAmount amount)  

public default Temporal minus(long amountToSubtract, TemporalUnit unit)  

public long until(Temporal endExclusive, TemporalUnit unit);

3. isSupported(TemporalUnit)

Check if the specified unit is supported by this Temporal.
public boolean isSupported(TemporalUnit unit)
This check is necessary before using the plus(long,TemporalUnit) or minus(long,TemporalUnit) method. If calling these methods with an unsupported unit, an exception will be thrown.
Temporal_isSupported_x1.java
Temporal localDate = LocalDate.now();

boolean supported = localDate.isSupported(ChronoField.DAY_OF_MONTH);
System.out.println("localDate support DAY_OF_MONTH? " + supported); // true

Temporal localTime = LocalTime.now();

supported = localTime.isSupported(ChronoField.DAY_OF_MONTH);
System.out.println("localTime support DAY_OF_MONTH? " + supported); // false
You can also use the TemporalUnit.isSupportedBy(Temporal) method to check if a particular TemporalUnit is supported by a given Temporal.
TemporalUnit_isSupportedBy_x1.java
Temporal localDate = LocalDate.now();

boolean supported = ChronoField.DAY_OF_MONTH.isSupportedBy(localDate);
System.out.println("localDate support DAY_OF_MONTH? " + supported); // true

4. with(TemporalAdjuster)

Return a copy of this Temporal object with some information adjusted by the specified TemporalAdjuster object.
public default Temporal with(TemporalAdjuster adjuster)
Basically, there are 2 ways to adjust a Temporal object, in which the second approach is recommended:
Temporal adjustedCopy = temporalAdjuster.adjustInto(temporal);  // (1)

Temporal adjustedCopy = temporal.with(temporalAdjuster);           // (2)
Example:
Temporal_with_adjuster_ex1.java
// Temporal object:
Temporal localDateTime = LocalDateTime.of(2020, 1, 1, 13, 30, 45);
System.out.println("localDateTime: " + localDateTime); // 2020-01-01T13:30:45

// TemporalAdjuter object:
TemporalAdjuster adjuster = Month.JULY;

LocalDateTime adjustedLocalDateTime = (LocalDateTime) localDateTime.with(adjuster);
System.out.println("adjustedLocalDateTime: " + adjustedLocalDateTime); // 2020-07-01T13:30:45
See also TemporalAdjuster article for more examples:

5. with(TemporalField, long)

Return a copy of this Temporal object with the specified field changed.
public Temporal with(TemporalField field, long newValue)
In some cases, changing one field can make another field invalid. For example, January 31, changing from January to February will make the day-of-month invalid. This method will change the day-of-month to the nearest valid date.
Temporal_with_field_ex1.java
// Temporal object:
Temporal localDate1 = LocalDate.of(2020, 1, 15);
System.out.println("localDate1: " + localDate1); // 2020-01-15

Temporal copiedLocalDate1 = localDate1.with(ChronoField.MONTH_OF_YEAR, 2);
System.out.println("copiedLocalDate1: " + copiedLocalDate1); // 2020-02-15
System.out.println();

// Temporal object:
Temporal localDate2 = LocalDate.of(2020, 1, 31);
System.out.println("localDate2: " + localDate2); // 2020-01-31

Temporal copiedLocalDate2 = localDate2.with(ChronoField.MONTH_OF_YEAR, 2);
System.out.println("copiedLocalDate2: " + copiedLocalDate2); // 2020-02-29
  • ChronoField
  • TemporalField

6. plus(TemporalAmount)

Return a copy of this Temporal with an amount of time added.
public default Temporal plus(TemporalAmount amount)
Example:
Temporal_plus_amount_ex1.java
Temporal localDateTime = LocalDateTime.of(2020,5,15, 13,30,45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();
 
// plus(TemporalAmount amountToAdd)
TemporalAmount amount1 = Period.ofDays(5);
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.plus(amount1);
System.out.println("localDateTime1: " + localDateTime1); // 2020-05-20T13:30:45
 
// 1 day 2 hours 30 minutes.
TemporalAmount amount2 = Duration.ofMinutes(1* 24 * 60 + 2* 60 + 30);
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.plus(amount2);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-16T16:00:45
The Temporal.plus(TemporalAmount) method works similarly to the TemporalAmount.addTo(Temporal) method:
// This method is defined in the TemporalAmount interface:
public Temporal addTo(Temporal temporal)

7. plus(long, TemporalUnit)

Return a copy of this Temporal with the specified amount of value added.
public Temporal plus(long amountToAdd, TemporalUnit unit)
Example:
Temporal_plus_unit_ex1.java
Temporal localDateTime = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();

// plus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.plus(20, ChronoUnit.DAYS);
System.out.println("localDateTime1: " + localDateTime1); // 2020-06-04T13:30:45

// plus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.plus(2, ChronoUnit.WEEKS);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-29T13:30:45
The Temporal.plus(long,TemporalUnit) method works similarly to the TemporalUnit.addTo(R,long) method:
// This method is defined in the TemporalUnit interface:
public <R extends Temporal> R addTo(R temporal, long amount)

8. minus(TemporalAmount)

Return a copy of this Temporal with the specified amount of time subtracted.
public default Temporal minus(TemporalAmount amount)
Example:
Temporal_minus_amount_ex1.java
Temporal localDateTime = LocalDateTime.of(2020,5,15, 13,30,45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();
 
// minus(TemporalAmount amountToAdd)
TemporalAmount amount1 = Period.ofDays(5);
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.minus(amount1);
System.out.println("localDateTime1: " + localDateTime1); // 2020-05-10T13:30:45
 
// 1 day 2 hours 30 minutes.
TemporalAmount amount2 = Duration.ofMinutes(1* 24 * 60 + 2* 60 + 30);
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.minus(amount2);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-14T11:00:45
The Temporal.minus(TemporalAmount) method works similarly to the TemporalAmount.subtractFrom(Temporal) method:
// This method is defined in the TemporalAmount interface:
public Temporal subtractFrom(Temporal temporal)

9. minus(long, TemporalUnit)

Return a copy of this Temporal with the specified amount subtracted in the specified unit.
public default Temporal minus(long amountToSubtract, TemporalUnit unit)
Example:
Temporal_minus_unit_ex1.java
Temporal localDateTime = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("localDateTime: " + localDateTime); // 2020-05-15T13:30:45
System.out.println();

// minus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime1 = (LocalDateTime) localDateTime.minus(20, ChronoUnit.DAYS);
System.out.println("localDateTime1: " + localDateTime1); // 2020-04-25T13:30:45

// minus(long amountToAdd, TemporalUnit unit)
LocalDateTime localDateTime2 = (LocalDateTime) localDateTime.minus(20, ChronoUnit.HOURS);
System.out.println("localDateTime2: " + localDateTime2); // 2020-05-14T17:30:45

10. until(Temporal, TemporalUnit)

Calculate the amount of time from one Temporal to another Temporal in the specified units.
(**) The specified unit must be supported by both Temporal objects participating in the method, or else a DateTimeException will be thrown.
public long until(Temporal endExclusive, TemporalUnit unit)
Example:
Temporal_until_ex1.java
Temporal temporalFrom = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("temporalFrom: " + temporalFrom); // 2020-05-15T13:30:45

Temporal temporalTo = LocalDate.of(2020, 5, 16).atStartOfDay(); // LocalDateTime
System.out.println("temporalTo: " + temporalTo); // 2020-05-16T00:00
System.out.println();

long hourAmount = temporalFrom.until(temporalTo, ChronoUnit.HOURS);
System.out.println("hourAmount: " + hourAmount); // 10
You can also use the TemporalUnit.between(Temporal,Temporal) method in the same case:
TemporalUnit_between_ex1.java
Temporal temporalFrom = LocalDateTime.of(2020, 5, 15, 13, 30, 45);
System.out.println("temporalFrom: " + temporalFrom); // 2020-05-15T13:30:45

Temporal temporalTo = LocalDate.of(2020, 5, 16).atStartOfDay(); // LocalDateTime
System.out.println("temporalTo: " + temporalTo); // 2020-05-16T00:00
System.out.println();

long hourAmount = ChronoUnit.HOURS.between(temporalFrom, temporalTo);
System.out.println("hourAmount: " + hourAmount); // 10