Руководство Java TemporalAccessor
1. TemporalAccessor
Интерфейс TemporalAccessor имитирует общее понятие между понятиями даты (date), времени (time), смещения времени (time-offset), смещения часового пояса (zone-offset) и эры (era). Он предоставляет основные методы получения информации от этих объектов.
public interface TemporalAccessor
Список подклассов или enum, реализующих интерфейс (implement) TemporalAccessor:
- Era
- ThaiBuddhistEra
- ChronoLocalDate
- ChronoLocalDateTime
- ChronoZonedDateTime
- LocalDate
- Temporal
- ZoneOffset
- DayOfWeek
- MonthDay
- Month
- IsoEra
- HijrahEra
- JapaneseEra
- MinguoEra
- LocalTime
- LocalDateTime
- ZonedDateTime
- ChronoZonedDateTime
- ThaiBuddhistDate
- MinguoDate
- JapaneseDate
- HijrahDate
- YearMonth
- Year
- OffsetDateTime
- OffsetTime
- Instant
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
Руководства Java Date Time
- Руководство Java ZoneId
- Руководство Java Temporal
- Руководство Java Period
- Руководство Java TemporalAdjusters
- Руководство Java MinguoDate
- Руководство Java TemporalAccessor
- Руководство Java JapaneseEra
- Руководство Java HijrahDate
- Руководство Java Date Time
- Что такое летнее время (DST)?
- Руководство Java LocalDate
- Руководство Java LocalTime
- Руководство Java ZonedDateTime
- Руководство Java JapaneseDate
- Руководство Java Duration
- Руководство Java TemporalQuery
- Руководство Java TemporalAdjuster
- Руководство Java ChronoUnit
- Руководство Java TemporalQueries
Show More
- Руководства Java Web Services
- Руководства Java Servlet/JSP
- Руководства JavaFX
- Руководства Java SWT
- Руководства Oracle Java ADF
- Java Basic
- Руководства Java Collections Framework
- Руководства Java IO
- Руководства Struts2 Framework
- Руководства Spring Boot
- Руководства Spring Cloud
- Руководства Maven
- Руководства Gradle