Java Period 类
最后修改时间:2025 年 4 月 16 日
java.time.Period
类表示基于日期的时长,以年、月和日为单位。它模拟了以日历字段表示的时间量或时长。 Period 用于修改或计算日期之间的差异。
Period
是不可变的且线程安全的。它通常用于基于日期的计算,例如向日期添加月份或查找年龄。该类自动处理夏令时和其他日历不规则性。
Period 类概述
Period
提供了创建 Period、解析字符串和执行计算的方法。关键操作包括添加到日期、比较 Period 和提取组件。该类分别处理年、月和日。
public final class Period implements ChronoPeriod, Serializable { public static Period of(int years, int months, int days); public static Period ofYears(int years); public static Period ofMonths(int months); public static Period ofDays(int days); public static Period between(LocalDate start, LocalDate end); public static Period parse(CharSequence text); public int getYears(); public int getMonths(); public int getDays(); public boolean isZero(); public boolean isNegative(); public Period plus(Period amountToAdd); public Period minus(Period amountToSubtract); public Period normalized(); }
上面的代码显示了 Period
提供的关键方法。这些方法允许创建、比较和操作 Period。该类处理基于日期的计算,同时考虑了不同的月份长度和闰年。
创建 Period 对象
Period 对象可以通过几种方式创建。最常见的方法是用于特定持续时间的工厂方法和从字符串解析。 between
方法计算日期之间的 Period。
package com.zetcode; import java.time.Period; import java.time.LocalDate; public class Main { public static void main(String[] args) { // Using factory methods Period oneYear = Period.ofYears(1); System.out.println("One year: " + oneYear); Period twoMonths = Period.ofMonths(2); System.out.println("Two months: " + twoMonths); Period threeDays = Period.ofDays(3); System.out.println("Three days: " + threeDays); // Combined period Period complex = Period.of(1, 2, 3); System.out.println("1 year, 2 months, 3 days: " + complex); // From dates LocalDate start = LocalDate.of(2025, 1, 1); LocalDate end = LocalDate.of(2026, 3, 15); Period between = Period.between(start, end); System.out.println("Between dates: " + between); // From string Period parsed = Period.parse("P1Y2M3D"); System.out.println("Parsed from string: " + parsed); } }
此示例演示了创建 Period 对象的不同方法。输出以 ISO-8601 格式 (P1Y2M3D) 显示 Period。 between
方法计算两个日期之间的确切 Period。
获取 Period 组件
一个 Period 可以分解为它的年、月和日组件。这些值表示 Period 的各个部分。这些方法对于显示或进一步计算特定组件非常有用。
package com.zetcode; import java.time.Period; public class Main { public static void main(String[] args) { Period period = Period.of(2, 5, 10); // Get individual components int years = period.getYears(); int months = period.getMonths(); int days = period.getDays(); System.out.println("Years: " + years); System.out.println("Months: " + months); System.out.println("Days: " + days); // Check if zero or negative System.out.println("Is zero: " + period.isZero()); System.out.println("Is negative: " + period.isNegative()); // Normalized form Period normalized = period.normalized(); System.out.println("Normalized: " + normalized); } }
此示例演示了如何从 Period 中提取组件。 normalized
方法通过将多余的月份转换为年,确保月份在 0-11 之间。负的 Period 表示时间向后移动。
加减 Period
可以使用 plus
和 minus
方法将 Period 添加到日期或从日期中减去。这些操作考虑了不同的月份长度和闰年。计算是日历感知的。
package com.zetcode; import java.time.Period; import java.time.LocalDate; public class Main { public static void main(String[] args) { LocalDate date = LocalDate.of(2025, 1, 15); Period period = Period.of(1, 2, 3); // Add period to date LocalDate future = date.plus(period); System.out.println("Future date: " + future); // Subtract period from date LocalDate past = date.minus(period); System.out.println("Past date: " + past); // Add periods together Period another = Period.of(0, 3, 10); Period combined = period.plus(another); System.out.println("Combined period: " + combined); // Subtract periods Period difference = period.minus(another); System.out.println("Difference: " + difference); } }
此示例演示了使用 Period 执行算术的各种方法。当添加到日期时,Period 会自动处理月份长度变化。 Period 算术分别保留每个组件。
比较 Period
可以比较 Period 是否相等或检查其零/负值。请注意,比较方法不会在组件之间进行转换(1 个月 ≠ 30 天)。该类提供了用于基本 Period 分析的方法。
package com.zetcode; import java.time.Period; public class Main { public static void main(String[] args) { Period period1 = Period.of(1, 2, 3); Period period2 = Period.of(0, 14, 3); Period period3 = Period.of(1, 2, 3); // Equality checks System.out.println("Period1 equals period2: " + period1.equals(period2)); System.out.println("Period1 equals period3: " + period1.equals(period3)); // Zero and negative checks System.out.println("Period1 is zero: " + period1.isZero()); System.out.println("Period1 is negative: " + period1.isNegative()); // Normalized comparison System.out.println("Normalized equals: " + period1.normalized().equals(period2.normalized())); } }
此示例显示了比较 Period 对象的各种方法。请注意,除非进行规范化,否则 14 个月不被认为等于 1 年零 2 个月。负的 Period 表示时间向后移动。
计算年龄
Period 的一个常见用途是计算年龄或日期之间的时间跨度。 between
方法以年、月和日为单位提供精确的计算。这对于生日计算非常有用。
package com.zetcode; import java.time.Period; import java.time.LocalDate; import java.time.Month; public class Main { public static void main(String[] args) { LocalDate birthDate = LocalDate.of(1990, Month.MAY, 15); LocalDate currentDate = LocalDate.now(); // Calculate age Period age = Period.between(birthDate, currentDate); System.out.printf("Age: %d years, %d months, %d days%n", age.getYears(), age.getMonths(), age.getDays()); // Future date calculation LocalDate futureDate = currentDate.plus(Period.ofYears(5)); Period untilFuture = Period.between(currentDate, futureDate); System.out.println("Until future date: " + untilFuture); // Specific event calculation LocalDate eventDate = LocalDate.of(2025, Month.DECEMBER, 25); Period untilEvent = Period.between(currentDate, eventDate); System.out.println("Until event: " + untilEvent); } }
此示例演示了计算年龄和日期之间的时间跨度。 between
方法提供了精确的结果,考虑了闰年和不同的月份长度。输出显示了人类可读的时长。
Period 解析和格式化
Period 支持 ISO-8601 格式进行解析,并且可以转换为字符串。格式为 PnYnMnD,其中 n 是年、月或日的数量。这对于序列化和配置很有用。
package com.zetcode; import java.time.Period; public class Main { public static void main(String[] args) { // Parsing ISO-8601 format Period p1 = Period.parse("P1Y"); System.out.println("1 year: " + p1); Period p2 = Period.parse("P2M"); System.out.println("2 months: " + p2); Period p3 = Period.parse("P3D"); System.out.println("3 days: " + p3); Period p4 = Period.parse("P1Y2M3D"); System.out.println("1Y2M3D: " + p4); Period p5 = Period.parse("P-1Y2M"); System.out.println("Negative 1Y2M: " + p5); // Converting to string String periodStr = p4.toString(); System.out.println("As string: " + periodStr); } }
此示例显示了从字符串解析 Period 并将其转换回来的过程。 ISO-8601 格式是严格的 - 组件必须按顺序排列(年、月、日)。每个组件都支持负值。
来源
在本文中,我们介绍了 Java Period 类的基本方法和特性。理解这些概念对于在 Java 应用程序中进行准确的基于日期的计算至关重要。
作者
列出所有Java教程。