Java TemporalAccessor 接口
最后修改时间:2025 年 4 月 16 日
java.time.temporal.TemporalAccessor
接口提供对时间对象的只读访问。它是 java.time 包中所有日期时间类的基本接口。TemporalAccessor 允许查询时间对象。
TemporalAccessor
定义了用于检查日期时间值的方法。它支持获取字段和查询时间信息。许多类,如 LocalDate 和 ZonedDateTime,都实现了此接口。
TemporalAccessor 接口概述
该接口提供了访问时间信息的方法。关键操作包括检查字段支持和获取字段值。它与 TemporalField 和 TemporalUnit 一起使用,以实现灵活的时间处理。
public interface TemporalAccessor { boolean isSupported(TemporalField field); long getLong(TemporalField field); default int get(TemporalField field); default <R> R query(TemporalQuery<R> query); }
上面的代码展示了 TemporalAccessor
的方法。这些方法允许检查时间对象而不修改它们。该接口构成了 Java 中只读时间操作的基础。
检查支持的字段
isSupported
方法检查时间对象中是否有可用的字段。不同的时间类支持不同的字段。在尝试访问字段值之前,此检查至关重要。
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.now(); // Check supported fields System.out.println("Year supported: " + date.isSupported(ChronoField.YEAR)); System.out.println("Hour supported: " + date.isSupported(ChronoField.HOUR_OF_DAY)); System.out.println("Era supported: " + date.isSupported(ChronoField.ERA)); // Alternative check System.out.println("Month supported: " + date.isSupported(ChronoField.MONTH_OF_YEAR)); } }
此示例演示了如何检查 LocalDate 对象中的字段支持。基于日期的类通常不支持与时间相关的字段。在访问字段之前,请务必验证支持以避免异常。
获取字段值
getLong
方法将字段值作为长整型数字检索。对于较小的范围,get
提供 int 值。这些方法对于不支持的字段会抛出异常。
package com.zetcode; import java.time.LocalDateTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDateTime dateTime = LocalDateTime.now(); // Get field values long year = dateTime.getLong(ChronoField.YEAR); int month = dateTime.get(ChronoField.MONTH_OF_YEAR); int day = dateTime.get(ChronoField.DAY_OF_MONTH); System.out.println("Year: " + year); System.out.println("Month: " + month); System.out.println("Day: " + day); // Get time values int hour = dateTime.get(ChronoField.HOUR_OF_DAY); int minute = dateTime.get(ChronoField.MINUTE_OF_HOUR); System.out.println("Hour: " + hour); System.out.println("Minute: " + minute); } }
此示例展示了如何从 LocalDateTime 检索各种字段值。getLong
方法用于较大的范围,例如年。get
方法适用于较小的范围,例如小时和分钟。
使用 TemporalQuery
query
方法允许复杂的时间查询。它使用 TemporalQuery 实现来提取信息。这提供了比直接字段访问更大的灵活性。
package com.zetcode; import java.time.LocalDate; import java.time.ZonedDateTime; import java.time.temporal.TemporalQueries; public class Main { public static void main(String[] args) { ZonedDateTime zdt = ZonedDateTime.now(); // Query for local date LocalDate date = zdt.query(TemporalQueries.localDate()); System.out.println("Local date: " + date); // Query for time zone System.out.println("Zone: " + zdt.query(TemporalQueries.zone())); // Query for precision System.out.println("Precision: " + zdt.query(TemporalQueries.precision())); // Custom query String quarter = zdt.query(temporal -> { int month = temporal.get(ChronoField.MONTH_OF_YEAR); return "Q" + ((month - 1) / 3 + 1); }); System.out.println("Quarter: " + quarter); } }
此示例演示了各种时间查询。 TemporalQueries 中的内置查询提供了常见的操作。自定义查询展示了如何实现业务逻辑,例如季度计算。
使用不同的时间类型
TemporalAccessor 在不同的时间类型之间统一工作。可以使用相同的方法来处理 LocalDate、LocalTime 和其他实现。这提供了对时间信息的一致访问。
package com.zetcode; import java.time.Instant; import java.time.LocalTime; import java.time.YearMonth; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { // With LocalTime LocalTime time = LocalTime.now(); System.out.println("Hour: " + time.get(ChronoField.HOUR_OF_DAY)); // With Instant Instant instant = Instant.now(); System.out.println("Epoch second: " + instant.getLong(ChronoField.INSTANT_SECONDS)); // With YearMonth YearMonth yearMonth = YearMonth.now(); System.out.println("Month: " + yearMonth.get(ChronoField.MONTH_OF_YEAR)); // Common interface usage printTemporalInfo(time); printTemporalInfo(instant); printTemporalInfo(yearMonth); } private static void printTemporalInfo(TemporalAccessor temporal) { if (temporal.isSupported(ChronoField.YEAR)) { System.out.println("Year: " + temporal.getLong(ChronoField.YEAR)); } } }
此示例展示了 TemporalAccessor 与不同的时间类型一起工作。 printTemporalInfo
方法演示了多态行为。请注意在访问年份值之前进行字段支持检查。
提取部分信息
TemporalAccessor 可以从时间对象中提取部分信息。当只需要特定字段时,这很有用。该接口提供了对时间数据的灵活访问。
package com.zetcode; import java.time.LocalDateTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDateTime ldt = LocalDateTime.now(); // Extract date part System.out.println("Date: " + ldt.get(ChronoField.YEAR) + "-" + ldt.get(ChronoField.MONTH_OF_YEAR) + "-" + ldt.get(ChronoField.DAY_OF_MONTH)); // Extract time part System.out.println("Time: " + ldt.get(ChronoField.HOUR_OF_DAY) + ":" + ldt.get(ChronoField.MINUTE_OF_HOUR) + ":" + ldt.get(ChronoField.SECOND_OF_MINUTE)); // Extract day of week System.out.println("Day of week: " + ldt.get(ChronoField.DAY_OF_WEEK)); // Extract week of year System.out.println("Week of year: " + ldt.get(ChronoField.ALIGNED_WEEK_OF_YEAR)); } }
此示例演示了如何从 LocalDateTime 提取特定字段。代码展示了如何构建自定义字符串表示形式。可以独立访问各种日期和时间组件。
处理不支持的字段
使用 TemporalAccessor 时,某些字段可能不受支持。适当的错误处理至关重要。isSupported
检查应先于字段访问。
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoField; import java.time.temporal.UnsupportedTemporalTypeException; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.now(); try { // Attempt to access unsupported field int hour = date.get(ChronoField.HOUR_OF_DAY); System.out.println("Hour: " + hour); } catch (UnsupportedTemporalTypeException e) { System.out.println("Error: " + e.getMessage()); } // Safe field access if (date.isSupported(ChronoField.DAY_OF_YEAR)) { System.out.println("Day of year: " + date.get(ChronoField.DAY_OF_YEAR)); } else { System.out.println("Day of year not supported"); } } }
此示例展示了如何正确处理不支持的字段。第一次尝试对不支持的时间字段抛出异常。第二种方法在访问之前安全地检查支持情况。
来源
在本文中,我们介绍了 Java TemporalAccessor 接口的基本方法和特性。理解这些概念对于在现代 Java 应用程序中处理时间对象至关重要。
作者
列出所有Java教程。