You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中Time4j历法转换问题:农历年份获取、公历转换及资源求助

解决Time4j多历法转换的几个问题

咱们一步步来搞定你在Java项目中用Time4j做历法转换遇到的问题:

1. 农历年份显示公历年(而非循环序号)的问题

你遇到的obj.getYear()返回ji-hai(36)是因为getYear()返回的是ChineseYear对象,它默认的toString会显示干支+60年循环的序号。要得到你想要的ji-hai(2019)格式,有两种简单方法:

方法一:直接获取干支名称和对应公历年

调用ChineseYear的getDisplayName()获取干支名称,getGregorianYear()获取关联的公历年,组合起来即可:

import net.time4j.PlainDate;
import net.time4j.calendar.ChineseCalendar;

public class DateConverter {
    static PlainDate gregorian = PlainDate.nowInSystemTime();
    static ChineseCalendar obj = gregorian.transform(ChineseCalendar.axis());

    public static void main(String[] args) {
        String ganZhi = obj.getYear().getDisplayName();
        int gregorianYear = obj.getYear().getGregorianYear();
        String result = obj.getMonth() + "/" + obj.getDayOfMonth() + "/" + ganZhi + "(" + gregorianYear + ")";
        System.out.println(result); // 输出示例:8/30/ji-hai(2019)
        System.out.println(obj); // 原输出:chinese[ji-hai(2019)-8-30]
    }
}

方法二:用Time4j格式化器(更规范)

Time4j提供了ChronoFormatter来自定义日期格式,适合更复杂的格式化需求:

import net.time4j.PlainDate;
import net.time4j.calendar.ChineseCalendar;
import net.time4j.format.expert.ChronoFormatter;
import java.util.Locale;

public class DateConverter {
    static PlainDate gregorian = PlainDate.nowInSystemTime();
    static ChineseCalendar obj = gregorian.transform(ChineseCalendar.axis());

    public static void main(String[] args) {
        // 定义格式:月份/日/干支(公历年)
        ChronoFormatter<ChineseCalendar> formatter = ChronoFormatter.ofPattern(
            "M/d/G(y)", 
            Locale.CHINESE, 
            ChineseCalendar.axis()
        );
        System.out.println(formatter.format(obj)); // 输出示例:8/30/ji-hai(2019)
    }
}

这里的G代表干支年份,y代表对应的公历年,完全符合你的需求。

2. 接收用户输入的公文字符串转公历日期

要把用户输入的字符串(比如2023-10-05或2023/10/05)转换成PlainDate,同样用ChronoFormatter来解析,记得处理格式错误的情况:

import net.time4j.PlainDate;
import net.time4j.format.expert.ChronoFormatter;
import java.text.ParseException;
import java.util.Locale;
import java.util.Scanner;

public class DateInputHandler {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入公历日期(格式:yyyy-MM-dd):");
        String userInput = scanner.nextLine();
        
        // 定义解析格式,根据用户输入习惯调整(比如MM/dd/yyyy)
        ChronoFormatter<PlainDate> parser = ChronoFormatter.ofPattern(
            "yyyy-MM-dd", 
            Locale.ENGLISH, 
            PlainDate.axis()
        );
        
        try {
            PlainDate gregorianDate = parser.parse(userInput);
            System.out.println("转换后的公历日期:" + gregorianDate);
            
            // 后续可以转农历/伊斯兰历
            ChineseCalendar chinese = gregorianDate.transform(ChineseCalendar.axis());
            System.out.println("对应农历:" + chinese);
        } catch (ParseException e) {
            System.err.println("输入格式错误,请按照yyyy-MM-dd格式输入!");
        }
        scanner.close();
    }
}

如果用户输入的是其他格式,只需要修改ofPattern里的模式字符串即可,比如MM/dd/yyyy对应美式日期格式。

3. Time4j优质示例资源推荐

不用找外部链接,Time4j本身就有很多实用的示例:

  • 官方Javadoc:每个历法类(比如ChineseCalendar、HijriCalendar)的文档里都有详细的代码示例,比如公历转伊斯兰历的基础用法:
import net.time4j.PlainDate;
import net.time4j.calendar.HijriCalendar;

public class HijriConverter {
    public static void main(String[] args) {
        // 公历转伊斯兰历(默认使用Umm al-Qura算法)
        PlainDate gregorian = PlainDate.of(2023, 10, 5);
        HijriCalendar hijri = gregorian.transform(HijriCalendar.family());
        System.out.println("伊斯兰历:" + hijri);
        
        // 伊斯兰历转公历
        PlainDate backToGregorian = hijri.transform(PlainDate.axis());
        System.out.println("转回公历:" + backToGregorian);
    }
}
  • 官方文档的Calendar Systems章节:里面系统讲解了各个历法的特性、转换方法、格式化解析技巧,是最权威的学习资料。
  • Time4j的测试代码:在Time4j的代码仓库中,time4j-calendar模块下的测试类包含了大量实际场景的用法示例,覆盖了各种边界情况,适合深入学习。

内容的提问来源于stack exchange,提问作者Ali Ansari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:12:28