当前位置: 首页 > news >正文

日历类生辰八字九九三伏入梅出梅算法

我们在编制应用软件时会遇到要使用日历类特性的时候,特别是需显示农历日期的一些元素。
日历类要素有:阳历农历的对应显示的算法,农历二十四节气交节时刻算法,农历年月日的干支表达算法,生辰八字的算法,还有就是九九三伏入梅出梅算法。

本文提供三类算法:
一是二十四节气交节时刻算法;
二是生辰八字的算法;
三是农历九九三伏入梅出梅算法。

二十四节气交节时刻的计算较难,有精确要求的算法是天文算法,此方法太过复杂,本文介绍一个简单的算法,对于不要求精确时刻的日历,此是个替代方法。
本文提供的生辰八字算法也是最简洁的算法。

相信大多数人对于九九三伏入梅出梅的算法有些困惑。网上的介绍都偏于理论的解释,少有实际实用的计算方法。本文就为大家提供此类功能的计算方法和打印方法。
要计算九九就要先计算得冬至日期,谚云:连冬起九,冬至日是一九第一天。
计算三伏先要计算得夏至日期,还要计算得几个是庚日的日期,夏至后第三个庚日起10天为初伏。
计算入梅出梅要计算得农历的纪日干支,因农历的依据是干支纪年法,再按 ”芒种后丙日入梅,小暑后未日出梅 ”  规则来确定入梅和出梅日期。

下例功能函数 print_bzjjff (  ){ ...... }  是九九三伏入梅出梅计算和打印的方法。
完整的万年历程序制作可参阅我在本站的博文“简明万年历编制(C语言)”。该文中有农历纪年算法和公历农历对照万年历软件界面输出方法。


下面是简单的 C 语言源码:
//******************************************
//* 日历类:节气九九三伏入梅出梅算法
//******************************************
Canvas cs;     //画布,显示日历
string sBarDes[10];
int nBarId[10];
float src[4];  //ClearDraw (cls) clear screen
int ds[3];          //get date yymmdd
int dy,dm,dd;
int wd;             //weekday
int alln,alln1;     //总天数
int n,n0,n1 ;
string s,ss,s0 ;
string s1,s2,s3,s4;
string wds,wdss;  //weekday
double dy0,dy1,dm1,dd1;  //日期计算
string dy2,dm2,dd2 ;
double hh1,mm1,ss1;      //时间计算
string hh2,mm2,ss2;
string date$ ;     //日期串
string jname1,jname2;    //节气计算
string jqnames;
double jd;
double juD,tht,yrD;
double sD;    //shouD
double vs,dalt;     //solar
int jqdn,jqd1,jqd2;  //print solar day  ( calendar )
string jqs1,jqs2;
string jqss1,jqss2;
string gzs,ggzs;  //干支计算
int gzy,gzm,gzd,gzh;  //干支 yy mm dd hh
int gzn1;
int yz,mz;    //年柱  月柱
string bzs;  //八字串
int dzd0,dzd1;  //冬至日
string p1, p2, p3, p4, p5 ;
string getss ;   //return $

main(){
setTitle ("日历类算法 (二)" );
jqnames="小寒大寒立春雨水惊蛰春分清明谷雨立夏小满芒种夏至小暑大暑立秋处暑白露秋分寒露霜降立冬小雪大雪冬至";

wdss="星期日星期一星期二星期三星期四星期五星期六";
gzs="甲子乙丑丙寅丁卯戊辰己巳庚午辛未壬申癸酉甲戌乙亥丙子丁丑戊寅己卯庚辰辛己壬午癸未甲申乙酉丙戌丁亥戊子己丑庚寅辛卯壬辰癸巳甲午乙未丙申丁酉戊戌己亥庚子辛丑壬寅癸卯甲辰乙巳丙午丁未戊申己酉庚戌辛亥壬子癸丑甲寅乙卯丙辰丁巳戊午己未庚申辛酉壬戌癸亥";

   setDisplay (0);     //不显示画布
sBarDes[0]="输入日期";
nBarId[0]=100;
sBarDes[1]=" 计  算 ";
nBarId[1]=101;
sBarDes[2]="< 上 月 ";
nBarId[2]=102;
sBarDes[3]="下 月 > ";
nBarId[3]=103;
sBarDes[4]="退出程序";
nBarId[4]=104;
sBarDes[5]="  ";
nBarId[5]=105;
setToolBarHeight(10);
setButtonTextSize(13);
setToolBarBackgroundColor(255,250,250,250);
setButtonColor(255,240,240,240);
setButtonTextColor(255,0,0,220);
setToolBar(100,myToolBarProc,sBarDes,nBarId,6);
getDate(ds);    //getDate = today
dy=ds[0] ;   dm=ds[1] ;   dd=ds[2] ;   
cal_bzjjff (); 
while (){}
}//main () 

inputDate (){     
//** 日期输入
getDate(ds);    //getDate = today
pickDate("输入日期:",ds);       //input date
clearOutput ();
dy=ds[0];
dm=ds[1];
dd=ds[2];
print "InputDate = ",dy ,"-",dm,"-",dd;
dd2=intToString(dd);  //this day $

      cal_bzjjff ();   //计算
}//inputDate()

cal_bzjjff (){
//** 计算生辰八字,节气,九九,三伏,入梅出梅
print "InputDate = ",dy ,"-",dm,"-",dd ;
getWeekday () ;  //计算总天数,星期几
print " ";
//** 计算当前月节气中气
//**** calculate solarterm    
dy2=intToString(dy);    
dm2=intToString(dm);
dy1=stringToDouble(dy2);
dm1=stringToDouble(dm2);
cs.SetTextSize (30);
dy0=dy1;
n=dm*2-1;
caljq();      //节气计算
jqd1=(int)(dd1);
jqs1=subString(jname2,0,2);
cs.DrawText (jname2,40,790);
jqss1=jname2;

          n=dm*2;
caljq ();      //节气计算
jqd2=(int)(dd1);
jqs2=subString(jname2,0,2);
cs.DrawText(jname2,40,830);         
jqss2=jname2;

//** 计算冬至日 >>> 计算九九
if (dm==12)dzd1=jqd2;    //show 九九
print "本年冬至 >>> ", dzd1;
if (dm<4){
n=24;     //节气序号
dy0=dy1-1;
caljq ();
dzd0=(int)(dd1);
print "上年冬至 >>> ", dzd0;   }

//** 计算当前日生辰八字
//** n=(dy+2096),计算至公元前(dy 是负数)
//calculate GZ,gzy,gzm,gzd,gzh, alln

//* jqd1是当月节气日,是八字年柱月柱
alln1=alln1+dd-1;       //all days
n=(dy+2096);
if(dm<2)n=n-1;
if(dm==2&&dd<jqd1)n=n-1;
gzy=n-(int)(n/60*60);     //mod (n, 60)
s1=subString(gzs,gzy*2,2);
if(dd<jqd1){mz=1;}else{mz=0;}
gzn1=(dy+2096)*12+dm-mz;
gzm=gzn1-(int)(gzn1/60*60);
s2=subString (gzs,gzm*2,2);
n1=alln1+9;
gzd=n1-(int)(n1/60*60);
s3=subString(gzs,gzd*2,2);
gzh=(gzd-(int)(gzd/5*5))*12;
s4=subString(gzs,gzh*2,2);
cs.SetColor(255,255,0,240);
cs.SetTextSize(27);
dd2=intToString(dd);  //this day $
if(len(dd2)==1)dd2="0"+dd2;
s="当前日期 :  "+dy2+" 年 "+dm2+" 月 "+dd2+ " 日";
s=s+" "+wds ;
date$=s;
// gzys=s1;   gzms=s2;   gzds=s3;  gzhs=s4;
s="今日八字 :  "+s1+" "+s2+" "+s3+" "+s4;   
bzs=s;      //八字 yy-mm-dd-hh

//** 计算 >>> 显示 >>> 九九三伏入梅出梅
print_bzjjff ();     //算法功能函数

//** 输出计算结果
print "______________________________________ ";
print " ";
print date$;
print bzs;
print " ";
print "节气 >>> " , jqss1 ;
print "节气 >>> " , jqss2 ;
print " ";
print "计算输出:九九三伏入梅出梅 ";
print "显示 >>> "+getss;
print "  ";
}//cal_bzjjff ()

getWeekday (){
//** 计算星期几
int ty;
int tm;
clearOutput ();
ty=dy;
tm=dm;
if (dm<3){
ty=dy-1;
tm=dm+12;   }
//first day=1 this month 月首日 dd=1
//iWeek=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) 
//mod 7   基姆拉尔森公式
alln=dd+2*tm+3*(tm+1)/5+ty+(int)(ty/4);
alln=alln-(int)(ty/100)+(int)(ty/400)+1;
wd=alln-alln/7*7;      //mod (alln,7)
wds=subString(wdss,wd*3,3);

//** 计算干支纪年,计算总天数
string yds;     //for gz day 
string ydds;
double tms;
yds="000031059090120151181212243273304334"; ydds=subString(yds,(dm-1)*3,3);
tms=stringToDouble(ydds);
alln1=(dy-1900)*365+((dy-1900-1)/4)+(int)(tms)+1;
if ((dy-dy/4*4)==0&&dm>2)alln1=alln1+1;
print "InputDate = ",dy ,"-",dm,"-",dd ;
print "总天数 = ",alln,"    ",alln1;
// return weekday >>> wds $
}//getWeekday ()

print_bzjjff ( ){    
//** calculate & show 九九三伏入梅出梅
//** 芒种后丙日入梅,小暑后未日出梅  //连冬起九
int jjiu,jiu1,jiu2;         //print and show 九九
string jius;
jius="一二三四五六七八九";

cs.SetTextSize (26);
cs.SetFillMode (1);//0不填色,1填色
ss=" ";  s=" "; 
p2=" ";   p4=" ";      //
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;
print ss;
if (dm==3&&dd>12)ss="      ";
cs.DrawText (ss,570,390);
p2=ss ;       
}   //show 九九$

//** 计算入梅出梅        
if (dm==6&&dd>4&&dd<17){
s0=subString (s3,0,1);
if (s0=="丙"){ ss="今日入梅";  }
else{  ss="  ";     print s0 ;    }
cs.DrawText (ss,583,330);   
p2=ss ;       }
if (dm==7&&dd>=6&&dd<18){
//** 20240706小暑出梅同日故 dd>=6
s0=subString (s3,1,1);
if (s0=="未"){ ss="今日出梅";}else{ss="  ";}
cs.DrawText (ss,583,330);   
p2=ss ;       }

 //** 计算三伏 calculate & show dog day
//夏至后第三个庚日起10天为初伏
//夏至后第四个庚日到立秋后第一个庚日为中伏
//立秋后第一个庚日起10天为末伏
int fn;
string fu1,fu2,fu3;
fu1="初伏第";
fu2="中伏第";
fu3="末伏第";

 //** 显示7月份伏日,初伏中伏,初伏7-11>>>7-20
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);   
p2=ss ;       }

//** 显示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);    
p2=ss ;       }

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);    
p2=ss ;       }
}    //show three fu day

       getss=p2 ;   //return getss $

  }//print_bzjjff ()

 

 

 

 

myToolBarProc(int nBtn,int nContext) {
if(nBtn==100){//计算星期, 显示月历
inputDate () ;
}
if(nBtn==101){//显示月历
if (dy<1900) {
getDate(ds);    //getDate = today
dy=ds[0] ;
dm=ds[1] ;
dd=ds[2] ;    }
cal_bzjjff (); 
}
if(nBtn==102){//上一月
if (dy<1900) {
getDate(ds);    //getDate = today
dy=ds[0] ;
dm=ds[1] ;
dd=ds[2] ;        }
dm=dm-1 ;
if (dm<1) { dy=dy-1 ; dm=12 ;  }
if (dm==2&&dd>28){ dd=28 ;    }
if (dd>30){ dd=30 ;    }                   
cal_bzjjff () ;
}
if(nBtn==103){//下一月
if (dy<1900) {
getDate(ds);    //getDate = today
dy=ds[0] ;
dm=ds[1] ;
dd=ds[2] ;        }
dm=dm+1 ;
if (dm>12) { dy=dy+1 ; dm=1;  }            
if (dm==2&&dd>28){ dd=28 ;    }
if (dd>30){ dd=30 ;    }      
cal_bzjjff () ;
}
if(nBtn==104){//退出程序
clearOutput();
cs.ClearDraw (0,src);
setDisplay (0);
exit (0);         }
if(nBtn==105){//空
setDisplay (0);
}
}//Toolbar () ***********************

caljq(){
//** calculate solar ** return jname2
//** 依据曾次亮先生节气算法拟合 >>>
juD=dy0*(365.2423112-0.000000000000064
*(dy0-100)*(dy0-100)- 0.00000003047
*(dy0-100))+15.218427*n+1721050.71301;
tht=0.0003*dy0-0.372781384-0.2617913325*n;
yrD=(1.945*sin(tht)-0.01206*sin(2*tht))
*(1.048994-0.00002583 *dy0);
sD=-0.0018*sin(2.313908653*dy0
-0.439822951-3.0443*n);
//'vs = juD          '** 平气
vs = (juD + yrD + sD);  //   '** 定气
dalt=-15+(juD-2382148)*(juD-2382148)/41048480;
//print dalt;   //test
dalt = dalt/86400;
jd = vs - 0.5 - dalt-0.025;     // + 0.008;
int gg;
gg=n-(int)(n/2*2);

jdtoGD ();     //儒略日转公历日期
s=jqs1+" " +jname2;
//return jname2;           
}//caljq() ***********************************

//calculate jd to GD ** return jname2  *****
jdtoGD(){
double a,b,c,d,e;
double F;
double allss;
F=jd-(int)(jd);
//print "   ";
//print " JD =  ",jd;      //test
//print " 时分秒 日小数 =  ",F;
a=(int)(jd+0.5);
b=a+1537;
c=(int)((b-122.1)/365.25);
d=(int)(365.25*c);
e=(int)((b-d)/30.6001);
dd1=b-d-(int)(30.6001*e);
dm1=e-1-(int)((e/14)*12);
dy1=c-4715-(int)((7+dm1)/10);
//print a," ",b,"  ",c,"  ",d,"  ",e;
dy2=intToString (dy);
dm2=intToString (dm);
dd2=doubleToString (dd1);
if (len(dm2)==1)dm2="0"+dm2;
if (dd1<10)dd2="0"+dd2;
dd2=subString (dd2,0,2);
//print dy2+" 年 "+dm2+" 月 "+dd2+" 日 ";
if(n==24)jqdn=(int)(dd1);
if (n==24&&dm1<3)jqdn=jqdn+1;

   //日allss 的小数转为时分秒
allss=(int)((jd-a)*86400+43200.5);
//print "allss = ", allss;
hh1=(int)(allss/3600);
mm1=(int)((allss-hh1*3600)/60);
ss1=(int)(allss-hh1*3600-mm1*60);
if(ss1>=60){
ss1=ss1-60;
mm1=mm1+1;}
if(mm1>=60){
mm1=mm1-60;
hh1=hh1+1;}
//print "JD  转为 GD,计算结果:”;
hh2=doubleToString(hh1);
mm2=doubleToString(mm1);
ss2=doubleToString(ss1);
if(hh1<10){
hh2="0"+doubleToString(hh1);}
if(mm1<10){
mm2="0"+doubleToString(mm1);}
if(ss1<10){
ss2="0"+doubleToString(ss1);}
hh2=subString (hh2,0,2);
mm2=subString (mm2,0,2);
ss2=subString (ss2,0,2);
jname1=subString(jqnames,(n-1)*2,2);
//print "节气 :  ",jname1;
jname2=jname1+" >   "+dm2+"-"+dd2+"  "+hh2+":"+mm2+":"+ss2;
//return jname2;
}//jdtoGD() **************


//**** END ****

 

http://www.xdnf.cn/news/1160569.html

相关文章:

  • 【用unity实现100个游戏之34】使用环状(车轮)碰撞器(Wheel Collider)从零实现一个汽车车辆物理控制系统,实现一个赛车游戏
  • PHP反序列化漏洞详解
  • 悬镜安全将受邀参加2025开放原子开源生态大会
  • 进程资源分配的安全性判断与安全序列
  • A316-Mini-V1:超小尺寸USB高清音频解码器模组技术探析
  • 基于Vue与CloudBase AI Toolkit的色觉识别Web应用开发报告:VibeCoding新范式实践
  • C#/.NET/.NET Core技术前沿周刊 | 第 47 期(2025年7.14-7.20)
  • 【前端状态更新与异步协调完全指南:React、Vue架构原理与复杂业务场景实战】
  • Django关于ListView通用视图的理解(Cursor解释)
  • RBAC(Role-Based Access Control,基于角色的访问控制)介绍(一种通过角色来管理用户权限的访问控制模型)
  • Spring Boot 集成 RabbitMQ:普通队列、延迟队列与死信队列全解析
  • 微信小程序服务端快速对接指南(java版)
  • Taro 路由相关 API 详解与实战
  • OpenCV学习(二)-二维、三维识别
  • opencv无法读取视频
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘pytest’问题
  • 金仓数据库:融合进化,智领未来——2025年数据库技术革命的深度解析
  • Spring MVC 核心工作流程
  • C/C++ 详谈结构体大小计算(内存对齐)
  • 在 Angular 应用程序中使用 Genkit 的完整指南
  • 在 Windows上用WSL和VSCode进行Linux开发环境配置
  • 【洛谷】The Blocks Problem、合并两个有序数组,补充pair(vector相关算法题p2)
  • Spring AI 集成阿里云百炼与 RAG 知识库,实现专属智能助手(框架思路)
  • 2025年终端安全管理系统的全方位解析,桌面管理软件的分析
  • Lua:小巧而强大的脚本语言,游戏与嵌入式的秘密武器
  • 智能体性能优化:延迟、吞吐量与成本控制
  • “融合进化,智领未来”电科金仓引领数字化转型新纪元
  • 前端JavaScript进阶
  • 基于大数据的旅游推荐系统 Python+Django+Hive+Vue.js
  • 文娱投资的逆势突破:博派资本的文化旅游综合体战略