Java TemporalQuery 接口
最后修改时间:2025 年 4 月 16 日
java.time.temporal.TemporalQuery 接口提供了一种查询时间对象以获取信息的方法。 它表示一个从时间对象(如 LocalDate 或 ZonedDateTime)中提取信息的函数。
TemporalQuery 是一个函数式接口,具有单个抽象方法 queryFrom。 它在整个 Java 时间 API 中用于灵活的时间查询。 该接口实现了类型安全的时间操作。
TemporalQuery 接口概述
TemporalQuery 接口定义了一个方法,该方法接受一个 TemporalAccessor 并返回一个结果。 结果类型由查询实现决定。 查询可以提取任何时间信息。
@FunctionalInterface
public interface TemporalQuery<R> {
R queryFrom(TemporalAccessor temporal);
}
上面的代码展示了 TemporalQuery 接口的简单结构。 泛型类型参数 R 指定返回类型。 实现可以查询时间对象的任何方面。
基本 TemporalQuery 示例
此示例演示了创建一个简单的 TemporalQuery,它从时间对象中提取星期几。 查询实现为一个 lambda 表达式。
package com.zetcode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalQuery;
public class Main {
public static void main(String[] args) {
TemporalQuery<DayOfWeek> dayOfWeekQuery = temporal ->
DayOfWeek.from(temporal);
LocalDate date = LocalDate.of(2025, 4, 16);
DayOfWeek day = date.query(dayOfWeekQuery);
System.out.println("Day of week: " + day);
}
}
此示例创建一个查询,从任何支持此信息的时间对象中提取星期几。 query 方法将查询应用于时间对象。 结果将打印到控制台。
查询特定信息
此示例展示了如何创建一个查询来检查日期是否为周末。 查询返回一个布尔值,指示日期是否为星期六或星期日。
package com.zetcode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalQuery;
public class Main {
public static void main(String[] args) {
TemporalQuery<Boolean> isWeekendQuery = temporal -> {
DayOfWeek day = DayOfWeek.from(temporal);
return day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY;
};
LocalDate weekday = LocalDate.of(2025, 4, 16);
LocalDate weekend = LocalDate.of(2025, 4, 19);
System.out.println("Is weekday weekend? " + weekday.query(isWeekendQuery));
System.out.println("Is weekend day weekend? " + weekend.query(isWeekendQuery));
}
}
该示例定义了一个查询,用于检查周末日期。 查询提取星期几,如果它是星期六或星期日,则返回 true。 测试了两个日期以演示查询的功能。
使用预定义的 TemporalQueries
Java 时间 API 在 TemporalQueries 类中提供了几个预定义的查询。 这些查询可以直接使用,无需创建自定义实现。
package com.zetcode;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
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 local time
LocalTime time = zdt.query(TemporalQueries.localTime());
System.out.println("Local time: " + time);
// Query for zone
ZoneId zone = zdt.query(TemporalQueries.zone());
System.out.println("Zone: " + zone);
// Query for precision
System.out.println("Precision: " + zdt.query(TemporalQueries.precision()));
}
}
此示例演示了如何使用来自 TemporalQueries 的预定义查询。 查询提取 ZonedDateTime 对象的不同方面。 每个查询返回特定类型的时间信息。
链接 TemporalQueries
Temporal 查询可以链接在一起以执行复杂的时间操作。 此示例展示了如何组合多个查询以提取特定信息。
package com.zetcode;
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.TemporalQuery;
public class Main {
public static void main(String[] args) {
TemporalQuery<Boolean> isSummerQuery = temporal -> {
LocalDate date = LocalDate.from(temporal);
return date.getMonth() == Month.JUNE
|| date.getMonth() == Month.JULY
|| date.getMonth() == Month.AUGUST;
};
TemporalQuery<Boolean> isWeekendInSummerQuery = temporal -> {
boolean isSummer = temporal.query(isSummerQuery);
boolean isWeekend = temporal.query(t -> {
var day = java.time.DayOfWeek.from(t);
return day == java.time.DayOfWeek.SATURDAY
|| day == java.time.DayOfWeek.SUNDAY;
});
return isSummer && isWeekend;
};
LocalDate summerWeekend = LocalDate.of(2025, 7, 19);
LocalDate winterWeekend = LocalDate.of(2025, 1, 18);
System.out.println("Is summer weekend? " +
summerWeekend.query(isWeekendInSummerQuery));
System.out.println("Is winter weekend? " +
winterWeekend.query(isWeekendInSummerQuery));
}
}
此示例创建一个复杂查询,用于检查日期是否是周末并且在夏季。 查询组合了两个更简单的查询来实现此目的。 结果演示了如何组合查询以获得更复杂的条件。
查询自定义业务逻辑
Temporal 查询可以封装有关日期和时间的业务规则。 此示例显示了一个查询,该查询检查日期时间是否在营业时间内。
package com.zetcode;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalQuery;
public class Main {
public static void main(String[] args) {
TemporalQuery<Boolean> isBusinessHoursQuery = temporal -> {
ZonedDateTime zdt = ZonedDateTime.from(temporal);
LocalTime time = zdt.toLocalTime();
DayOfWeek day = zdt.getDayOfWeek();
// Business hours: 9AM-5PM, Monday-Friday
return !(day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY)
&& time.isAfter(LocalTime.of(8, 59))
&& time.isBefore(LocalTime.of(17, 1));
};
ZonedDateTime businessTime = ZonedDateTime.of(
2025, 4, 16, 10, 30, 0, 0, ZoneId.of("America/New_York"));
ZonedDateTime nonBusinessTime = ZonedDateTime.of(
2025, 4, 19, 11, 0, 0, 0, ZoneId.of("America/New_York"));
System.out.println("Is business time? " +
businessTime.query(isBusinessHoursQuery));
System.out.println("Is non-business time? " +
nonBusinessTime.query(isBusinessHoursQuery));
}
}
此示例在时间查询中实现了有关工作时间的业务逻辑。 查询检查星期几和一天中的时间。 结果演示了查询如何根据定义的规则正确识别营业时间。
使用方法引用作为 TemporalQueries
方法引用可以用作 TemporalQuery 的简洁实现。 此示例展示了如何使用现有方法作为时间对象的查询。
package com.zetcode;
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.TemporalQueries;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2025, 4, 16);
// Using method references as queries
Month month = date.query(LocalDate::getMonth);
int year = date.query(LocalDate::getYear);
int day = date.query(LocalDate::getDayOfMonth);
System.out.println("Year: " + year);
System.out.println("Month: " + month);
System.out.println("Day: " + day);
// Alternative using predefined queries
System.out.println("Month (predefined): " +
date.query(TemporalQueries.localDate()).getMonth());
}
}
此示例演示了如何使用方法引用作为时间查询。 query 方法接受与 TemporalQuery 函数式接口匹配的方法引用。 该示例显示了直接方法引用和预定义查询进行比较。
将 TemporalQuery 与 TemporalAdjuster 结合使用
Temporal 查询可以与调整器结合使用,以创建强大的时间操作。 此示例查找给定日期后的下一个工作日。
package com.zetcode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalQuery;
public class Main {
public static void main(String[] args) {
TemporalQuery<Boolean> isBusinessDayQuery = temporal -> {
DayOfWeek day = DayOfWeek.from(temporal);
return day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY;
};
TemporalAdjuster nextBusinessDay = temporal -> {
LocalDate date = LocalDate.from(temporal);
do {
date = date.plusDays(1);
} while (!date.query(isBusinessDayQuery));
return date;
};
LocalDate friday = LocalDate.of(2025, 4, 18);
LocalDate nextBusiness = friday.with(nextBusinessDay);
System.out.println("Friday: " + friday);
System.out.println("Next business day: " + nextBusiness);
}
}
此示例将时间查询与时间调整器相结合。 查询标识工作日,调整器查找下一个工作日。 结果演示了跳过周末以找到下一个工作日。
来源
在本文中,我们介绍了 Java TemporalQuery 接口的基本方法和功能。 了解这些概念对于现代 Java 应用程序中的灵活时间操作至关重要。
作者
列出所有Java教程。