Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
有关Java SE 9及其后续版本中更新的语言功能的摘要,请参阅Java语言变更。
有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息,请参阅JDK发行说明。
一个TemporalQuery可以用来从基于时间的对象中检索信息。
TemporalQueries类(注意复数形式)提供了几个预定义的查询,包括在应用程序无法确定基于时间的对象的类型时有用的方法。与调整器一样,预定义查询被定义为静态方法,并且设计用于与static import语句一起使用。
例如,precision查询返回特定基于时间的对象可以返回的最小ChronoUnit。以下示例在几种类型的基于时间的对象上使用precision查询:
TemporalQuery<TemporalUnit> query = TemporalQueries.precision(); System.out.printf("LocalDate的精度为%s%n", LocalDate.now().query(query)); System.out.printf("LocalDateTime的精度为%s%n", LocalDateTime.now().query(query)); System.out.printf("Year的精度为%s%n", Year.now().query(query)); System.out.printf("YearMonth的精度为%s%n", YearMonth.now().query(query)); System.out.printf("Instant的精度为%s%n", Instant.now().query(query));
输出结果如下:
LocalDate的精度为Days LocalDateTime的精度为Nanos Year的精度为Years YearMonth的精度为Months Instant的精度为Nanos
您还可以创建自己的自定义查询。一种方法是创建一个实现TemporalQuery接口并具有queryFrom(TemporalAccessor)方法的类。示例CheckDate实现了两个自定义查询。第一个自定义查询可以在FamilyVacations
类中找到,该类实现了TemporalQuery接口。queryFrom方法将传入的日期与计划的假期日期进行比较,如果日期在这些日期范围内,则返回TRUE。
// 如果传入的日期是家庭度假的日期之一,则返回true。因为查询只比较月份和日期,即使Temporal类型不同,检查也会成功。 public Boolean queryFrom(TemporalAccessor date) { int month = date.get(ChronoField.MONTH_OF_YEAR); int day = date.get(ChronoField.DAY_OF_MONTH); // 春假在迪士尼乐园 if ((month == Month.APRIL.getValue()) && ((day >= 3) && (day <= 8))) return Boolean.TRUE; // 史密斯家族重聚在萨各托克湖 if ((month == Month.AUGUST.getValue()) && ((day >= 8) && (day <= 14))) return Boolean.TRUE; return Boolean.FALSE; }
第二个自定义查询实现在FamilyBirthdays
类中。该类提供了一个isFamilyBirthday方法,用于将传入的日期与几个生日进行比较,并返回TRUE如果有匹配。
// 如果传入的日期与家庭生日之一相同,则返回true。因为查询只比较月份和日期,即使Temporal类型不同,检查也会成功。 public static Boolean isFamilyBirthday(TemporalAccessor date) { int month = date.get(ChronoField.MONTH_OF_YEAR); int day = date.get(ChronoField.DAY_OF_MONTH); // 安吉的生日是4月3日。 if ((month == Month.APRIL.getValue()) && (day == 3)) return Boolean.TRUE; // 苏的生日是6月18日。 if ((month == Month.JUNE.getValue()) && (day == 18)) return Boolean.TRUE; // 乔的生日是5月29日。 if ((month == Month.MAY.getValue()) && (day == 29)) return Boolean.TRUE; return Boolean.FALSE; }
FamilyBirthday类没有实现TemporalQuery接口,并且可以作为lambda表达式的一部分使用。以下代码来自CheckDate示例,展示了如何调用这两个自定义查询。
// 不使用lambda表达式调用查询。 Boolean isFamilyVacation = date.query(new FamilyVacations()); // 使用lambda表达式调用查询。 Boolean isFamilyBirthday = date.query(FamilyBirthdays::isFamilyBirthday); if (isFamilyVacation.booleanValue() || isFamilyBirthday.booleanValue()) System.out.printf("%s是一个重要的日期!%n", date); else System.out.printf("%s不是一个重要的日期。%n", date);