Java TemporalAmount 接口
最后修改时间:2025 年 4 月 16 日
java.time.temporal.TemporalAmount
接口表示一段时间。它可用于定义诸如“2 小时”或“5 天”之类的量。此接口由 Duration 和 Period 等类实现。
TemporalAmount
提供了从时间对象中添加或减去时间量的方法。它同时适用于基于日期和基于时间的时间量。该接口是 Java 8 中引入的 Java 现代日期时间 API 的一部分。
TemporalAmount 接口概述
TemporalAmount
接口定义了时间操作的方法。关键实现是 Duration(基于时间)和 Period(基于日期)。该接口支持跨不同时间类型进行灵活的时间计算。
public interface TemporalAmount { long get(TemporalUnit unit); List<TemporalUnit> getUnits(); Temporal addTo(Temporal temporal); Temporal subtractFrom(Temporal temporal); }
上面的代码显示了 TemporalAmount
定义的方法。这些方法允许查询单位、获取值和执行时间算术运算。实现必须处理单位转换和边界条件。
将 Duration 与 TemporalAmount 一起使用
Duration 是 TemporalAmount 的一个基于时间的实现。它表示以秒和纳秒为单位的一段时间。Duration 非常适合精确的时间测量。
package com.zetcode; import java.time.Duration; import java.time.LocalTime; public class Main { public static void main(String[] args) { Duration duration = Duration.ofHours(2).plusMinutes(30); // Get units System.out.println("Units: " + duration.getUnits()); // Get value in seconds System.out.println("Seconds: " + duration.getSeconds()); // Add to temporal object LocalTime time = LocalTime.of(10, 0); LocalTime newTime = (LocalTime) duration.addTo(time); System.out.println("New time: " + newTime); // Subtract from temporal object LocalTime earlierTime = (LocalTime) duration.subtractFrom(time); System.out.println("Earlier time: " + earlierTime); } }
此示例演示了将 Duration 用作 TemporalAmount。我们创建一个 2.5 小时的持续时间,然后将其添加到 LocalTime 并从中减去。getUnits() 方法显示持续时间包含哪些时间单位。
将 Period 与 TemporalAmount 一起使用
Period 是 TemporalAmount 的一个基于日期的实现。它表示以年、月和天为单位的一段时间。Period 适用于基于日历的日期计算。
package com.zetcode; import java.time.LocalDate; import java.time.Period; public class Main { public static void main(String[] args) { Period period = Period.ofYears(1).plusMonths(2).plusDays(3); // Get units System.out.println("Units: " + period.getUnits()); // Get values System.out.println("Years: " + period.getYears()); System.out.println("Months: " + period.getMonths()); System.out.println("Days: " + period.getDays()); // Add to temporal object LocalDate date = LocalDate.of(2025, 1, 1); LocalDate newDate = (LocalDate) period.addTo(date); System.out.println("New date: " + newDate); } }
此示例显示了 Period 被用作 TemporalAmount。我们创建一个 1 年 2 个月 3 天的 Period,然后将其添加到 LocalDate。Period 自动处理日历感知日期算术。
自定义 TemporalAmount 实现
我们可以创建 TemporalAmount 的自定义实现,用于专门的时间计算。此示例显示了一个简单的实现,仅代表工作日。
package com.zetcode; import java.time.LocalDate; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalUnit; import java.util.Collections; import java.util.List; public class Main { static class BusinessDays implements TemporalAmount { private final long days; public BusinessDays(long days) { this.days = days; } @Override public Temporal addTo(Temporal temporal) { LocalDate date = LocalDate.from(temporal); long added = 0; while (added < days) { date = date.plus(1, ChronoUnit.DAYS); if (date.getDayOfWeek().getValue() < 6) { added++; } } return temporal.with(date); } @Override public Temporal subtractFrom(Temporal temporal) { return addTo(temporal).minus(days * 2, ChronoUnit.DAYS); } @Override public long get(TemporalUnit unit) { if (unit == ChronoUnit.DAYS) { return days; } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } @Override public ListgetUnits() { return Collections.singletonList(ChronoUnit.DAYS); } } public static void main(String[] args) { BusinessDays businessDays = new BusinessDays(5); LocalDate startDate = LocalDate.of(2025, 4, 1); // Tuesday LocalDate endDate = (LocalDate) businessDays.addTo(startDate); System.out.println("Start date: " + startDate); System.out.println("End date (5 business days later): " + endDate); } }
此示例演示了一个自定义 TemporalAmount,它跳过周末。BusinessDays 类在执行日期算术时仅添加工作日。这展示了如何为业务应用程序创建专门的时间计算。
组合 TemporalAmount 实现
我们可以组合不同的 TemporalAmount 实现以进行复杂的时间计算。此示例混合了 Period 和 Duration 以获得完整的时间跨度。
package com.zetcode; import java.time.Duration; import java.time.LocalDateTime; import java.time.Period; import java.time.temporal.TemporalAmount; public class Main { public static void main(String[] args) { // Date-based amount Period period = Period.of(1, 2, 3); // 1 year, 2 months, 3 days // Time-based amount Duration duration = Duration.ofHours(4).plusMinutes(30); LocalDateTime dateTime = LocalDateTime.of(2025, 1, 1, 10, 0); System.out.println("Original: " + dateTime); // Apply period first (date-based) LocalDateTime afterPeriod = (LocalDateTime) period.addTo(dateTime); System.out.println("After period: " + afterPeriod); // Then apply duration (time-based) LocalDateTime afterBoth = (LocalDateTime) duration.addTo(afterPeriod); System.out.println("After both: " + afterBoth); // Combined operation LocalDateTime combined = dateTime .plus(period) .plus(duration); System.out.println("Combined result: " + combined); } }
此示例显示了如何组合 Period 和 Duration 操作。我们首先添加一个 Period(基于日期),然后添加一个 Duration(基于时间)到 LocalDateTime。结果演示了使用多个 TemporalAmounts 的复杂时间算术运算。
查询 TemporalAmount 值
TemporalAmount 接口提供了查询其组成值的方法。此示例显示了如何检查不同时间量的单位和值。
package com.zetcode; import java.time.Duration; import java.time.Period; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalUnit; public class Main { public static void main(String[] args) { TemporalAmount[] amounts = { Period.of(1, 2, 3), Duration.ofHours(2).plusMinutes(30), Duration.ofDays(1).plusHours(6) }; for (TemporalAmount amount : amounts) { System.out.println("\nAmount: " + amount); System.out.println("Units: " + amount.getUnits()); for (TemporalUnit unit : amount.getUnits()) { System.out.println(unit + ": " + amount.get(unit)); } } // Custom query for specific unit Duration duration = Duration.ofMinutes(90); long hours = duration.get(ChronoUnit.HOURS); long minutes = duration.get(ChronoUnit.MINUTES); System.out.println("\n90 minutes = " + hours + " hours " + (minutes - hours * 60) + " minutes"); } }
此示例演示了如何查询 TemporalAmount 对象的组成部分。我们检查 Period 和 Duration 实例,显示它们的单位和值。get() 方法允许从量中访问特定的单位值。
将 TemporalAmount 与 TemporalAdjuster 一起使用
TemporalAmount 可与 TemporalAdjuster 一起使用,以进行更复杂的日期操作。此示例显示了组合这些接口以进行灵活的日期计算。
package com.zetcode; import java.time.LocalDate; import java.time.Period; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAmount; public class Main { static class NextBusinessDayAdjuster implements TemporalAdjuster { private final TemporalAmount amount; public NextBusinessDayAdjuster(TemporalAmount amount) { this.amount = amount; } @Override public Temporal adjustInto(Temporal temporal) { Temporal adjusted = amount.addTo(temporal); LocalDate date = LocalDate.from(adjusted); // Adjust to next business day if needed while (date.getDayOfWeek().getValue() >= 6) { date = date.plusDays(1); } return temporal.with(date); } } public static void main(String[] args) { TemporalAmount twoDays = Period.ofDays(2); TemporalAdjuster adjuster = new NextBusinessDayAdjuster(twoDays); LocalDate friday = LocalDate.of(2025, 4, 4); // Friday LocalDate nextBusinessDay = friday.with(adjuster); System.out.println("Friday: " + friday); System.out.println("Two business days later: " + nextBusinessDay); // Using with Period Period period = Period.ofWeeks(1); LocalDate inOneWeek = friday.with(new NextBusinessDayAdjuster(period)); System.out.println("One business week later: " + inOneWeek); } }
此示例将 TemporalAmount 与 TemporalAdjuster 结合使用,以创建业务日感知的日期计算。调整器确保结果落在工作日,即使添加标准时间量也是如此。这展示了强大的时间操作。
来源
在本文中,我们介绍了 Java TemporalAmount 接口的基本方法和特性。理解这些概念对于在现代 Java 应用程序中灵活地处理时间至关重要。
作者
列出所有Java教程。