ZetCode

Java ChronoPeriod 接口

最后修改时间:2025 年 4 月 16 日

java.time.chrono.ChronoPeriod 接口表示 ISO-8601 日历系统中基于日期的时间量。它将一段时间建模为年、月和日的组合。ChronoPeriod 用于基于日期的计算。

ChronoPeriod 是不可变的和线程安全的。它与 ChronoLocalDate 实现一起工作。该接口提供了从日期添加或减去周期的方法。它支持不同的日历系统。

ChronoPeriod 接口概述

ChronoPeriod 扩展了 TemporalAmount 并提供了获取周期组件的方法。关键操作包括添加到日期、比较周期和转换为其他格式。该接口处理以年、月和日为单位的周期。

public interface ChronoPeriod extends TemporalAmount {
    long get(TemporalUnit unit);
    List<TemporalUnit> getUnits();
    ChronoPeriod plus(TemporalAmount amountToAdd);
    ChronoPeriod minus(TemporalAmount amountToSubtract);
    ChronoPeriod multipliedBy(int scalar);
    ChronoPeriod negated();
    ChronoPeriod normalized();
    boolean isZero();
    boolean isNegative();
    Chronology getChronology();
}

上面的代码显示了 ChronoPeriod 提供的关键方法。这些方法允许创建、比较和操作周期。该接口支持不同日历系统的操作。

创建 ChronoPeriod 对象

ChronoPeriod 对象通常使用 Period 类的工厂方法创建。 between 方法计算两个日期之间的周期。也支持从字符串解析。

Main.java
package com.zetcode;

import java.time.LocalDate;
import java.time.Period;
import java.time.chrono.ChronoPeriod;

public class Main {

    public static void main(String[] args) {
        
        // Create from factory method
        ChronoPeriod period1 = Period.of(2, 3, 10);
        System.out.println("Period 1: " + period1);
        
        // Calculate between dates
        LocalDate start = LocalDate.of(2020, 1, 1);
        LocalDate end = LocalDate.of(2025, 4, 15);
        ChronoPeriod period2 = Period.between(start, end);
        System.out.println("Period between dates: " + period2);
        
        // Parse from string
        ChronoPeriod period3 = Period.parse("P1Y2M15D");
        System.out.println("Parsed period: " + period3);
    }
}

此示例演示了创建 ChronoPeriod 对象的不同方法。输出显示人类可读格式的周期。 between 方法计算两个日期之间的确切周期。

获取周期组件

ChronoPeriod 可以分解为年、月和日组件。这些值表示每个单位的时间量。这些方法对于显示或处理周期信息很有用。

Main.java
package com.zetcode;

import java.time.Period;
import java.time.chrono.ChronoPeriod;

public class Main {

    public static void main(String[] args) {

        ChronoPeriod period = Period.of(3, 8, 25);
        
        // Get individual components
        System.out.println("Years: " + period.getYears());
        System.out.println("Months: " + period.getMonths());
        System.out.println("Days: " + period.getDays());
        
        // Get using TemporalUnit
        System.out.println("Total months: " + 
            period.get(java.time.temporal.ChronoUnit.MONTHS));
    }
}

此示例展示了如何从 ChronoPeriod 中提取组件。带有 TemporalUnitget 方法提供了对周期组件的灵活访问。请注意,月份和年份没有标准化。

添加和减去周期

ChronoPeriod 通过 plusminus 方法支持时间算术。这些操作对于计算未来或过去的周期很有用。这些操作维护单独的年、月、日组件。

Main.java
package com.zetcode;

import java.time.Period;
import java.time.chrono.ChronoPeriod;

public class Main {

    public static void main(String[] args) {

        ChronoPeriod period1 = Period.of(1, 2, 15);
        ChronoPeriod period2 = Period.of(0, 5, 10);
        
        // Add periods
        ChronoPeriod added = period1.plus(period2);
        System.out.println("Added periods: " + added);
        
        // Subtract periods
        ChronoPeriod subtracted = period1.minus(period2);
        System.out.println("Subtracted periods: " + subtracted);
        
        // Add to date
        java.time.LocalDate date = java.time.LocalDate.now();
        System.out.println("Date plus period: " + date.plus(period1));
    }
}

此示例显示了使用 ChronoPeriod 执行算术运算的各种方法。操作可以组合周期或将它们应用于日期。请注意,组件是单独添加的,没有标准化。

乘法和取反周期

ChronoPeriod 提供了 multipliedBynegated 方法来缩放周期。这些操作对于重复模式或反转周期方向很有用。

Main.java
package com.zetcode;

import java.time.Period;
import java.time.chrono.ChronoPeriod;

public class Main {

    public static void main(String[] args) {

        ChronoPeriod period = Period.of(1, 3, 10);
        
        // Multiply period
        ChronoPeriod multiplied = period.multipliedBy(3);
        System.out.println("Multiplied period: " + multiplied);
        
        // Negate period
        ChronoPeriod negated = period.negated();
        System.out.println("Negated period: " + negated);
        
        // Normalize period
        ChronoPeriod normalized = Period.of(0, 15, 40).normalized();
        System.out.println("Normalized period: " + normalized);
    }
}

此示例演示了使用 ChronoPeriod 的缩放操作。 normalized 方法将多余的月份转换为年份。 请注意,在标准化期间,天数不会转换为月份。

比较周期

ChronoPeriod 可以使用 isZeroisNegative 和相等性检查进行比较。这些比较对于验证周期或检查空周期至关重要。

Main.java
package com.zetcode;

import java.time.Period;
import java.time.chrono.ChronoPeriod;

public class Main {

    public static void main(String[] args) {

        ChronoPeriod period1 = Period.of(0, 0, 0);
        ChronoPeriod period2 = Period.of(1, -2, 5);
        ChronoPeriod period3 = Period.of(1, 2, 5);
        
        System.out.println("Is period1 zero: " + period1.isZero());
        System.out.println("Is period2 negative: " + period2.isNegative());
        System.out.println("Are periods equal: " + period2.negated().equals(period3));
    }
}

此示例演示了比较 ChronoPeriod 对象的各种方法。 比较方法检查单个组件。 请注意,相等性需要所有组件的完全匹配。

使用不同的年表

ChronoPeriod 通过其 getChronology 方法支持不同的日历系统。这允许使用非 ISO 日历,例如日本或泰国佛教日历。

Main.java
package com.zetcode;

import java.time.chrono.HijrahChronology;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.ChronoPeriod;
import java.time.Period;

public class Main {

    public static void main(String[] args) {

        ChronoPeriod isoPeriod = Period.of(1, 2, 15);
        System.out.println("ISO chronology: " + isoPeriod.getChronology());
        
        // Create period with different chronology
        ChronoPeriod hijrahPeriod = HijrahChronology.INSTANCE.period(1, 2, 15);
        System.out.println("Hijrah chronology: " + hijrahPeriod.getChronology());
        
        // Convert between chronologies
        LocalDate isoDate = LocalDate.now();
        LocalDate hijrahDate = HijrahChronology.INSTANCE.date(isoDate);
        ChronoPeriod convertedPeriod = Period.between(
            hijrahDate, 
            hijrahDate.plus(hijrahPeriod)
        );
        System.out.println("Converted period: " + convertedPeriod);
    }
}

此示例展示了使用 ChronoPeriod 处理不同日历系统的方法。 该接口在各种年表中提供一致的操作。 请注意,日历之间的转换可能会产生不同的结果。

来源

Java ChronoPeriod 接口文档

在本文中,我们介绍了 Java ChronoPeriod 接口的基本方法和功能。 了解这些概念对于现代 Java 应用程序中基于日期的计算至关重要。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员。我于 2007 年开始撰写编程文章,至今已撰写超过 1,400 篇文章和八本电子书。 凭借超过八年的教学经验,我致力于分享我的知识,帮助他人掌握编程概念。

列出所有Java教程