时间查询
原文: https://docs.oracle.com/javase/tutorial/datetime/iso/queries.html
TemporalQuery
可用于从基于时间的对象中检索信息。
预定义查询
TemporalQueries
类(注意复数)提供了几个预定义查询,包括当应用程序无法识别基于时间的对象的类型时有用的方法。与调整器一样,预定义查询被定义为静态方法,旨在与静态导入语句一起使用。
例如, 精度
查询返回可由特定基于时间的对象返回的最小ChronoUnit
。以下示例对几种类型的基于时间的对象使用precision
查询:
TemporalQueries query = TemporalQueries.precision();
System.out.printf("LocalDate precision is %s%n",
LocalDate.now().query(query));
System.out.printf("LocalDateTime precision is %s%n",
LocalDateTime.now().query(query));
System.out.printf("Year precision is %s%n",
Year.now().query(query));
System.out.printf("YearMonth precision is %s%n",
YearMonth.now().query(query));
System.out.printf("Instant precision is %s%n",
Instant.now().query(query));
输出如下所示:
LocalDate precision is Days
LocalDateTime precision is Nanos
Year precision is Years
YearMonth precision is Months
Instant precision is Nanos
自定义查询
您还可以创建自己的自定义查询。一种方法是使用 queryFrom(TemporalAccessor)
方法创建一个实现TemporalQuery
接口的类。 `CheckDate
`示例实现了两个自定义查询。第一个自定义查询可以在 `FamilyVacations
`类中找到,它实现了 TemporalQuery
接口。 queryFrom
方法将传入的日期与预定的休假日期进行比较,如果它落在这些日期范围内,则返回TRUE
。
// Returns true if the passed-in date occurs during one of the
// family vacations. Because the query compares the month and day only,
// the check succeeds even if the Temporal types are not the same.
public Boolean queryFrom(TemporalAccessor date) {
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);
// Disneyland over Spring Break
if ((month == Month.APRIL.getValue()) && ((day >= 3) && (day <= 8)))
return Boolean.TRUE;
// Smith family reunion on Lake Saugatuck
if ((month == Month.AUGUST.getValue()) && ((day >= 8) && (day <= 14)))
return Boolean.TRUE;
return Boolean.FALSE;
}
第二个自定义查询在 `FamilyBirthdays
`类中实现。这个类提供了isFamilyBirthday
方法,它将传入的日期与几个生日进行比较,如果匹配则返回TRUE
。
// Returns true if the passed-in date is the same as one of the
// family birthdays. Because the query compares the month and day only,
// the check succeeds even if the Temporal types are not the same.
public static Boolean isFamilyBirthday(TemporalAccessor date) {
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);
// Angie's birthday is on April 3.
if ((month == Month.APRIL.getValue()) && (day == 3))
return Boolean.TRUE;
// Sue's birthday is on June 18.
if ((month == Month.JUNE.getValue()) && (day == 18))
return Boolean.TRUE;
// Joe's birthday is on May 29.
if ((month == Month.MAY.getValue()) && (day == 29))
return Boolean.TRUE;
return Boolean.FALSE;
}
FamilyBirthday
类没有实现TemporalQuery
接口,可以用作 lambda 表达式的一部分。以下代码来自CheckDate
示例,显示了如何调用两个自定义查询。
// Invoking the query without using a lambda expression.
Boolean isFamilyVacation = date.query(new FamilyVacations());
// Invoking the query using a lambda expression.
Boolean isFamilyBirthday = date.query(FamilyBirthdays::isFamilyBirthday);
if (isFamilyVacation.booleanValue() || isFamilyBirthday.booleanValue())
System.out.printf("%s is an important date!%n", date);
else
System.out.printf("%s is not an important date.%n", date);