ZetCode

Java HijrahChronology 类

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

java.time.chrono.HijrahChronology 类实现了回历(伊斯兰)日历系统。它是 Java 日期和时间 API 中的一种历法实现。回历是许多穆斯林国家使用的阴历。

HijrahChronology 是不可变的且线程安全的。它提供了创建日期、执行计算以及在回历和其他日历系统之间转换的方法。该类支持伊斯兰历的不同变体。

HijrahChronology 类概述

HijrahChronology 扩展了 AbstractChronology 并实现了伊斯兰历规则。主要功能包括日期创建、与 ISO 日期的转换以及特定于日历的计算。该类处理回历的阴历性质。

public final class HijrahChronology extends AbstractChronology implements Serializable {
    public static HijrahChronology INSTANCE;
    public static HijrahDate now();
    public static HijrahDate now(Clock clock);
    public static HijrahDate now(ZoneId zone);
    public HijrahDate date(int prolepticYear, int month, int dayOfMonth);
    public HijrahDate dateEpochDay(long epochDay);
    public HijrahDate dateYearDay(int prolepticYear, int dayOfYear);
    public HijrahDate date(TemporalAccessor temporal);
    public long epochSecond(int year, int month, int dayOfMonth, 
        int hour, int minute, int second, ZoneOffset zoneOffset);
}

上面的代码展示了 HijrahChronology 提供的主要方法。这些方法允许从各种组件创建回历日期,并在日历系统之间进行转换。该类遵循标准的历法接口。

创建回历日期

可以使用 HijrahChronology 的工厂方法创建回历日期。该类提供了几种从年/月/日组件或从其他时间对象构造日期的方法。

Main.java
package com.zetcode; 

import java.time.chrono.HijrahDate;
import java.time.chrono.HijrahChronology;
import java.time.LocalDate;

public class Main {

    public static void main(String[] args) {
        
        // Current Hijrah date
        HijrahDate today = HijrahChronology.INSTANCE.dateNow();
        System.out.println("Today in Hijrah: " + today);
        
        // From year, month, day
        HijrahDate date1 = HijrahChronology.INSTANCE.date(1445, 9, 1);
        System.out.println("Specific date: " + date1);
        
        // From ISO date
        HijrahDate date2 = HijrahChronology.INSTANCE.date(LocalDate.of(2025, 4, 16));
        System.out.println("From ISO date: " + date2);
        
        // From epoch day
        HijrahDate date3 = HijrahChronology.INSTANCE.dateEpochDay(20000);
        System.out.println("From epoch day: " + date3);
    }
}

此示例演示了创建 HijrahDate 对象的不同方法。输出显示回历日历系统中的日期。请注意,月份编号从 1(穆哈拉姆)到 12(都尔黑哲)开始。

在日历之间转换

HijrahChronology 提供了在回历和 ISO 日期之间转换的方法。在应用程序中使用多个日历系统时,这些转换至关重要。

Main.java
package com.zetcode; 

import java.time.chrono.HijrahDate;
import java.time.chrono.HijrahChronology;
import java.time.LocalDate;

public class Main {

    public static void main(String[] args) {
        
        // Convert from Hijrah to ISO
        HijrahDate hijrahDate = HijrahChronology.INSTANCE.date(1445, 9, 1);
        LocalDate isoDate = LocalDate.from(hijrahDate);
        System.out.println("Hijrah to ISO: " + isoDate);
        
        // Convert from ISO to Hijrah
        LocalDate todayIso = LocalDate.now();
        HijrahDate todayHijrah = HijrahChronology.INSTANCE.date(todayIso);
        System.out.println("ISO to Hijrah: " + todayHijrah);
        
        // Using epoch day conversion
        long epochDay = hijrahDate.toEpochDay();
        System.out.println("Epoch day: " + epochDay);
        HijrahDate fromEpoch = HijrahChronology.INSTANCE.dateEpochDay(epochDay);
        System.out.println("From epoch day: " + fromEpoch);
    }
}

此示例展示了回历和 ISO 日期之间的双向转换。toEpochDay 方法提供了一个通用的数值表示,可用于计算或存储。转换在不同的日历系统中保持相同的时间点。

使用回历日期字段

HijrahDate 提供了对特定于日历的字段(如年、月和日)的访问。这些字段遵循伊斯兰历系统,可以被访问或修改。

Main.java
package com.zetcode; 

import java.time.chrono.HijrahDate;
import java.time.chrono.HijrahChronology;
import java.time.temporal.ChronoField;

public class Main {

    public static void main(String[] args) {
        
        HijrahDate date = HijrahChronology.INSTANCE.dateNow();
        
        // Get individual fields
        int year = date.get(ChronoField.YEAR);
        int month = date.get(ChronoField.MONTH_OF_YEAR);
        int day = date.get(ChronoField.DAY_OF_MONTH);
        
        System.out.printf("Current Hijrah date: %04d-%02d-%02d%n", year, month, day);
        
        // Get day of year
        int dayOfYear = date.get(ChronoField.DAY_OF_YEAR);
        System.out.println("Day of year: " + dayOfYear);
        
        // Get era (always AH - After Hijra)
        System.out.println("Era: " + date.getEra());
    }
}

此示例演示了访问 HijrahDate 的各种字段。ChronoField 常量提供了对标准日期组件的访问。请注意,在回历系统中,纪元始终为 AH (希吉来纪元后)。

回历日期的日期运算

HijrahDate 通过 plusminus 方法支持时间运算。这些操作考虑了回历的阴历性质,月份有 29 或 30 天。

Main.java
package com.zetcode; 

import java.time.chrono.HijrahDate;
import java.time.chrono.HijrahChronology;
import java.time.temporal.ChronoUnit;

public class Main {

    public static void main(String[] args) {
        
        HijrahDate date = HijrahChronology.INSTANCE.date(1445, 1, 1);
        System.out.println("Start date: " + date);
        
        // Add days
        HijrahDate plusDays = date.plus(10, ChronoUnit.DAYS);
        System.out.println("Plus 10 days: " + plusDays);
        
        // Add months (lunar months)
        HijrahDate plusMonths = date.plus(2, ChronoUnit.MONTHS);
        System.out.println("Plus 2 months: " + plusMonths);
        
        // Add years
        HijrahDate plusYears = date.plus(1, ChronoUnit.YEARS);
        System.out.println("Plus 1 year: " + plusYears);
        
        // Subtract weeks
        HijrahDate minusWeeks = date.minus(3, ChronoUnit.WEEKS);
        System.out.println("Minus 3 weeks: " + minusWeeks);
    }
}

此示例显示了使用 HijrahDate 的各种时间运算。请注意,添加月份时会考虑到阴历月份的长度变化。所有操作都返回新的实例,因为 HijrahDate 是不可变的。

比较回历日期

HijrahDate 实现了 Comparable 并提供了按时间顺序比较日期的方法。这些比较对于使用伊斯兰历的应用程序中的基于日期的逻辑至关重要。

Main.java
package com.zetcode; 

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

public class Main {

    public static void main(String[] args) {
        
        HijrahDate date1 = HijrahChronology.INSTANCE.date(1445, 1, 1);
        HijrahDate date2 = HijrahChronology.INSTANCE.date(1445, 2, 15);
        HijrahDate date3 = HijrahChronology.INSTANCE.date(1446, 1, 1);
        
        // Compare dates
        System.out.println("date1 before date2: " + date1.isBefore(date2));
        System.out.println("date2 after date1: " + date2.isAfter(date1));
        System.out.println("date1 compareTo date3: " + date1.compareTo(date3));
        
        // Equality check
        HijrahDate date1Copy = HijrahChronology.INSTANCE.date(1445, 1, 1);
        System.out.println("date1 equals copy: " + date1.equals(date1Copy));
    }
}

此示例演示了比较 HijrahDate 对象的各种方法。比较方法考虑了完整的日期,包括年、月和日。请注意,相等需要所有组件完全匹配。

自定义回历日历变体

回历有不同的变体,基于区域观察。Java 允许通过配置文件加载自定义日历变体。

Main.java
package com.zetcode; 

import java.time.chrono.HijrahDate;
import java.time.chrono.HijrahChronology;
import java.time.chrono.HijrahEra;
import java.util.Properties;

public class Main {

    public static void main(String[] args) {
        
        // Normally you would load from hijrah-config.properties file
        Properties props = new Properties();
        props.setProperty("id", "custom");
        props.setProperty("type", "islamic-umalqura");
        props.setProperty("version", "2.0");
        
        // In real usage, this would be configured before first use
        System.out.println("Custom calendar configuration:");
        props.forEach((k, v) -> System.out.println(k + ": " + v));
        
        // Using the default INSTANCE (which may be configured)
        HijrahDate date = HijrahChronology.INSTANCE.date(HijrahEra.AH, 1445, 9, 1);
        System.out.println("Date using current configuration: " + date);
    }
}

此示例演示了自定义回历日历变体的概念。在实践中,您将创建一个 hijrah-config.properties 文件。配置会影响配置后创建的所有 HijrahDate 实例。

来源

Java HijrahChronology 类文档

在本文中,我们介绍了 Java HijrahChronology 类的基本方法和功能。理解这些概念对于在 Java 应用程序中使用伊斯兰日期至关重要。

作者

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

列出所有Java教程