【问题标题】:Formatting Chinese converted date by time4j to Gregorian in Java在Java中将time4j的中文转换日期格式化为公历
【发布时间】:2020-01-28 19:53:29
【问题描述】:

我正在使用 Java 开发一个项目,我需要将不同类型的日期相互更改,例如(公历到中文,反之亦然,公历到回历,反之亦然)。我尝试使用 Time4j,它具有将不同类型的日期相互转换的功能,但不幸的是,即使在我尝试阅读它的文档之后,我也不明白如何使用这个库。 p>

现在我正在尝试将公历日期转换为中文日期,但是当我使用object.getYear() 时,我无法获得中文日期的正常年份,它返回循环年份,但我需要正常年份,例如2019.

这是我的代码:

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 result = obj.getMonth() + "/" + obj.getDayOfMonth() + "/" + obj.getYear() ;

    System.out.println(result);         // 8/30/ji-hai(36)
    System.out.println(obj);            // chinese[ji-hai(2019)-8-30]
}
}

我需要这种类型的年份 ji-hai(2019) 并且默认是 toString() 方法,当我使用 object.getYear() 方法时它返回 ji-hai(36) 。

现在如何将我的返回值从 ji-hai(36) 更改为 ji-hai(2019)。另外,如果我想从用户那里接收公历日期,我应该如何为这种转换做准备?我可以将它作为字符串文本接收并将其转换为公历日期然后使用它吗?有可能吗?

另外,如果您知道一个很好的资源,可以通过示例解释 Time4j 的类和方法的用法,请与我分享。

谢谢。

【问题讨论】:

    标签: java calendar chinese-locale time4j


    【解决方案1】:

    短解:

    我建议不要尝试依赖toString() 等各种类型的toString() 方法,而是使用能够处理中国日历的专用格式引擎。 Time4J 有自己的基于类ChronoFormatter 的格式引擎:

        ChineseCalendar obj = PlainDate.nowInSystemTime().transform(ChineseCalendar.axis());
    
        ChronoFormatter<ChineseCalendar> f =
            ChronoFormatter.ofPattern(
              "d/M/U(r)", 
              PatternType.CLDR, 
              Locale.ROOT, 
              ChineseCalendar.axis());
    
        System.out.println(f.print(obj));   
        // output today: 1/9/ji-hai(2019)
    

    模式与中国年份:

    我使用了“d/M/U(r)”模式。中国历法的“正常”年是CLDR图案符号“U”所代表的循环年。循环年在 60 年后开始一个新的循环。对年份的任何其他定义显然是不寻常的。这可能会让西方用户感到惊讶,因为他们经常期望有任何一种预测年份只是以向前的方式计算。但是,Time4J 还支持另外两种年份。一个是时代的一年,现在只具有历史意义。另一种年份是相关的公历年(使用模式符号“r”)。它的主要目的只是使循环年明确。 因此,许多人喜欢将中国年构造为循环年和相关公历的组合,形式如下:

    U(r) or r(U)
    

    甚至可以确定仅在 12 年后重复的十二生肖。假设你有一个中国历法对象,你可以这样确定生肖:

        String zodiac = obj.getYear().getZodiac(Locale.ENGLISH);
        System.out.println("Year of " + zodiac); // Year of Pig
    

    逆向方式(解析并转换为公历):

    只需使用上面定义的格式化程序,然后解析:

        PlainDate gregorian = f.parse("1/9/ji-hai(2019)").transform(PlainDate.axis());
        System.out.println(gregorian); // output: 2019-09-29
    

    关于转录:

    我已使用根语言环境来构建格式化程序。它以简单的拉丁字母生成循环年份,没有任何变音符号。如果您可能想使用官方拼音转录,您可以改用英语语言环境。循环年将显示为“jǐ-hài”。中文(韩语和日语也使用相同的脚本)、越南语和俄语支持使用其他脚本的特殊转录。

    Time4J 的 API 文档可以在 online 找到。该文档已经包含格式化和解析中国日历的示例。但我欢迎任何进一步的贡献或改进它的具体建议。

    【讨论】:

    • 非常感谢您提供的全面信息。我只想提一下,解析和转换为 gregorian 会引发异常。 (ParseException:需要数字)。为什么会发生这种情况,我是否可以以相同的方式将所有其他可用的日期类型相互更改,或者每种类型的日期都有自己的转换方法,其工作方式不同?
    • @AliDK a) 是的,解析方法被声明为抛出一个检查过的ParseException'. If you have a parse problem then you can open another question describing your input and deliver a compilable and reproducible example, and then I can answer again. b) About transformation, the method transform()' 接受Chronology 类型的参数,兼容任何Calendrical 类型,因此您可以转换到ChineseCalendar、PlainDate(gregorian)、PersianCalendar等。另请参阅API-doc
    • @AliDK 您报告的解析错误消息(需要数字)似乎表明您的模式与您要解析的输入不匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    相关资源
    最近更新 更多