时间查询

原文: https://docs.oracle.com/javase/tutorial/datetime/iso/queries.html

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

预定义查询

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

例如, 精度 查询返回可由特定基于时间的对象返回的最小ChronoUnit 。以下示例对几种类型的基于时间的对象使用precision查询:

  1. TemporalQueries query = TemporalQueries.precision();
  2. System.out.printf("LocalDate precision is %s%n",
  3. LocalDate.now().query(query));
  4. System.out.printf("LocalDateTime precision is %s%n",
  5. LocalDateTime.now().query(query));
  6. System.out.printf("Year precision is %s%n",
  7. Year.now().query(query));
  8. System.out.printf("YearMonth precision is %s%n",
  9. YearMonth.now().query(query));
  10. System.out.printf("Instant precision is %s%n",
  11. Instant.now().query(query));

输出如下所示:

  1. LocalDate precision is Days
  2. LocalDateTime precision is Nanos
  3. Year precision is Years
  4. YearMonth precision is Months
  5. Instant precision is Nanos

自定义查询

您还可以创建自己的自定义查询。一种方法是使用 queryFrom(TemporalAccessor) 方法创建一个实现TemporalQuery接口的类。 `CheckDate `示例实现了两个自定义查询。第一个自定义查询可以在 `FamilyVacations `类中找到,它实现了 TemporalQuery接口。 queryFrom方法将传入的日期与预定的休假日期进行比较,如果它落在这些日期范围内,则返回TRUE

  1. // Returns true if the passed-in date occurs during one of the
  2. // family vacations. Because the query compares the month and day only,
  3. // the check succeeds even if the Temporal types are not the same.
  4. public Boolean queryFrom(TemporalAccessor date) {
  5. int month = date.get(ChronoField.MONTH_OF_YEAR);
  6. int day = date.get(ChronoField.DAY_OF_MONTH);
  7. // Disneyland over Spring Break
  8. if ((month == Month.APRIL.getValue()) && ((day >= 3) && (day <= 8)))
  9. return Boolean.TRUE;
  10. // Smith family reunion on Lake Saugatuck
  11. if ((month == Month.AUGUST.getValue()) && ((day >= 8) && (day <= 14)))
  12. return Boolean.TRUE;
  13. return Boolean.FALSE;
  14. }

第二个自定义查询在 `FamilyBirthdays `类中实现。这个类提供了isFamilyBirthday方法,它将传入的日期与几个生日进行比较,如果匹配则返回TRUE

  1. // Returns true if the passed-in date is the same as one of the
  2. // family birthdays. Because the query compares the month and day only,
  3. // the check succeeds even if the Temporal types are not the same.
  4. public static Boolean isFamilyBirthday(TemporalAccessor date) {
  5. int month = date.get(ChronoField.MONTH_OF_YEAR);
  6. int day = date.get(ChronoField.DAY_OF_MONTH);
  7. // Angie's birthday is on April 3.
  8. if ((month == Month.APRIL.getValue()) && (day == 3))
  9. return Boolean.TRUE;
  10. // Sue's birthday is on June 18.
  11. if ((month == Month.JUNE.getValue()) && (day == 18))
  12. return Boolean.TRUE;
  13. // Joe's birthday is on May 29.
  14. if ((month == Month.MAY.getValue()) && (day == 29))
  15. return Boolean.TRUE;
  16. return Boolean.FALSE;
  17. }

FamilyBirthday类没有实现TemporalQuery接口,可以用作 lambda 表达式的一部分。以下代码来自CheckDate示例,显示了如何调用两个自定义查询。

  1. // Invoking the query without using a lambda expression.
  2. Boolean isFamilyVacation = date.query(new FamilyVacations());
  3. // Invoking the query using a lambda expression.
  4. Boolean isFamilyBirthday = date.query(FamilyBirthdays::isFamilyBirthday);
  5. if (isFamilyVacation.booleanValue() || isFamilyBirthday.booleanValue())
  6. System.out.printf("%s is an important date!%n", date);
  7. else
  8. System.out.printf("%s is not an important date.%n", date);