ZetCode

Java AbstractChronology 类

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

java.time.chrono.AbstractChronology 是日历系统的抽象基类。它为不同的历法实现提供了框架,例如 ISO、回历或日本日历。

AbstractChronology 实现了 Chronology 接口。它作为特定于日历的操作的基础。该类处理跨不同日历的日期创建、字段管理和时间查询。

AbstractChronology 类概述

AbstractChronology 为所有历法实现提供通用功能。关键操作包括日期创建、纪元处理和日历系统标识。该类是 Java 综合日期时间 API 的一部分。

public abstract class AbstractChronology implements Chronology {
    public abstract String getId();
    public abstract String getCalendarType();
    public ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth);
    public ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth);
    public ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear);
    public ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear);
    public ChronoLocalDate date(TemporalAccessor temporal);
    public boolean isLeapYear(long prolepticYear);
    public int prolepticYear(Era era, int yearOfEra);
    public Era eraOf(int eraValue);
    public List<Era> eras();
    public ChronoPeriod period(int years, int months, int days);
}

上面的代码显示了 AbstractChronology 提供的关键方法。这些方法允许创建日期、处理纪元和查询日历系统。每个具体的历法都必须实现这些抽象方法。

获取历法信息

每个历法都有一个唯一的标识符和日历类型。这些属性有助于识别正在使用的日历系统。这些方法提供了有关历法实现的元数据。

Main.java
package com.zetcode;

import java.time.chrono.HijrahChronology;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.MinguoChronology;
import java.time.chrono.ThaiBuddhistChronology;

public class Main {

    public static void main(String[] args) {
        
        System.out.println("Hijrah Chronology:");
        System.out.println("ID: " + HijrahChronology.INSTANCE.getId());
        System.out.println("Calendar Type: " + 
            HijrahChronology.INSTANCE.getCalendarType());
        
        System.out.println("\nJapanese Chronology:");
        System.out.println("ID: " + JapaneseChronology.INSTANCE.getId());
        System.out.println("Calendar Type: " + 
            JapaneseChronology.INSTANCE.getCalendarType());
        
        System.out.println("\nMinguo Chronology:");
        System.out.println("ID: " + MinguoChronology.INSTANCE.getId());
        System.out.println("Calendar Type: " + 
            MinguoChronology.INSTANCE.getCalendarType());
        
        System.out.println("\nThai Buddhist Chronology:");
        System.out.println("ID: " + ThaiBuddhistChronology.INSTANCE.getId());
        System.out.println("Calendar Type: " + 
            ThaiBuddhistChronology.INSTANCE.getCalendarType());
    }
}

此示例演示了如何从不同的历法获取标识信息。每个日历系统都有唯一的标识符和类型。这些属性对于序列化和系统集成很有用。

在不同的日历中创建日期

AbstractChronology 提供了在各种日历系统中创建日期的方法。可以使用年-月-日或年-日组合来创建日期。这些方法支持前历年和基于纪元的年份。

Main.java
package com.zetcode;

import java.time.chrono.HijrahChronology;
import java.time.chrono.HijrahDate;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;

public class Main {

    public static void main(String[] args) {
        
        // Create Hijrah date
        HijrahDate hijrahDate = HijrahChronology.INSTANCE
            .date(1445, 10, 15);
        System.out.println("Hijrah Date: " + hijrahDate);
        
        // Create Japanese date with era
        JapaneseDate japaneseDate = JapaneseChronology.INSTANCE
            .date(JapaneseEra.HEISEI, 30, 5, 1);
        System.out.println("Japanese Date: " + japaneseDate);
        
        // Create date from year-day
        HijrahDate hijrahYearDay = HijrahChronology.INSTANCE
            .dateYearDay(1445, 200);
        System.out.println("Hijrah Year-Day: " + hijrahYearDay);
        
        // Create date from temporal
        JapaneseDate fromTemporal = JapaneseChronology.INSTANCE
            .date(japaneseDate);
        System.out.println("From Temporal: " + fromTemporal);
    }
}

此示例显示了在非 ISO 日历系统中创建日期的不同方法。date 方法支持各种参数组合。每个历法都根据其特定规则处理日期创建。

使用纪元

许多日历系统使用纪元来标记重要时期。AbstractChronology 提供了使用纪元值的方法。这些方法包括获取所有纪元以及在纪元年份和前历年之间进行转换。

Main.java
package com.zetcode;

import java.time.chrono.JapaneseChronology;
import java.time.chrono.JapaneseEra;
import java.time.chrono.MinguoChronology;
import java.time.chrono.MinguoEra;

public class Main {

    public static void main(String[] args) {
        
        // List all Japanese eras
        System.out.println("Japanese Eras:");
        JapaneseChronology.INSTANCE.eras().forEach(System.out::println);
        
        // Get era by value
        JapaneseEra heisei = JapaneseChronology.INSTANCE
            .eraOf(JapaneseEra.HEISEI.getValue());
        System.out.println("\nHeisei Era: " + heisei);
        
        // Convert between era year and proleptic year
        int prolepticYear = JapaneseChronology.INSTANCE
            .prolepticYear(JapaneseEra.HEISEI, 30);
        System.out.println("Proleptic Year: " + prolepticYear);
        
        // Minguo era example
        System.out.println("\nMinguo Era Before Common: " + 
            MinguoChronology.INSTANCE.eraOf(MinguoEra.BEFORE_ROC.getValue()));
    }
}

此示例演示了在不同日历系统中处理纪元。日本日历有多个纪元标记着皇室统治。其他日历,如民国,有不同的纪元系统。这些方法提供了在不同表示之间的转换。

检查闰年

闰年的规则在不同的日历系统之间有所不同。isLeapYear 方法根据历法的规则确定某年是否为闰年。这对于准确的日期计算非常重要。

Main.java
package com.zetcode;

import java.time.chrono.HijrahChronology;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.ThaiBuddhistChronology;

public class Main {

    public static void main(String[] args) {
        
        // Check leap years in different calendars
        int year = 2024;
        
        System.out.println("ISO Leap Year: " + 
            ThaiBuddhistChronology.INSTANCE.isLeapYear(year - 543));
        
        System.out.println("Hijrah Leap Year: " + 
            HijrahChronology.INSTANCE.isLeapYear(year - 579));
        
        System.out.println("Japanese Leap Year: " + 
            JapaneseChronology.INSTANCE.isLeapYear(year));
        
        // Check multiple years
        System.out.println("\nHijrah Leap Years 1440-1445:");
        for (long y = 1440; y <= 1445; y++) {
            System.out.println(y + ": " + 
                HijrahChronology.INSTANCE.isLeapYear(y));
        }
    }
}

此示例检查不同日历系统中的闰年。请注意泰国佛教和回历的年份调整。每个历法都实现了自己的闰年计算规则。结果可能在系统之间有所不同。

创建 ChronoPeriod 对象

AbstractChronology 可以创建特定于日历系统的期间对象。这些期间表示以年、月和天为单位的时间量。它们对于在历法中进行日期算术运算很有用。

Main.java
package com.zetcode;

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

public class Main {

    public static void main(String[] args) {
        
        // Create periods in different chronologies
        ChronoPeriod hijrahPeriod = HijrahChronology.INSTANCE
            .period(1, 6, 15);
        System.out.println("Hijrah Period: " + hijrahPeriod);
        
        ChronoPeriod japanesePeriod = JapaneseChronology.INSTANCE
            .period(2, 3, 10);
        System.out.println("Japanese Period: " + japanesePeriod);
        
        // Use period with dates
        HijrahDate hijrahDate = HijrahChronology.INSTANCE
            .date(1445, 1, 1);
        HijrahDate futureDate = hijrahDate.plus(hijrahPeriod);
        System.out.println("Future Hijrah Date: " + futureDate);
        
        // Negative period
        ChronoPeriod pastPeriod = HijrahChronology.INSTANCE
            .period(-1, -2, -5);
        HijrahDate pastDate = hijrahDate.plus(pastPeriod);
        System.out.println("Past Hijrah Date: " + pastDate);
    }
}

此示例显示了如何在不同的日历系统中创建和使用期间。期间可以是正数或负数,用于加/减时间。历法确保期间在应用于日期时遵循日历的特定规则。

比较跨日历的日期

可以使用 compareTo 方法比较来自不同历法的日期。比较基于纪元日值,从而允许跨日历系统进行一致的排序。这使得可以使用多个日历。

Main.java
package com.zetcode;

import java.time.chrono.HijrahChronology;
import java.time.chrono.HijrahDate;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.JapaneseDate;
import java.time.chrono.ThaiBuddhistChronology;
import java.time.chrono.ThaiBuddhistDate;

public class Main {

    public static void main(String[] args) {
        
        // Create dates in different calendars
        HijrahDate hijrahDate = HijrahChronology.INSTANCE
            .date(1445, 1, 1);
        JapaneseDate japaneseDate = JapaneseChronology.INSTANCE
            .date(2023, 1, 1);
        ThaiBuddhistDate thaiDate = ThaiBuddhistChronology.INSTANCE
            .date(2566, 1, 1);
        
        // Compare dates
        System.out.println("Hijrah vs Japanese: " + 
            hijrahDate.compareTo(japaneseDate));
        System.out.println("Japanese vs Thai: " + 
            japaneseDate.compareTo(thaiDate));
        System.out.println("Thai vs Hijrah: " + 
            thaiDate.compareTo(hijrahDate));
        
        // Check if dates are equal in different calendars
        System.out.println("\nSame moment different calendars:");
        HijrahDate hd = HijrahChronology.INSTANCE.date(1445, 1, 1);
        JapaneseDate jd = JapaneseChronology.INSTANCE.date(hd);
        System.out.println("Equal: " + hd.equals(jd));
        System.out.println("Compare: " + hd.compareTo(jd));
    }
}

此示例演示了比较跨不同日历系统的日期。虽然这些日期可能表示同一时刻,但它们的日历表示形式不同。比较基于底层纪元日值,以确保一致性。

来源

Java AbstractChronology 类文档

在本文中,我们介绍了 Java AbstractChronology 类的基本方法和特性。理解这些概念对于在 Java 应用程序中使用多个日历系统至关重要。

作者

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

列出所有Java教程