我们在编制应用软件时会遇到要使用日历类特性的时候,特别是需显示农历日期的一些元素。
日历类里阳历对应的农历要素的算法较复杂。
要素有:阳历农历的对应显示的算法,农历二十四节气交节时刻算法,农历纪年纪月的干支纪年算法,生辰八字的算法,还有就是九九三伏入梅出梅算法。
相信大多数人对于九九三伏入梅出梅的算法有些困惑。网上的介绍都偏于理论的解释,少有实际实用的计算方法。本文就为大家提供此类功能的计算方法和打印方法。
要计算九九就要先计算得冬至日期,谚云:连冬起九,冬至日是一九第一天。
计算三伏先要计算得夏至日期,还要计算得几个是庚日的日期,夏至后第三个庚日起10天为初伏。
计算入梅出梅要计算得农历的纪日干支,因农历的依据是干支纪年法,再按 ”芒种后丙日入梅,小暑后未日出梅 ” 规则来确定入梅和出梅日期。
下例功能函数 print_bzjjff ( ){ ...... } 是九九三伏入梅出梅计算和打印的方法。
至于如何使用此函数,可参阅我在本站的博文“简明万年历编制(C语言)”。该文中有农历纪年算法和节气算法。
下面是代码:
print_bzjjff ( ){
//** 九九三伏入梅出梅计算和打印 ********
//** 九九计算:连冬起九,冬至日起算
int jjiu,jiu1,jiu2; //print and show 九九
string jius;
jius="一二三四五六七八九";
//** dzd0 = 上年冬至日,dzd1 = 本年冬至日
//** dm 当前月, dd 当前日
if (dm>11&&dd>=dzd1||dm<4){
if (dm==12&&dd>=dzd1) jjiu=dd-dzd1;
if (dm==1) jjiu=31-dzd0+dd;
if (dm==2) jjiu=31-dzd0+31+dd;
if (dm==3&&dd<13) jjiu=31-dzd0+31+28+dd;
jiu2=jjiu-(int)(jjiu/9*9)+1;
jiu1=(int)(jjiu/9)+1;
print "jiu1 = ",jiu1," jiu2 = ",jiu2; //test
s0=subString (jius,jiu1-1,1);
s=intToString (jiu2);
ss=s0+"九第 "+s+" 天 ";
if (jjiu>80) ss=" ";
print jjiu; //test
print ss;
if (dm==3&&dd>12) ss=" ";
cs.SetTextSize (26);
cs.DrawText (ss,570,390);
} //show jiujiu$
//** 芒种后丙日入梅,小暑后未日出梅
//** s3 是计算日的纪日干支$ 字串,生辰八字计算时所得
ss=" "; s=" ";
if (dm==6&&dd>4&&dd<17){
s0=subString (s3,0,1);
if (s0=="丙"){ ss="今日入梅"; }
else{ ss=" "; print s0 ; }
cs.DrawText (ss,583,330); }
//** 20240706小暑出梅同日故 dd>=6
if (dm==7&&dd>=6&&dd<18){
s0=subString (s3,1,1);
if (s0=="未"){ ss="今日出梅"; }
else{ ss=" "; }
cs.DrawText (ss,583,330); }
//** 三伏日计算:show dog day ******
//** 夏至后第三个庚日起10天为初伏
//** 夏至后第四个庚日到立秋后第一个庚日为中伏
//** 立秋后第一个庚日起10天为末伏
//** 计算 n >>> gzd <=> s3 日干支
int fn;
string fu1,fu2,fu3;
fu1="初伏第";
fu2="中伏第";
fu3="末伏第";
ss=" ";
//** 显示7月份伏日,初伏中伏,初伏7-11>>>7-20
//** 六十甲子序表,十日一庚,逢七为庚日,mod ( X , 10 ) 求庚日和差值
if (dm==7&&dd>10){
n=(dd-dd/10*10)-((gzd-gzd/10*10)-6);
if (n<1) n=n+10;
if (n<11) n=n+10; //庚日
print " 伏日干支 庚日 = ", n ;
n0=dd-n+1; //庚日差值
if (dd>=n&&dd<=n+9){
ss=fu1+intToString (n0)+"天"; }
if (dd>n+9){
ss=fu2+intToString (n0-10)+"天"; }
cs.DrawText (ss,578, 390); }
//** 显示8月份伏日,中伏末伏
if (dm==8){
n=(dd-dd/10*10)-((gzd-gzd/10*10)-6);
if (n<10) n=n+10;
if (n>=10) n=n-10;
print " 伏日干支 庚日 = ", n ;
n0=31-n-10+dd; //庚日差值
if (n != 9&&n != 8) {
if (dd<n+10) {ss=fu2+intToString (n0-10)+"天"; }
if (dd>=n+10&&dd<n+20){
ss=fu3+intToString (n0-30)+"天"; }
cs.DrawText (ss,578, 390); }
if (n==9||n==8) {
//** 夏至日前一天,前二天庚日,伏30天
if (dd<n) {ss=fu2+intToString (n0-10)+"天"; }
if (dd>=n&&dd<n+10) {
ss=fu3+intToString (n0-20)+"天"; }
cs.DrawText (ss,578, 390); }
} //show three fu day
}//print_bzjjff ()
附图: