add ganzhi and shenxiao to ics

This commit is contained in:
Chen Wei
2016-04-10 10:23:13 +08:00
parent e9607df347
commit 459ff548c1
3 changed files with 67 additions and 12 deletions

View File

@@ -24,7 +24,7 @@ int main(int argc, char *argv[])
"METHOD:PUBLISH\n" "METHOD:PUBLISH\n"
"X-WR-CALNAME:农历\n" "X-WR-CALNAME:农历\n"
"X-WR-TIMEZONE:Asia/Shanghai\n" "X-WR-TIMEZONE:Asia/Shanghai\n"
"X-WR-CALDESC:中国农历%d-%d, 包括节气. 数据来自香港天文台\n", start, end); "X-WR-CALDESC:中国农历%d-%d, 包括节气.\n", start, end);
while (start <= end) { while (start <= end) {
cn_lunarcal(start); cn_lunarcal(start);
start++; start++;

View File

@@ -31,6 +31,20 @@ static char *CN_SOLARTERM[] = {
"小雪", "大雪", "冬至" "小雪", "大雪", "冬至"
}; };
/* 干支记年 */
static char *GAN[] = {
"", "", "", "", "", "", "", "", "", ""
};
static char *ZHI[] = {
"", "", "", "", "", "", "", "", "", "", "", ""
};
static char *SX[] = {
"", "", "", "", "", "", "", "", "", "", "", ""
};
static double newmoons[MAX_NEWMOONS]; static double newmoons[MAX_NEWMOONS];
static double solarterms[MAX_SOLARTERMS]; static double solarterms[MAX_SOLARTERMS];
static int firstnm_offset; static int firstnm_offset;
@@ -144,6 +158,7 @@ int get_cached_lc(struct lunarcal *p[], int year)
est_nm = jd_nm + SYNODIC_MONTH; est_nm = jd_nm + SYNODIC_MONTH;
} }
/* fill in and mark each day with its lunar calendar year, month, day */
len = mark_month_day(p); len = mark_month_day(p);
/* add to cache */ /* add to cache */
@@ -171,18 +186,20 @@ int get_cached_lc(struct lunarcal *p[], int year)
/* mark month and day number, solarterms */ /* mark month and day number, solarterms */
int mark_month_day(struct lunarcal *lcs[]) int mark_month_day(struct lunarcal *lcs[])
{ {
int i, k, len; int i, k, len, idx_lc_newyear;
int leapmonth, month; int leapmonth, month;
double lc_start, lc_end, jd, month_day1; double lc_start, lc_end, jd, month_day1;
struct lunarcal *lc; struct lunarcal *lc;
GregorianDate g;
len = 0;
month = 11; month = 11;
month_day1 = 0;
idx_lc_newyear = -1;
leapmonth = find_leap(); leapmonth = find_leap();
lc_start = newmoons[firstnm_offset]; lc_start = newmoons[firstnm_offset];
lc_end = solarterms[MAX_SOLARTERMS -1]; lc_end = solarterms[MAX_SOLARTERMS -1];
jd = lc_start; jd = lc_start;
month_day1 = 0;
len = 0;
while (jd < lc_end) { /* fill in days into array lcs */ while (jd < lc_end) { /* fill in days into array lcs */
/* scan for month jd belongs */ /* scan for month jd belongs */
for (i = firstnm_offset; i < MAX_NEWMOONS; i++) { for (i = firstnm_offset; i < MAX_NEWMOONS; i++) {
@@ -205,10 +222,26 @@ int mark_month_day(struct lunarcal *lcs[])
lc = lcalloc(jd); lc = lcalloc(jd);
lc->month = month; lc->month = month;
lc->day = (int) (jd - month_day1 + 1); lc->day = (int) (jd - month_day1 + 1);
if (lc->month == 1 && lc->day == 1)
idx_lc_newyear = len; /* found 正月初一 */
lcs[len++] = lc; lcs[len++] = lc;
jd += 1.0; jd += 1.0;
} }
/* mark lunar year */
int lyear;
g = jd2g(lcs[idx_lc_newyear]->jd); /* 正月初一 in Gregorian */
for (i = 0; i < len; i++) {
if (i < idx_lc_newyear)
lyear = g.year - 1;
else
lyear = g.year;
lcs[i]->lyear = lyear;
}
/* modify days with solar terms */ /* modify days with solar terms */
for (i = 0; i < MAX_SOLARTERMS - 1; i++) { for (i = 0; i < MAX_SOLARTERMS - 1; i++) {
if (solarterms[i] >= lc_start) { if (solarterms[i] >= lc_start) {
@@ -270,6 +303,7 @@ struct lunarcal *lcalloc(double jd)
if (p) { if (p) {
p->jd = jd; p->jd = jd;
p->solarterm = -1; p->solarterm = -1;
p->lyear = -1;
p->month = -1; p->month = -1;
p->day = -1; p->day = -1;
} }
@@ -277,28 +311,46 @@ struct lunarcal *lcalloc(double jd)
} }
/* generate 干支年份, e.g. 丙申[猴] */
void ganzhi(char *buf, size_t buflen, int lyear)
{
int idx_gan, idx_zhi, idx_sx;
idx_gan = lyear % 10;
idx_zhi = lyear % 12;
idx_sx = idx_zhi;
snprintf(buf, buflen, "%s%s[%s]", GAN[idx_gan], ZHI[idx_zhi], SX[idx_sx]);
}
void print_lunarcal(struct lunarcal *p[], int len) void print_lunarcal(struct lunarcal *p[], int len)
{ {
int i; int i;
char isodate[30]; char isodate[30], dtstart[30], dtend[30];
char tmp[30]; char tmp[30];
char dtstart[30]; char gzyear[30];
char dtend[30];
char utcstamp[30]; char utcstamp[30];
struct tm* utc_time; struct tm *utc_time;
time_t t = time(NULL); time_t t = time(NULL);
utc_time = gmtime(&t); utc_time = gmtime(&t);
sprintf (utcstamp, "%04d%02d%02dT%02d%02d%02dZ", 1900+utc_time->tm_year, utc_time->tm_mon, utc_time->tm_mday, utc_time->tm_hour, utc_time->tm_min, utc_time->tm_sec); sprintf(utcstamp, "%04d%02d%02dT%02d%02d%02dZ",
1900 + utc_time->tm_year, 1 + utc_time->tm_mon, utc_time->tm_mday,
utc_time->tm_hour, utc_time->tm_min, utc_time->tm_sec);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
jdftime(isodate, p[i]->jd, "%y-%m-%d", 0, 0); jdftime(isodate, p[i]->jd, "%y-%m-%d", 0, 0);
jdftime(dtstart, p[i]->jd, "%y%m%d", 0, 0); jdftime(dtstart, p[i]->jd, "%y%m%d", 0, 0);
jdftime(dtend, p[i]->jd, "%y%m%d", 24, 0); jdftime(dtend, p[i]->jd, "%y%m%d", 24, 0);
if (p[i]->day == 1) if (p[i]->day == 1) {
sprintf(tmp, "%s", CN_MON[p[i]->month]); ganzhi(gzyear, 30, p[i]->lyear);
else sprintf(tmp, "%s%s", gzyear, CN_MON[p[i]->month]);
} else {
sprintf(tmp, "%s", CN_DAY[p[i]->day]); sprintf(tmp, "%s", CN_DAY[p[i]->day]);
}
if (p[i]->solarterm > -1) if (p[i]->solarterm > -1)
sprintf(tmp, "%s %s", tmp, CN_SOLARTERM[p[i]->solarterm]); sprintf(tmp, "%s %s", tmp, CN_SOLARTERM[p[i]->solarterm]);
printf("BEGIN:VEVENT\n" printf("BEGIN:VEVENT\n"
"DTSTAMP:%s\n" "DTSTAMP:%s\n"
"UID:%s-lc@infinet.github.io\n" "UID:%s-lc@infinet.github.io\n"

View File

@@ -7,6 +7,7 @@
struct lunarcal { struct lunarcal {
double jd; double jd;
int solarterm; /* index of solarterm */ int solarterm; /* index of solarterm */
int lyear; /* year in Lunar Calendar */
int month; /* month in Lunar Calendar */ int month; /* month in Lunar Calendar */
int day; /* day in Lunar Calendar */ int day; /* day in Lunar Calendar */
}; };
@@ -28,6 +29,8 @@ int find_leap(void);
int mark_month_day(struct lunarcal *lcs[]); int mark_month_day(struct lunarcal *lcs[]);
void ganzhi(char *buf, size_t buflen, int lyear);
struct lunarcal *lcalloc(double jd); struct lunarcal *lcalloc(double jd);
void print_lunarcal(struct lunarcal *p[], int len); void print_lunarcal(struct lunarcal *p[], int len);