Temporal Query

TemporalQuery可用于从基于时间的对象中检索信息。

Predefined Queries

TemporalQueries类(请注意复数)提供了几个 预定义的查询,包括当应用程序无法识别基于时间的对象的类型时有用的方法。与调节器一样,预定义的查询被定义为静态方法,并设计为与static import语句一起使用。

例如,precision查询返回的最小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

Custom Queries

您也可以创建自己的自定义查询。一种实现方法是创建一个使用queryFrom(TemporalAccessor)方法实现TemporalQueryinterface的类。 CheckDate示例实现了两个自定义查询。可以在实现TemporalQueryinterface的FamilyVacations类中找到第一个自定义查询。 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类未实现TemporalQueryinterface,可以用作lambda expression的一部分。 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);