betacode

Руководство Java TemporalAccessor

  1. TemporalAccessor
  2. TemporalAccessor methods
  3. query(TemporalQuery<R>)
  4. range(TemporalField)
  5. get(TemporalField)
  6. getLong(TemporalField)
  7. isSupported(TemporalField)

1. TemporalAccessor

Интерфейс TemporalAccessor имитирует общее понятие между понятиями даты (date), времени (time), смещения времени (time-offset), смещения часового пояса (zone-offset) и эры (era). Он предоставляет основные методы получения информации от этих объектов.
public interface TemporalAccessor
Список подклассов или enum, реализующих интерфейс (implement) TemporalAccessor:
TemporalAccessor - это интерфейс на уровне фреймворка (framework-level). Будьте осторожны при использовании его в вашем приложении, потому что это базовый интерфейс различных календарных систем, поддерживаемых в Java Date Time API. Более подробное обсуждение см. интерфейс ChronoLocalDate.
  • Руководство Java ChronoLocalDate
Примечание: Если вы собираетесь писать классы, реализующие (implement) интерфейс TemporalAccessor, вам следует писать классы с неизменяемостью (immutability), чтобы они соответствовали Java Date Time API (хотя это и не требуется).

2. TemporalAccessor methods

public boolean isSupported(TemporalField field);

public default ValueRange range(TemporalField field)  

public default int get(TemporalField field)  

public long getLong(TemporalField field);

public default <R> R query(TemporalQuery<R> query)

3. query(TemporalQuery<R>)

Запросите этот объект TemporalAccessor с помощью указанного объекта TemporalQuery для извлечения информации.
public default <R> R query(TemporalQuery<R> query)
См. Примеры этой темы в статье о TemporalQuery:

4. range(TemporalField)

Возвращает объект ValueRange, описывающий диапазон допустимых значений для указанного поля (field). Это метод интерфейса TemporalAccessor по умолчанию. Он может быть переопределен (override) в подклассах TemporalAccessor.
public default ValueRange range(TemporalField field) {
    if (field instanceof ChronoField) {
        if (isSupported(field)) {
            return field.range();
        }
        throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    }
    Objects.requireNonNull(field, "field");
    return field.rangeRefinedBy(this);
}
В принципе, объект ValueRange содержит минимальное и максимальное значение данного поля (field) по типу данных long. Если указанное поле не задано или не поддерживается, создается исключение UnsupportedTemporalTypeException.
ChronoField - это enum, реализующий (implement) интерфейс TemporalField, который содержит стандартные поля и достаточен для использования в Java Date Time API.
  • ChronoField.DAY_OF_WEEK
  • ChronoField.DAY_OF_YEAR
  • ChronoField.HOUR_OF_DAY
  • ...
TemporalAccessor_range_x1.java
package org.o7planning.temporalaccessor.ex;

import java.time.LocalDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.ValueRange;

public class TemporalAccessor_range_x1 {

    public static void main(String[] args) {

        TemporalAccessor localDateTime = LocalDateTime.of(2021, 2, 15, 0, 0, 0);
        System.out.printf("localDateTime: %s%n%n", localDateTime); // 2021-02-15T00:00

        if (localDateTime.isSupported(ChronoField.HOUR_OF_DAY)) {
            ValueRange valueRange1 = localDateTime.range(ChronoField.HOUR_OF_DAY);

            System.out.println("HOUR_OF_DAY range: " + valueRange1); // 0 - 23
            System.out.println("valueRange1.getMinimum(): " + valueRange1.getMinimum()); // 0
            System.out.println("valueRange1.getMaximum(): " + valueRange1.getMaximum()); // 23
        }
        System.out.println(" --------- ");

        if (localDateTime.isSupported(ChronoField.DAY_OF_MONTH)) {
            ValueRange valueRange2 = localDateTime.range(ChronoField.DAY_OF_MONTH);

            System.out.println("DAY_OF_MONTH range: " + valueRange2); // 1 - 28
            System.out.println("valueRange2.getMinimum(): " + valueRange2.getMinimum()); // 1
            System.out.println("valueRange2.getMaximum(): " + valueRange2.getMaximum()); // 28
        }

        System.out.println(" --------- ");

        if (localDateTime.isSupported(ChronoField.DAY_OF_YEAR)) {
            ValueRange valueRange3 = localDateTime.range(ChronoField.DAY_OF_YEAR);

            System.out.println("DAY_OF_MONTH range: " + valueRange3); // 1 - 365
            System.out.println("valueRange3.getMinimum(): " + valueRange3.getMinimum()); // 1
            System.out.println("valueRange3.getMaximum(): " + valueRange3.getMaximum()); // 365
        }
    }
}
Output:
localDateTime: 2021-02-15T00:00

HOUR_OF_DAY range: 0 - 23
valueRange1.getMinimum(): 0
valueRange1.getMaximum(): 23
 ---------
DAY_OF_MONTH range: 1 - 28
valueRange2.getMinimum(): 1
valueRange2.getMaximum(): 28
 ---------
DAY_OF_MONTH range: 1 - 365
valueRange3.getMinimum(): 1
valueRange3.getMaximum(): 365
  • TemporalField
  • ChronoField

5. get(TemporalField)

Возвращает значение указанного поля (field) из этого объекта TemporalAccessor в виде 32-разрядного целого числа.
public default int get(TemporalField field) {
    ValueRange range = range(field);
    if (range.isIntValue() == false) {
        throw new UnsupportedTemporalTypeException("Invalid field " + field + " for get() method, use getLong() instead");
    }
    long value = getLong(field);
    if (range.isValidValue(value) == false) {
        throw new DateTimeException("Invalid value for " + field + " (valid values " + range + "): " + value);
    }
    return (int) value;
}
Примечание: В некоторых случаях следует использовать метод getLong(TemporalField) вместо get(TemporalField). Причина состоит в том, что типа данных int недостаточно для хранения значений некоторых полей (field), таких как ChronoField.PROLEPTIC_MONTH, ChronoField.EPOCH_DAY.
Например:
TemporalAccessor_get_x1.java
package org.o7planning.temporalaccessor.ex;

import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;

public class TemporalAccessor_get_x1 {

    public static void main(String[] args) {
        TemporalAccessor localDate = LocalDate.of(2021, 2, 15);
        System.out.printf("localDate: %s%n%n", localDate); // 2021-02-15T00:00  
        
        if (localDate.isSupported(ChronoField.YEAR)) {
            int year = localDate.get(ChronoField.YEAR);  
            System.out.println("year: " + year); // 2021
        }

        if (localDate.isSupported(ChronoField.DAY_OF_MONTH)) {
            int dayOfMonth = localDate.get(ChronoField.DAY_OF_MONTH);  
            System.out.println("dayOfMonth: " + dayOfMonth); // 15
        }

        if (localDate.isSupported(ChronoField.DAY_OF_YEAR)) {
            int dayOfYear = localDate.get(ChronoField.DAY_OF_YEAR);
            System.out.println("dayOfYear: " + dayOfYear); // 46
        }
    }
}
  • ChronoField
  • TemporalField

6. getLong(TemporalField)

Возвращает значение указанного поля (field) из этого объекта TemporalAccessor в виде целого числа 64 bit.
public long getLong(TemporalField field)
В принципе, этот метод такой же, как get(TemporalField). Разница состоит в том, что он возвращает тип данных long. Например, типа данных int недостаточно для хранения значения поля ChronoField.EPOCH_DAY, поэтому вам нужно использовать метод getLong(Temporal).
Следующие стандартные поля должны использоваться методом getLong(TemporalField) вместо метода get(TemporalField):
  • ChronoField.PROLEPTIC_MONTH
  • ChronoField.EPOCH_DAY
TemporalAccessor_getLong_x1.java
package org.o7planning.temporalaccessor.ex;

import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;

public class TemporalAccessor_getLong_x1 {

    public static void main(String[] args) {
        TemporalAccessor localDate = LocalDate.of(2021, 2, 15);
        System.out.printf("localDate: %s%n%n", localDate); // 2021-02-15T00:00  
        
        if (localDate.isSupported(ChronoField.EPOCH_DAY)) {
            // Using getLong(TemporalField) method:
            long epochDay  = localDate.getLong(ChronoField.EPOCH_DAY);  
            System.out.println("epochDay: " + epochDay); // 18673
        }

        if (localDate.isSupported(ChronoField.EPOCH_DAY)) {
            // Using get(TemporalField) method:
            int epochDay  = localDate.get(ChronoField.EPOCH_DAY); // --> Exception!
            System.out.println("epochDay: " + epochDay);  
        }
    }
}
Output:
localDate: 2021-02-15

epochDay: 18673
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Invalid field 'EpochDay' for get() method, use getLong() instead
    at java.base/java.time.LocalDate.get0(LocalDate.java:699)
    at java.base/java.time.LocalDate.get(LocalDate.java:650)
    at org.o7planning.temporalaccessor.ex.TemporalAccessor_getLong_x1.main(TemporalAccessor_getLong_x1.java:21)
  • ChronoField
  • TemporalField

7. isSupported(TemporalField)

Проверьте, поддерживается ли указанное поле (field) этим TemporalAccessor.
public boolean isSupported(TemporalField field)
(**) Список стандартных полей (field) , которые он поддерживает, см. конкретные классы.
Например:
  • Класс LocalDate представляет дату (date) и не включает время и часовой пояс. Он поддерживает стандартные поля, такие как ChronoField.YEAR, ChronoField.DAY_OF_MONTH,.. но не такие поля, как ChronoField.SECOND_OF_DAY, ChronoField.HOUR_OF_DAY, ...
  • Класс LocalDateTime представляет дату (date) и время (time), но не включает часовой пояс. Он поддерживает стандартные поля, такие как ChronoField.YEAR, ChronoField.DAY_OF_MONTH, ChronoField.SECOND_OF_DAY, ChronoField.HOUR_OF_DAY.. но не поддерживает такие поля, как ChronoField.OFFSET_SECONDS,..
TemporalAccessor_isSupported_ex1.java
TemporalAccessor localDate = LocalDate.of(2021, 2, 15);

System.out.println("Does localDate support: ");
 
System.out.println(" YEAR ? " + localDate.isSupported(ChronoField.YEAR)); // true
System.out.println(" DAY_OF_MONTH ? " + localDate.isSupported(ChronoField.DAY_OF_MONTH)); // true
System.out.println(" SECOND_OF_DAY ? " + localDate.isSupported(ChronoField.SECOND_OF_DAY)); // false
System.out.println(" HOUR_OF_DAY ? " + localDate.isSupported(ChronoField.HOUR_OF_DAY)); // false
System.out.println(" OFFSET_SECONDS ? " + localDate.isSupported(ChronoField.OFFSET_SECONDS)); // false

System.out.println(" ----- ");

TemporalAccessor localDateTime = LocalDateTime.of(2021, 2, 15, 12, 30, 45);
System.out.println("Does localDateTime support: ");

System.out.println(" YEAR ? " + localDateTime.isSupported(ChronoField.YEAR)); // true
System.out.println(" DAY_OF_MONTH ? " + localDateTime.isSupported(ChronoField.DAY_OF_MONTH)); // true
System.out.println(" SECOND_OF_DAY ? " + localDateTime.isSupported(ChronoField.SECOND_OF_DAY)); // true
System.out.println(" HOUR_OF_DAY ? " + localDateTime.isSupported(ChronoField.HOUR_OF_DAY)); // true
System.out.println(" OFFSET_SECONDS ? " + localDate.isSupported(ChronoField.OFFSET_SECONDS)); // false
Output:
Does localDate support:
 YEAR ? true
 DAY_OF_MONTH ? true
 SECOND_OF_DAY ? false
 HOUR_OF_DAY ? false
 OFFSET_SECONDS ? false
 -----
Does localDateTime support:
 YEAR ? true
 DAY_OF_MONTH ? true
 SECOND_OF_DAY ? true
 HOUR_OF_DAY ? true
 OFFSET_SECONDS ? false
  • TemporalField
  • ChronoField