Java Temporal 接口
最后修改时间:2025 年 4 月 16 日
java.time.temporal.Temporal
接口是一个框架级接口,用于表示日期时间对象。它提供了对日期时间字段的访问,并允许进行日期时间运算。像 LocalDate 和 ZonedDateTime 这样的类实现了这个接口。
Temporal
定义了查询和操作时间对象的操作。它支持添加或减去时间单位、比较日期以及访问时间字段。该接口支持对不同日期时间类型的多态处理。
Temporal 接口概述
Temporal 接口提供了用于时间算术和字段访问的方法。关键操作包括添加/减去时间、查询字段和调整值。它与 TemporalUnit 和 TemporalField 配合使用,以实现灵活的操作。
public interface Temporal extends TemporalAccessor { boolean isSupported(TemporalUnit unit); Temporal with(TemporalField field, long newValue); Temporal plus(long amountToAdd, TemporalUnit unit); Temporal minus(long amountToSubtract, TemporalUnit unit); long until(Temporal endExclusive, TemporalUnit unit); }
以上代码展示了 Temporal
接口的关键方法。这些方法可以操作时间对象,同时保持不可变性。实现类为这些操作提供了具体行为。
基本的时间操作
此示例演示了通过 Temporal 接口可用的基本操作。我们将使用实现 Temporal 的 LocalDate 来展示常见方法。操作包括添加时间和查询字段。
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.of(2025, 4, 15); // Add 2 weeks Temporal futureDate = date.plus(2, ChronoUnit.WEEKS); System.out.println("Date in 2 weeks: " + futureDate); // Subtract 3 months Temporal pastDate = date.minus(3, ChronoUnit.MONTHS); System.out.println("Date 3 months ago: " + pastDate); // Check if unit is supported boolean supported = date.isSupported(ChronoUnit.DAYS); System.out.println("Days supported: " + supported); } }
此示例展示了使用 LocalDate 的基本 Temporal 操作。plus 和 minus 方法返回新的 Temporal 对象。isSupported 方法检查时间单位是否可与时间对象一起使用。
使用 Temporal 进行字段调整
Temporal 接口允许修改日期时间对象的特定字段。这可以使用 with
方法完成,该方法返回一个新的调整后的对象。字段调整是精确的,并自动处理边缘情况。
package com.zetcode; import java.time.LocalDateTime; import java.time.temporal.ChronoField; public class Main { public static void main(String[] args) { LocalDateTime dateTime = LocalDateTime.now(); System.out.println("Original: " + dateTime); // Change year Temporal newYear = dateTime.with(ChronoField.YEAR, 2030); System.out.println("Year changed: " + newYear); // Change hour Temporal newHour = dateTime.with(ChronoField.HOUR_OF_DAY, 15); System.out.println("Hour changed: " + newHour); // Chain adjustments Temporal adjusted = dateTime .with(ChronoField.MONTH_OF_YEAR, 12) .with(ChronoField.DAY_OF_MONTH, 25); System.out.println("Christmas date: " + adjusted); } }
此示例演示了使用 Temporal 接口的字段调整。每个 with
操作都返回一个新的 Temporal 对象。多个调整可以链接在一起以创建复杂的转换。
计算 Temporal 之间的时间
until
方法以指定的单位计算两个时间对象之间的时间。这对于确定日期或时间之间的持续时间很有用。该方法会自动处理不同的时间类型。
package com.zetcode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; public class Main { public static void main(String[] args) { LocalDate today = LocalDate.now(); LocalDate futureDate = today.plusMonths(3).plusDays(5); // Days between dates long daysBetween = today.until(futureDate, ChronoUnit.DAYS); System.out.println("Days between: " + daysBetween); // Months between dates long monthsBetween = today.until(futureDate, ChronoUnit.MONTHS); System.out.println("Months between: " + monthsBetween); // Mixed types calculation LocalDateTime now = LocalDateTime.now(); LocalDateTime later = now.plusHours(5).plusMinutes(30); long minutesBetween = now.until(later, ChronoUnit.MINUTES); System.out.println("Minutes between: " + minutesBetween); } }
此示例展示了如何计算时间对象之间的时间。until 方法适用于不同的时间类型和单位。请注意,计算是精确的,并遵守日历规则。
Temporal 与 TemporalAdjuster
Temporal 对象可以与 TemporalAdjusters 一起使用,以进行复杂的日期调整。调整器提供了预构建的操作,例如“下个星期二”或“当月最后一天”。这演示了 Temporal 接口的灵活性。
package com.zetcode; import java.time.LocalDate; import java.time.DayOfWeek; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.of(2025, 4, 15); // Next Friday Temporal nextFriday = date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)); System.out.println("Next Friday: " + nextFriday); // Last day of month Temporal monthEnd = date.with(TemporalAdjusters.lastDayOfMonth()); System.out.println("Month end: " + monthEnd); // First day of next year Temporal yearStart = date.with(TemporalAdjusters.firstDayOfNextYear()); System.out.println("Next year start: " + yearStart); // Custom adjuster (add 2 weeks) Temporal custom = date.with(temporal -> temporal.plus(2, ChronoUnit.WEEKS)); System.out.println("Custom adjusted: " + custom); } }
此示例演示了将 TemporalAdjusters 与 Temporal 对象一起使用。调整器通过函数式接口提供常见的日期操作。也可以使用 lambda 表达式创建自定义调整器。
使用 TemporalQueries
Temporal 对象支持查询以提取信息。query 方法允许从时间对象中灵活地提取数据。这对于通用日期时间处理代码很有用。
package com.zetcode; import java.time.LocalDateTime; import java.time.temporal.TemporalQueries; import java.time.temporal.TemporalQuery; public class Main { public static void main(String[] args) { LocalDateTime dateTime = LocalDateTime.now(); // Query for LocalDate TemporalQuery<java.time.LocalDate> dateQuery = TemporalQueries.localDate(); java.time.LocalDate datePart = dateTime.query(dateQuery); System.out.println("Date part: " + datePart); // Query for time precision TemporalQuery<java.time.temporal.ChronoUnit> precisionQuery = TemporalQueries.precision(); java.time.temporal.ChronoUnit precision = dateTime.query(precisionQuery); System.out.println("Precision: " + precision); // Custom query (get day of week) TemporalQuery<String> dayQuery = temporal -> temporal.query(TemporalQueries.localDate()) .getDayOfWeek().toString(); String dayOfWeek = dateTime.query(dayQuery); System.out.println("Day of week: " + dayOfWeek); } }
此示例展示了如何查询时间对象以获取信息。内置查询通过 TemporalQueries 提供,并且可以创建自定义查询。query 方法支持对不同时间类型的多态处理。
组合 Temporal 操作
此示例演示了组合多个 Temporal 操作以进行复杂的日期时间计算。我们将链接操作以创建涉及日期计算的业务逻辑场景。
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { LocalDate projectStart = LocalDate.of(2025, 4, 15); // Calculate project timeline Temporal milestone1 = projectStart .plus(2, ChronoUnit.WEEKS) .with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY)); Temporal milestone2 = ((LocalDate) milestone1) .plus(3, ChronoUnit.WEEKS) .with(TemporalAdjusters.lastDayOfMonth()); Temporal projectEnd = ((LocalDate) milestone2) .plus(1, ChronoUnit.MONTHS) .with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.FRIDAY)); System.out.println("Project start: " + projectStart); System.out.println("Milestone 1: " + milestone1); System.out.println("Milestone 2: " + milestone2); System.out.println("Project end: " + projectEnd); // Calculate total duration long totalDays = projectStart.until(projectEnd, ChronoUnit.DAYS); System.out.println("Total project days: " + totalDays); } }
此示例结合了多个 Temporal 操作来模拟项目时间线。我们使用 plus 操作、调整器和持续时间计算。请注意,当需要 LocalDate 中的特定方法时,需要进行类型转换。
来源
在本文中,我们介绍了 Java Temporal 接口的基本方法和功能。理解这些概念对于在现代 Java 应用程序中处理日期和时间至关重要。
作者
列出所有Java教程。