Temporal Fields – Date and Time

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.

Click here to view code image

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:

Click here to view code image

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

Click here to view code image

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

Click here to view code image

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):

Click here to view code image

                   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