Temporal Fields
The java.time.temporal.TemporalField interface represents a specific field of a temporal object. The java.time.temporal.ChronoField enum type implements this interface, defining the fields by constant names so that a specific field can be conveniently accessed. Selected constants from the ChronoField enum type include SECOND_OF_MINUTE, MINUTE_OF_DAY, DAY_OF_MONTH, MONTH_OF_YEAR, and YEAR.
The output from Example 17.4 shows a table with all the temporal fields defined by the ChronoField enum type.
Analogous to a ChronoUnit enum constant, a ChronoField enum constant can be queried by the following selected methods:
TemporalUnit getBaseUnit()
Gets the unit that the field is measured in. For example, ChronoField.DAY_OF_ MONTH.getBaseUnit() returns ChronoUnit.DAYS.
boolean isDateBased()
boolean isTimeBased()
Check whether this field represents a date or a time field, respectively. For example, ChronoField.HOUR_OF_DAY.isDateBased() is false, but ChronoField.SECOND_ OF_MINUTE.isTimeBased() is true.
boolean isSupportedBy(TemporalAccessor temporal)
Checks whether this field is supported by the specified temporal object. For example, ChronoField.YEAR.isSupportedBy(LocalTime.MIDNIGHT) is false.
static ChronoField[] values()
Returns an array containing the field constants of this enum type, in the order they are declared. This method is called at (7) in Example 17.4.
The temporal classes provide the method isSupported(field) to determine whether a temporal field is valid for a temporal object. In Example 17.4, this method is used at (8), (9), and (10) to determine whether each temporal field defined by the ChronoField enum type is a valid field for the different temporal classes.
The following methods of the temporal classes all accept a temporal field that designates a specific field of the temporal object:
- get(field), (p. 1032)
LocalDate date = LocalDate.of(2021, 8, 13);
int monthValue = date.get(ChronoField.MONTH_OF_YEAR);
System.out.print(“Date ” + date + ” has month of the year: ” + monthValue);
// Date 2021-08-13 has month of the year: 8
- with(field, amount), (p. 1035)
LocalDateTime dateTime = LocalDateTime.of(2021, 8, 13, 20, 20);
System.out.print(“Date-time ” + dateTime);
dateTime = dateTime.with(ChronoField.DAY_OF_MONTH, 11)
.with(ChronoField.MONTH_OF_YEAR, 1)
.with(ChronoField.YEAR, 2022);
System.out.println(” changed to: ” + dateTime);
// Date-time 2021-08-13T20:20 changed to: 2022-01-11T20:20
In Example 17.4, the code at (1) and at (6) prints tables that show which ChronoUnit and ChronoField constants are valid in which temporal-based object. A LocalTime instance supports time-based units and fields, and a LocalDate instance supports date-based units and fields. A LocalDateTime or a ZonedDateTime supports both time-based and date-based units and fields. Using an invalid enum constant for a temporal object will invariably result in an UnsupportedTemporalTypeException being thrown.
Example 17.4 Valid Temporal Units and Temporal Fields
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
public class ValidTemporalUnitsAndFields {
public static void main(String[] args) {
// Temporals:
LocalTime time = LocalTime.now();
LocalDate date = LocalDate.now();
LocalDateTime dateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
Instant instant = Instant.now();
// Print supported units: // (1)
System.out.printf(“%29s %s %s %s %s %s%n”,
“ChronoUnit”, “LocalTime”, “LocalDate”, “LocalDateTime”,
” ZDT “, “Instant”);
ChronoUnit[] units = ChronoUnit.values(); // (2)
for (ChronoUnit unit : units) {
System.out.printf(“%28S: %7b %9b %10b %9b %7b%n”,
unit.name(), time.isSupported(unit), date.isSupported(unit), // (3)
dateTime.isSupported(unit), zonedDateTime.isSupported(unit), // (4)
instant.isSupported(unit)); // (5)
}
System.out.println();
// Print supported fields: // (6)
System.out.printf(“%29s %s %s %s %s %s%n”,
“ChronoField”, “LocalTime”, “LocalDate”, “LocalDateTime”,
” ZDT “, “Instant”);
ChronoField[] fields = ChronoField.values(); // (7)
for (ChronoField field : fields) {
System.out.printf(“%28S: %7b %9b %10b %9b %7b%n”,
field.name(), time.isSupported(field), date.isSupported(field),// (8)
dateTime.isSupported(field), zonedDateTime.isSupported(field), // (9)
instant.isSupported(field)); // (10)
}
System.out.println();
}
}
Output from the program (ZDT stands for ZonedDateTime in the output):
ChronoUnit LocalTime LocalDate LocalDateTime ZDT Instant
NANOS: true false true true true
MICROS: true false true true true
MILLIS: true false true true true
SECONDS: true false true true true
MINUTES: true false true true true
HOURS: true false true true true
HALF_DAYS: true false true true true
DAYS: false true true true true
WEEKS: false true true true false
MONTHS: false true true true false
YEARS: false true true true false
DECADES: false true true true false
CENTURIES: false true true true false
MILLENNIA: false true true true false
ERAS: false true true true false
FOREVER: false false false false false
ChronoField LocalTime LocalDate LocalDateTime ZDT Instant
NANO_OF_SECOND: true false true true true
NANO_OF_DAY: true false true true false
MICRO_OF_SECOND: true false true true true
MICRO_OF_DAY: true false true true false
MILLI_OF_SECOND: true false true true true
MILLI_OF_DAY: true false true true false
SECOND_OF_MINUTE: true false true true false
SECOND_OF_DAY: true false true true false
MINUTE_OF_HOUR: true false true true false
MINUTE_OF_DAY: true false true true false
HOUR_OF_AMPM: true false true true false
CLOCK_HOUR_OF_AMPM: true false true true false
HOUR_OF_DAY: true false true true false
CLOCK_HOUR_OF_DAY: true false true true false
AMPM_OF_DAY: true false true true false
DAY_OF_WEEK: false true true true false
ALIGNED_DAY_OF_WEEK_IN_MONTH: false true true true false
ALIGNED_DAY_OF_WEEK_IN_YEAR: false true true true false
DAY_OF_MONTH: false true true true false
DAY_OF_YEAR: false true true true false
EPOCH_DAY: false true true true false
ALIGNED_WEEK_OF_MONTH: false true true true false
ALIGNED_WEEK_OF_YEAR: false true true true false
MONTH_OF_YEAR: false true true true false
PROLEPTIC_MONTH: false true true true false
YEAR_OF_ERA: false true true true false
YEAR: false true true true false
ERA: false true true true false
INSTANT_SECONDS: false false false true true
OFFSET_SECONDS: false false false true false