Important Update!
I no longer update this code actively as I have stopped working on my own little project indefinitely related to this code. I may 'revive' the project again later this year (2010) if time permits, and then I'll continue to maintain this code. But I may convert the code to Python then.
If you need more data about the conversion, the following web sites may be useful to you:
Chinese Lunar Calendar
Gregorian-Lunar Calendar Conversion

1. What is This?
calcn includes some handy C functions for converting a date in Chinese calendar to a date in Western calendar, and vice versa. It uses a small lookup table to achieve space as well as time efficient conversion. No floating point operation is used in the conversion. Thus the code can be used by many types of platforms.
2. Source Code
calcn-0.6.tar.bz2 (Beta Version)
There are only 3 files in the package.
-
calcn.h: The header file. Include this to use the conversion functions. -
calcn.c: Implementation of the conversion functions. Link to this during the compilation. -
calcn_test.c: A simple test program that makes use of all functions fromcalcn.c. A good place to learn all functions within 3 minutes if you are lazy to read the documentation. Just do agcc calcn_test.c calcn.c -o calcn_testto get start.
The code should be compilable by any C compiler that is compliant with the C89 or the C99 standard. (It has been tested to be compiled with gcc -c -O3 -Wall -W -ansi -pedantic calcn.c and gcc -c -O3 -Wall -W -std=c99 -pedantic calcn.c without any warning and error.)
The code is distributed under the terms of LGPL.
3. Sample Test Session
This is a sample session from the test program. Note that the test program uses UTF-8 encoding to display some Chinese characters.
[1] Chinese -> Gregorian [2] Gregorian -> Chinese [3] Chinese year -> Gregorian year [4] Gregorian year -> Chinese year [q] Quit ? 1 Cycle (1-)? 78 Year in the cycle (1-60)? 23 Month (1-12)? 10 A leap month (0=no; 1=leap)? 0 Day (1-30)? 18 Western: 2006/12/8 [1] Chinese -> Gregorian [2] Gregorian -> Chinese [3] Chinese year -> Gregorian year [4] Gregorian year -> Chinese year [q] Quit ? 2 Year (1929-2043)? 2006 Month (1-12)? 12 Day (1-31)? 8 Chinese: 第78元运丙戌年十月十八日 [1] Chinese -> Gregorian [2] Gregorian -> Chinese [3] Chinese year -> Gregorian year [4] Gregorian year -> Chinese year [q] Quit ? 3 Cycle (1-)? 78 Year in the cycle (1-60)? 23 Gregorian year: 2006 [1] Chinese -> Gregorian [2] Gregorian -> Chinese [3] Chinese year -> Gregorian year [4] Gregorian year -> Chinese year [q] Quit ? 4 Year? 2006 Cycle : 78 Year in the cycle : 23
4. How do use it?
4.1. Date Representations
For a date in Western (Gregorian) calendar:
struct calgregorian {
int year; // The year [CALCN_YEAR_FROM..CALCN_YEAR_TO]
int month; // The month [1..12]
int day; // The day of the month [1..31]
};
For a date in the Chinese calendar:
struct calchinese {
int scycle; /* The sexagenary cycle [1..] (Year 2637 BCE as epoch) */
int syear; /* The year in the sexagenary cycle [1..60] */
int month; /* The month [1..12] */
int leap_month; /* 0 for a normal month; 1 for a leap/intercalary month */
int day; /* The day of the month [1..30] */
};
4.2. Conversion Functions
int calcn_chinese_from_gregorian(struct calchinese *p_calchinese,
const struct calgregorian *p_calgregorian);
int calcn_gregorian_from_chinese(struct calgregorian *p_calgregorian,
const struct calchinese *p_calchinese);
void calcn_year_chinese_from_astro(int *p_scycle, int *p_syear, const int year);
int calcn_year_astro_from_chinese(const int scycle, const int syear);
calcn_chinese_from_gregorian() converts a date in the Gregorian calendar to a date in the Chinese calendar, while calcn_gregorian_from_chinese() does the reverse. The return value has the following meanings:
-
0: The conversion is successful. -
CALCN_ERROR_OUT_OF_RANGE: The date is out of the range that can be handled by the program. Only the Gregorian year betweenCALCN_YEAR_FROMandCALCN_YEAR_TO(inclusive) can be handled by the function. -
CALCN_ERROR_INVALID_DATE: The date is invalid. It can be that the day of the month or the month is out of range, or a Chinese month has been specified as a leap month while there is no such a leap month in that year.
calcn_year_chinese_from_astro() converts an astronomical year to the Chinese year in the sexagenary cycle, while calcn_year_astro_from_chinese() does the reverse. The astronomical year -2636 is used as the epoch (the 1st year in the 1st cycle) for the conversion.
The numbering of the astronomical year is based on the familiar AD/BCE scheme, but it follows the normal integer numbering strictly. An astronomical year with a positive value is simply equal to the Western AD year. However, there is an astronomical year 0, which corresponds to 1 BCE. So, year n BCE corresponds to the -(n-1) astronomical year.
5. Known Issues
5.1. Bugs
No known outstanding bugs. Please contact me if you find any. (But I no longer maintain the code actively, so it's better if you have a patch for the bug.)
5.2. Limitations
The date conversion routines currently work for Gregorian years 1929-2043 only. I use my own program to generate the table and verify it against the calendar calculated by the Purple Mountain Observatory (紫金山天文台). The situation is a bit 'chaotic' before 1929 when the modern meridian of 120 degree East was not used yet. I have yet to decide some issues on this. I will add the data for future years when I have time to verify them against a reliable source.

Digg
Facebook
Google
Yahoo
Technorati