ZetCode

Java JapaneseDate 类

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

java.time.chrono.JapaneseDate 类代表日本皇历系统中的日期。它实现了 ChronoLocalDate 接口,并遵循基于日本纪元的日期表示约定。

JapaneseDate 是不可变的且线程安全的。它处理明治 6 年(1873 年)及之后的日期,当时日本采用了格里高利历。该类支持所有日本纪元,包括令和、平成、昭和和大正。

JapaneseDate 类概述

JapaneseDate 提供了处理日本日历日期的方法。主要功能包括基于纪元的日期创建、与其他日历系统的相互转换以及日期算术。该类处理日本纪元转换。

public final class JapaneseDate implements ChronoLocalDate, Serializable {
    public static JapaneseDate now();
    public static JapaneseDate now(ZoneId zone);
    public static JapaneseDate of(int prolepticYear, int month, int day);
    public static JapaneseDate of(Era era, int yearOfEra, int month, int day);
    public static JapaneseDate from(TemporalAccessor temporal);
    public JapaneseEra getEra();
    public int lengthOfMonth();
    public JapaneseChronology getChronology();
    public long toEpochDay();
    public static JapaneseDate ofEpochDay(long epochDay);
}

上面的代码展示了 JapaneseDate 提供的关键方法。 这些方法允许创建日本纪元的日期、在日历系统之间进行转换以及执行日期计算。该类处理纪元转换。

创建 JapaneseDate 对象

可以通过多种方式创建 JapaneseDate 对象。最常用的方法是 now 获取当前日期,以及用于特定日期的工厂方法。可以使用纪元或推算年创建日期。

Main.java
package com.zetcode; 

import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;

public class Main {

    public static void main(String[] args) {
        
        // Current date
        JapaneseDate now = JapaneseDate.now();
        System.out.println("Current Japanese date: " + now);
        
        // Specific date in Reiwa era
        JapaneseDate reiwaDate = JapaneseDate.of(JapaneseEra.REIWA, 3, 5, 1);
        System.out.println("Reiwa 3-5-1: " + reiwaDate);
        
        // Specific date using proleptic year
        JapaneseDate prolepticDate = JapaneseDate.of(2020, 5, 1);
        System.out.println("Proleptic 2020-5-1: " + prolepticDate);
        
        // From epoch day
        JapaneseDate epochDate = JapaneseDate.ofEpochDay(18765);
        System.out.println("From epoch day: " + epochDate);
    }
}

此示例演示了创建 JapaneseDate 对象的不同方法。 输出显示日本日历格式的日期。 now 方法捕获日本日历系统中的当前日期。

使用日本纪元

JapaneseDate 提供了使用日本纪元的方法。纪元系统是日本日历的基础。每个纪元都以新天皇的统治开始。

Main.java
package com.zetcode; 

import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;

public class Main {

    public static void main(String[] args) {

        JapaneseDate date = JapaneseDate.now();
        
        // Get current era
        JapaneseEra era = date.getEra();
        System.out.println("Current era: " + era);
        
        // List all available eras
        System.out.println("\nAvailable Japanese eras:");
        for (JapaneseEra e : JapaneseEra.values()) {
            System.out.println(e + " (" + e.getValue() + ")");
        }
        
        // Create date in Showa era
        JapaneseDate showaDate = JapaneseDate.of(JapaneseEra.SHOWA, 50, 1, 1);
        System.out.println("\nShowa 50-1-1: " + showaDate);
    }
}

此示例显示了如何使用日本纪元。 getEra 方法返回当前纪元。 可以使用 JapaneseEra.values() 列出所有可用的纪元。可以使用特定纪元创建日期。

在日历系统之间转换

JapaneseDate 可以与其他的日历系统进行相互转换。当处理国际日期或与其他 Java 日期 API 交互时,这非常有用。

Main.java
package com.zetcode; 

import java.time.LocalDate;
import java.time.chrono.JapaneseDate;
import java.time.temporal.ChronoField;

public class Main {

    public static void main(String[] args) {

        // Convert from LocalDate
        LocalDate localDate = LocalDate.of(2020, 5, 1);
        JapaneseDate japaneseDate = JapaneseDate.from(localDate);
        System.out.println("From LocalDate: " + japaneseDate);
        
        // Convert to LocalDate
        LocalDate backToLocal = LocalDate.from(japaneseDate);
        System.out.println("Back to LocalDate: " + backToLocal);
        
        // Using epoch days for conversion
        long epochDay = japaneseDate.toEpochDay();
        JapaneseDate fromEpoch = JapaneseDate.ofEpochDay(epochDay);
        System.out.println("From epoch days: " + fromEpoch);
        
        // Accessing year components
        int prolepticYear = japaneseDate.get(ChronoField.YEAR);
        int eraYear = japaneseDate.get(ChronoField.YEAR_OF_ERA);
        System.out.println("Proleptic year: " + prolepticYear);
        System.out.println("Era year: " + eraYear);
    }
}

此示例演示了 JapaneseDate 与其他日历系统之间的转换。 fromtoEpochDay 方法实现了无缝转换。 可以在推算年和纪元两种形式中访问年份值。

使用 JapaneseDate 进行日期算术

JapaneseDate 通过从 ChronoLocalDate 继承的方法支持日期算术。 这些操作遵循日本日历规则和纪元转换。

Main.java
package com.zetcode; 

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

public class Main {

    public static void main(String[] args) {

        JapaneseDate date = JapaneseDate.of(JapaneseEra.REIWA, 2, 4, 29);
        System.out.println("Original date: " + date);
        
        // Add days
        JapaneseDate plusDays = date.plusDays(10);
        System.out.println("Plus 10 days: " + plusDays);
        
        // Subtract months
        JapaneseDate minusMonths = date.minusMonths(2);
        System.out.println("Minus 2 months: " + minusMonths);
        
        // Add years (may cross era boundaries)
        JapaneseDate plusYears = date.plus(1, ChronoUnit.YEARS);
        System.out.println("Plus 1 year: " + plusYears);
        
        // Using period-based arithmetic
        JapaneseDate complex = date.plus(1, ChronoUnit.YEARS)
                                 .minus(3, ChronoUnit.MONTHS)
                                 .plus(5, ChronoUnit.DAYS);
        System.out.println("Complex operation: " + complex);
    }
}

此示例显示了使用 JapaneseDate 的各种日期算术运算。 这些操作会自动处理纪元转换。 方法支持添加或减去天、月和年,同时保持日历的正确性。

比较日本日期

JapaneseDate 实现了 Comparable 接口,并提供了日期比较的方法。 这些比较是纪元感知的,并遵循时间顺序。

Main.java
package com.zetcode; 

import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;

public class Main {

    public static void main(String[] args) {

        JapaneseDate date1 = JapaneseDate.of(JapaneseEra.HEISEI, 30, 4, 30);
        JapaneseDate date2 = JapaneseDate.of(JapaneseEra.REIWA, 1, 5, 1);
        JapaneseDate date3 = JapaneseDate.of(JapaneseEra.REIWA, 2, 1, 1);
        
        System.out.println("Date1: " + date1);
        System.out.println("Date2: " + date2);
        System.out.println("Date3: " + date3);
        
        // Comparison methods
        System.out.println("Date1 is before Date2: " + date1.isBefore(date2));
        System.out.println("Date2 is after Date1: " + date2.isAfter(date1));
        System.out.println("Date2 equals Date2: " + date2.equals(date2));
        
        // Compare across era boundaries
        System.out.println("Compare Date1 and Date2: " + date1.compareTo(date2));
        System.out.println("Compare Date2 and Date3: " + date2.compareTo(date3));
    }
}

此示例演示了比较 JapaneseDate 对象。 比较在纪元边界上也能正确工作。 compareTo 方法返回负值、零值或正值,指示时间顺序。

处理纪元转换

JapaneseDate 正确处理日本纪元之间的转换。 这对于纪元变更前后的日期(例如从平成到令和)尤为重要。

Main.java
package com.zetcode; 

import java.time.LocalDate;
import java.time.chrono.JapaneseDate;
import java.time.chrono.JapaneseEra;

public class Main {

    public static void main(String[] args) {

        // Heisei era last day
        JapaneseDate heiseiLast = JapaneseDate.of(JapaneseEra.HEISEI, 31, 4, 30);
        System.out.println("Heisei last day: " + heiseiLast);
        
        // Reiwa era first day
        JapaneseDate reiwaFirst = heiseiLast.plusDays(1);
        System.out.println("Reiwa first day: " + reiwaFirst);
        
        // Verify era transition
        System.out.println("New era: " + reiwaFirst.getEra());
        System.out.println("Year in new era: " + 
            reiwaFirst.get(JapaneseDate.ERA_YEAR));
            
        // Conversion around era boundary
        LocalDate boundaryLocal = LocalDate.of(2019, 4, 30);
        JapaneseDate boundaryJapanese = JapaneseDate.from(boundaryLocal);
        System.out.println("Boundary date: " + boundaryJapanese);
    }
}

此示例显示了 JapaneseDate 如何处理纪元转换。 从平成 31 年到令和 1 年的转换得到正确处理。 日期算术和转换在纪元边界上无缝工作。

来源

Java JapaneseDate 类文档

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

作者

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

列出所有Java教程