MenoData / Time4J

Advanced date, time and interval library for Java with sun/moon-astronomy and calendars like Chinese, Coptic, Ethiopian, French Republican, Hebrew, Hijri, Historic Christian, Indian National, Japanese, Julian, Korean, Minguo, Persian, Thai, Vietnamese
GNU Lesser General Public License v2.1
424 stars 62 forks source link

How can I use Time4J to parse Chinese calendar? #948

Closed lxconfig closed 2 years ago

lxconfig commented 2 years ago

the string such as "二零零九年零一月十三日",and I want it to be formatted as “2009-01-13” I can't parse it using the following method ChronoFormatter<ChineseCalendar> f = ChronoFormatter.ofPattern( "yyyy年M月d日", PatternType.CLDR, Locale.CHINA, ChineseCalendar.axis()).with(Attributes.NUMBER_SYSTEM, NumberSystem.ARABIC); ChineseCalendar calendar = f.parse(date); LocalDate localDate = calendar.transform(PlainDate.axis()).toTemporalAccessor(); the problem is : java.lang.IllegalArgumentException: Unsupported element: YEAR

MenoData commented 2 years ago

You should better use the pattern letter "r" (related gregorian year) instead of "yyyy" (=year-of-era).

MenoData commented 2 years ago

Sorry for my late final analysis but I can now really answer your question.

Main error is: You really want the gregorian calendar with Chinese numerals and not the traditional Chinese rural calendar. My previous comment was mislead by your usage of Chinese calendar in presented code example. But the year 2009 is just a gregorian year, not a Chinese cyclic year or similar.

Unfortunately, Time4J has not yet supported Chinese numerals. But this enhancement is part of next release.

Solution using the next release v5.9:

    ChronoFormatter<PlainDate> f = 
        ChronoFormatter.setUp(PlainDate.axis(), Locale.CHINA)
            .startSection(Attributes.NUMBER_SYSTEM, NumberSystem.CHINESE_DECIMAL)
            .addPattern("yyyy年MM月", PatternType.CLDR) // two MM for padding
            .endSection()
            .startSection(Attributes.NUMBER_SYSTEM, NumberSystem.CHINESE_MANDARIN)
            .addPattern("d日", PatternType.CLDR)
            .endSection()
            .build();
    assertThat(
        f.parse("二零零九年零一月十三日"), 
        is(PlainDate.of(2009, 1, 13)));
    assertThat(
        f.print(PlainDate.of(2009, 1, 13)), 
        is("二零零九年零一月十三日"));
MenoData commented 2 years ago

Now Time4J-v5.9 has been released with all enhancements to solve your issue.