Conversion from Gregorian to Chinese
Only now I have released a new version of Time4J (v4.35, but I use Time4A -v3.40-2018b on Android), which supports the Chinese calendar . The transition from the Gregorian to the Chinese lunar calendar can be done in a direct way:
PlainDate gregorian = PlainDate.nowInSystemTime(); // 2018-03-07 ChineseCalendar cc = gregorian.transform(ChineseCalendar.axis()); System.out.println(cc); // chinese[wu-xu(2018)-1-21]
The Chinese calendar documentation also contains examples of how to format or parse it in many localized ways.
Special Design Requirements for Android Display
Keep in mind that the Chinese calendar contains elements that do not exist in the gregorian calendar, such as cyclic years , leap months or solar terms (a summary of our astronomical seasons). Time4J / A can format it, but it is calendar specific. This is true if you think of a universal calendar that will be universally applied to all calendars. It is probably best to do a specific display for the Chinese calendar on Android, so other important data, such as cyclic years in text form or solar terms, can also be displayed.
Comparison with ICU4J
The main differences:
- API style: ICU4J adopted the old world
java.util.Calendar , while Time4J / A follows domain-controlled - Immutable Function (ICU4J-calendar-class is NOT immutable unlike Time4J / A)
- solar terms (ICU4J doesn't seem to support this feature)
- (ICU4J uses an astronomical module based on a book by Peter Duffet / Smith, and Time4J / A is mainly based on the work of Jean Mius).
While some people still like the old-fashioned style of the ICU4J, Iām most worried about the accuracy of the ICU4J. As a reference, you can see the data published by the Hong Kong Observatory for 2018. ICU4J deviates from Hong Kong data already on 2018-11-07 (for a whole month, the date is one day incorrect!). Proof using the following code:
DateFormat df = DateFormat.getDateInstance( DateFormat.FULL, ULocale.forLanguageTag("en-u-ca-chinese")); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); sf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); ChineseCalendar cc = new ChineseCalendar(78, 35, 0, 0, 1); System.out.println(df.format(cc.getTime())); // Friday, First Month 1, 2018(wu-xu) for (int i = 0; i < 13; i++) { cc.add(Calendar.MONTH, 1); System.out.print(df.format(cc.getTime())); System.out.println("=>" + sf.format(cc.getTime())); }
Exit (note the line in November):
Saturday, Second Month 1, 2018(wu-xu)=>2018-03-17 Monday, Third Month 1, 2018(wu-xu)=>2018-04-16 Tuesday, Fourth Month 1, 2018(wu-xu)=>2018-05-15 Thursday, Fifth Month 1, 2018(wu-xu)=>2018-06-14 Friday, Sixth Month 1, 2018(wu-xu)=>2018-07-13 Saturday, Seventh Month 1, 2018(wu-xu)=>2018-08-11 Monday, Eighth Month 1, 2018(wu-xu)=>2018-09-10 Tuesday, Ninth Month 1, 2018(wu-xu)=>2018-10-09 Wednesday, Tenth Month 1, 2018(wu-xu)=>2018-11-07 Friday, Eleventh Month 1, 2018(wu-xu)=>2018-12-07 Sunday, Twelfth Month 1, 2018(wu-xu)=>2019-01-06 Tuesday, First Month 1, 2019(ji-hai)=>2019-02-05 Thursday, Second Month 1, 2019(ji-hai)=>2019-03-07
See also the old unresolved ICU4J debugger error question , many more dates in the future are erroneous. Of course, astronomical calculations cannot be strictly predicted in the future, but the first date when Time4J / A deviates from Hong Kong data is the year 2057 (calculated as soon as 37 seconds after local midnight) and not yet the current 2018, as in ICU4J . Therefore, I would advise ICU4J if they have not adjusted their astronomical module and cannot even be right during the current year.
To be realistic in the distant future, we do not know who is right for 2057, and even the observatory in Hong Kong clearly did not indicate this date:
If the time of the new moon (the first day of the lunar month) or a sunny day is close to midnight, the dates of the corresponding lunar month or solar term in the "Conversion Table" may have a one-day difference. such a situation will arise on the new moons on September 28, 2057 [...]