ZetCode

Java 民国历法类

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

java.time.chrono.MinguoChronology 类实现了台湾使用的民国历法系统。它是 ISO-8601 的另一种历法。民国纪元始于 1912 年,即中华民国成立之年。

MinguoChronology 是不可变的且线程安全的。它遵循与 ISO 历法相同的规则,但年份编号偏移了 1911。例如,民国 1 年对应于公元 1912 年。该类提供了在民国日期和 ISO 日期之间转换的方法。

MinguoChronology 类概述

MinguoChronology 提供了创建民国日期、执行计算以及在不同历法之间转换的方法。关键操作包括日期创建、字段访问和历法比较。该类处理民国纪元之前的闰年。

public final class MinguoChronology extends AbstractChronology {
    public static MinguoChronology INSTANCE;
    public MinguoDate date(int prolepticYear, int month, int dayOfMonth);
    public MinguoDate dateYearDay(int prolepticYear, int dayOfYear);
    public MinguoDate dateEpochDay(long epochDay);
    public MinguoDate dateNow();
    public MinguoDate dateNow(ZoneId zone);
    public MinguoDate dateNow(Clock clock);
    public MinguoDate date(TemporalAccessor temporal);
    public int prolepticYear(Era era, int yearOfEra);
    public MinguoEra eraOf(int eraValue);
    public List<Era> eras();
    public boolean isLeapYear(long prolepticYear);
    public int getCalendarType();
}

以上代码展示了 MinguoChronology 提供的关键方法。这些方法允许创建民国日期、在纪元之间转换以及检查闰年。该类遵循与 ISO 相同的日期规则,但年份编号不同。

创建民国日期

可以使用历法实例通过多种方式创建民国日期。最常用的方法是使用 date 创建特定日期,使用 dateNow 创建当前日期。所有日期都在民国历法系统中创建。

Main.java
package com.zetcode; 

import java.time.chrono.MinguoChronology;
import java.time.chrono.MinguoDate;
import java.time.LocalDate;

public class Main {

    public static void main(String[] args) {
        
        // Current Minguo date
        MinguoDate today = MinguoChronology.INSTANCE.dateNow();
        System.out.println("Today in Minguo: " + today);
        
        // Specific Minguo date (year 112 = 2023 CE)
        MinguoDate date1 = MinguoChronology.INSTANCE.date(112, 4, 15);
        System.out.println("Specific Minguo date: " + date1);
        
        // From ISO date
        MinguoDate fromIso = MinguoDate.from(LocalDate.of(2023, 4, 15));
        System.out.println("From ISO date: " + fromIso);
        
        // Year-day date
        MinguoDate yearDay = MinguoChronology.INSTANCE.dateYearDay(112, 105);
        System.out.println("Year-day date: " + yearDay);
    }
}

此示例演示了创建 MinguoDate 对象的不同方法。请注意,民国年份比 ISO 年份偏移了 1911。输出以民国历法格式 (年-月-日) 显示日期。

在民国和 ISO 之间转换

民国日期可以转换为 ISO 日期,也可以从 ISO 日期转换。在使用不同历法系统的系统时,这些转换至关重要。转换保留了两个历法中相同的日期。

Main.java
package com.zetcode; 

import java.time.LocalDate;
import java.time.chrono.MinguoDate;

public class Main {

    public static void main(String[] args) {

        // Convert ISO to Minguo
        LocalDate isoDate = LocalDate.of(2023, 4, 15);
        MinguoDate minguoDate = MinguoDate.from(isoDate);
        System.out.println("ISO 2023-04-15 → Minguo: " + minguoDate);
        
        // Convert Minguo to ISO
        LocalDate backToIso = LocalDate.from(minguoDate);
        System.out.println("Minguo " + minguoDate + " → ISO: " + backToIso);
        
        // Proleptic year conversion
        int minguoYear = minguoDate.getChronology().prolepticYear(
            minguoDate.getEra(), minguoDate.getYearOfEra());
        System.out.println("Proleptic year: " + minguoYear);
        
        // Year difference
        System.out.println("Minguo year 112 = ISO year " + (112 + 1911));
    }
}

此示例显示了民国日期和 ISO 日期之间的转换。年份偏移在两个方向上始终如一地应用。请注意,闰年处理民国纪元之前的日期(公元 1912 年之前)。

使用民国日期字段

MinguoDate 提供了对日期字段的访问,类似于 LocalDate。这些字段遵循民国历法规则,但可以使用标准的时间接口进行访问。这允许在不同历法系统中一致地处理日期。

Main.java
package com.zetcode; 

import java.time.chrono.MinguoDate;
import java.time.temporal.ChronoField;

public class Main {

    public static void main(String[] args) {

        MinguoDate date = MinguoDate.of(112, 4, 15);
        
        // Get date components
        System.out.println("Year: " + date.get(ChronoField.YEAR_OF_ERA));
        System.out.println("Month: " + date.getMonthValue());
        System.out.println("Day: " + date.getDayOfMonth());
        
        // Era information
        System.out.println("Era: " + date.getEra());
        System.out.println("Is leap year: " + date.isLeapYear());
        
        // Day of year/week
        System.out.println("Day of year: " + date.getDayOfYear());
        System.out.println("Day of week: " + date.getDayOfWeek());
    }
}

此示例演示了访问 MinguoDate 的各种字段。这些字段的工作方式与 LocalDate 类似,但反映了民国历法值。闰年计算遵循与 ISO 历法相同的规则。

民国日期算术

MinguoDate 通过 plusminus 方法支持时间算术。这些操作遵循民国历法规则,同时保持与 ISO 日期计算的一致性。

Main.java
package com.zetcode; 

import java.time.chrono.MinguoDate;
import java.time.temporal.ChronoUnit;

public class Main {

    public static void main(String[] args) {

        MinguoDate date = MinguoDate.of(112, 4, 15);
        
        // Add days
        MinguoDate plusDays = date.plusDays(10);
        System.out.println("Plus 10 days: " + plusDays);
        
        // Subtract months
        MinguoDate minusMonths = date.minusMonths(2);
        System.out.println("Minus 2 months: " + minusMonths);
        
        // Add years
        MinguoDate plusYears = date.plusYears(1);
        System.out.println("Plus 1 year: " + plusYears);
        
        // Using ChronoUnit
        MinguoDate plusWeeks = date.plus(2, ChronoUnit.WEEKS);
        System.out.println("Plus 2 weeks: " + plusWeeks);
    }
}

此示例显示了对 MinguoDate 的各种时间算术运算。这些计算正确处理了月份长度和闰年,符合民国历法规则。所有操作都返回新的不可变的 MinguoDate 实例。

比较民国日期

MinguoDate 实现了 Comparable 接口,并提供了用于日期比较的方法。这些操作对于在使用民国历法系统的应用程序中基于日期的逻辑至关重要。

Main.java
package com.zetcode; 

import java.time.chrono.MinguoDate;

public class Main {

    public static void main(String[] args) {

        MinguoDate date1 = MinguoDate.of(112, 4, 15);
        MinguoDate date2 = MinguoDate.of(112, 5, 20);
        MinguoDate date3 = MinguoDate.of(111, 12, 31);
        
        // Comparison methods
        System.out.println("Is date1 before date2? " + date1.isBefore(date2));
        System.out.println("Is date1 after date3? " + date1.isAfter(date3));
        
        // CompareTo
        System.out.println("Compare date1 and date2: " + date1.compareTo(date2));
        
        // Equality
        MinguoDate sameDate = MinguoDate.of(112, 4, 15);
        System.out.println("Is date1 equal to sameDate? " + date1.equals(sameDate));
        
        // Between dates
        long daysBetween = date1.until(date2, java.time.temporal.ChronoUnit.DAYS);
        System.out.println("Days between date1 and date2: " + daysBetween);
    }
}

此示例演示了比较 MinguoDate 对象的各种方法。比较方法考虑了年、月和日组成部分。until 方法以指定的单位计算日期之间的时间。

格式化和解析民国日期

可以使用 DateTimeFormatter 格式化和解析民国日期。可以配置格式化程序以显示民国特定的纪元和年份信息,同时保持与标准日期模式的兼容性。

Main.java
package com.zetcode; 

import java.time.chrono.MinguoDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;

public class Main {

    public static void main(String[] args) {

        MinguoDate date = MinguoDate.of(112, 4, 15);
        
        // Default formatting
        System.out.println("Default format: " + date);
        
        // Localized formatting
        DateTimeFormatter formatter = DateTimeFormatter
            .ofLocalizedDate(FormatStyle.FULL)
            .withLocale(Locale.TAIWAN);
        System.out.println("Taiwan locale: " + date.format(formatter));
        
        // Custom pattern
        DateTimeFormatter customFormatter = DateTimeFormatter
            .ofPattern("GGGG y年 M月 d日")
            .withChronology(MinguoChronology.INSTANCE);
        System.out.println("Custom format: " + date.format(customFormatter));
        
        // Parsing
        MinguoDate parsed = MinguoDate.parse("Minguo 112-04-15");
        System.out.println("Parsed date: " + parsed);
    }
}

此示例显示了民国日期的格式化和解析。格式化程序可以显示纪元信息和本地化的月份名称。请注意,台湾地区通常使用民国历法来显示日期。

来源

Java MinguoChronology 类文档

在本文中,我们介绍了 Java MinguoChronology 类的基本方法和特性。理解这些概念对于使用台湾官方历法系统处理日期至关重要。

作者

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

列出所有Java教程