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
相关产品推荐
相关产品推荐

