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教程。