PHP根据年月日时计算出四柱的算法源代码

PHP计算四柱的代码网上应该是没有的,这是宇润花了好几天时间研究的成果!

<?php
class SiZhu
{
	public $niangan,$nianzhi,$yuegan,$rigan;
	function nianzhu($year)
	{
		$a = array('甲','乙','丙','丁','戊','己','庚','辛','壬','癸');
		$b = array('子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥');
		$last = $year % 10;
		if($last <= 3)
		{
			$last += 10;
		}
		$this->niangan = $last - 3;
		$tiangan = $a[$this->niangan - 1];
		$last = $year % 100;
		if($year >= 1800 && $year <= 1899)
		{
			$nianzhi = $last + 9;
		}
		else if($year >= 1900 && $year <= 1999)
		{
			$nianzhi = $last + 1;
		}
		else if($year >= 2000 && $year <= 2099)
		{
			$nianzhi = $last + 5;
		}
		if($nianzhi > 12)
		{
			$nianzhi %= 12;
		}
		$this->nianzhi = $nianzhi;
		$dizhi = $b[$nianzhi - 1];
		return $tiangan . $dizhi;
	}
	function yuezhu($month)
	{
		$a = array('甲','乙','丙','丁','戊','己','庚','辛','壬','癸');
		$b = array('寅','卯','辰','巳','午','未','申','酉','戌','亥','子','丑');
		$this->yuegan = $this->niangan * 2 + $month;
		if($this->yuegan > 10)
		{
			$this->yuegan %= 10;
		}
		return $a[$this->yuegan - 1] . $b[$month - 1];
	}
	function rizhu($year,$month,$day)
	{
		$a = array('甲','乙','丙','丁','戊','己','庚','辛','壬','癸');
		$b = array('子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥');
		$today = strtotime("{$year}-{$month}-{$day}");
		$year_start = strtotime("{$year}-01-01");
		$days = ( $today - $year_start )/86400 + 1;
		$n = (int)(($year - 1900) * 5 + ($year - 1900 + 3) / 4 + 9 + $days);
		$n = $n % 60;
		$this->rigan = $n % 10;
		if($this->rigan == 0)
		{
			$this->rigan = 10;
		}
		$dizhi = $n % 12;
		if($dizhi == 0)
		{
			$dizhi = 12;
		}
		return $a[$this->rigan - 1] . $b[$dizhi - 1];
	}
	function shizhu($hour)
	{
		$a = array('甲','乙','丙','丁','戊','己','庚','辛','壬','癸');
		$b = array('子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥');
		if($hour >= 23 || $hour < 1)
		{
			$shizhi = 1;
		}
		else if($hour >= 1 && $hour < 3)
		{
			$shizhi = 2;
		}
		else if($hour >= 3 && $hour < 5)
		{
			$shizhi = 3;
		}
		else if($hour >= 5 && $hour < 7)
		{
			$shizhi = 4;
		}
		else if($hour >= 7 && $hour < 9)
		{
			$shizhi = 5;
		}
		else if($hour >= 9 && $hour < 11)
		{
			$shizhi = 6;
		}
		else if($hour >= 11 && $hour < 13)
		{
			$shizhi = 7;
		}
		else if($hour >= 13 && $hour < 15)
		{
			$shizhi = 8;
		}
		else if($hour >= 15 && $hour < 17)
		{
			$shizhi = 9;
		}
		else if($hour >= 17 && $hour < 19)
		{
			$shizhi = 10;
		}
		else if($hour >= 19 && $hour < 21)
		{
			$shizhi = 11;
		}
		else if($hour >= 21 && $hour < 23)
		{
			$shizhi = 12;
		}
		$n = $this->rigan * 2 + $shizhi - 2;
		if($n > 10)
		{
			$n %= 10;
		}
		return $a[$n - 1] . $b[$shizhi - 1];
	}
}

年柱和月柱都需要传农历的年和月,日柱和时柱都是公历的几号和几时。

不要问我为什么这么算,百度找来的计算方式,然后尝试修改而成,我并不懂原理。

跟其它网站以及易语言内置的四柱计算函数的计算结果比较过一些日期,目前还未发现有问题。

四柱是啥

四柱即出生人的出生年、月、日、时分别称之为年柱、月柱、日柱和时柱;以天干地支纪年法表示出来每柱两个字,共八个字也称生辰八字,用以推算个人运程。

  • 标签
  • 发表评论
当前用户:
  • 评论列表
  • XIAO 2018-07-30 10:45:30

    月柱是有问题的

  • 羽凡 2017-11-22 14:45:19

    月干如果正好算的是20,取于就是0了,这样的结果是错的

  • Jackylin 2017-05-06 00:29:40

    CI怎么抽离service出来啊,我百度的那个办法报一个错,无法加载到类,可以分享一个ci扩展业务层的文章吗?而且业务写在controller不太好维护的

    • 宇润 2017-05-06 08:59:26

      不会CI,帮不到你,手动斜眼。。

  • 三生三世 2017-05-04 10:55:52

    月柱不对 网上的算法有问题

    • 宇润 2017-05-04 18:21:00

      哪个日期算出来的不对?

      • 三生三世 2017-05-06 18:16:58

        都不对 对比了百度的日历

        • 三生三世 2017-05-06 18:26:36

          年 的干支还会存在二月的问题
          看别人c的代码 有时间转下看看 直接运行也会有边界值得问题 二月 和 首尾 闰年 还是对这个算法不了解的,有时间研究下这个算法
          #include<conio.h>
          #include<stdio.h>
          #include<stdlib.h>
          static char *tg[]={"甲","乙","丙","丁","戊","已","庚","辛","壬","癸"};
          static char *dz[]={"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
          static char *ny[]={"地中金","炉中火","大林木","路旁土","剑锋金","山头火","涧下水","城头土","白腊金","杨柳木","泉中水","屋上土","霹雳火","松柏木","长流水","沙中金","山下火","平地木","壁上土","金箔金","佛灯火","天河水","大驿土","钗钏金","桑柘木","大溪水","沙中土","天上火","石榴木","大海水"};
          static char *jq[]={"立春","惊蛰","清明","立夏","芒种","小暑","立秋","白露","寒露","立冬","大雪","小寒"};
          main()
          {
          int flag=1,acctemp,acc,t,tempy,Y,ytg,ydz,yny,tempm,M,mtg,mdz,mny,D,dtg,ddz,dny,H,htg,hdz,hny;
          int temp [12]={5,7,6,7,7,8,9,9,9,8,8,7};
          char e;
          FILE *fp;
          int Isleapyear(int year);
          void ycompute(int year,int *tg,int *dz);
          void mcompute(int month,int ytg,int *tg,int *dz);
          void dcompute(int year,int accumulative_number,int *tg,int *dz);
          void hcompute(int hour,int dtg,int *tg,int *dz);
          void compute(int tg,int dz,int *ny);
          printf("\n\t\t\t\t欢迎使用四柱纳音\n");
          printf("\n\n\t****************************************************************\n");
          printf("\n使用须知:\n\n\t1.输入的年月日一律采用阳历,时间请用24小时制。\n");
          printf("\n\t2.测试完毕,系统将会于D盘生成测试记录,可自行查看。\n");
          printf("\n\t****************************************************************\n");
          do
          {
          if((fp=fopen("d:\\四柱纳音测试记录.txt","a"))==NULL)
          {
          printf("操作失败!\n");
          exit(1);
          }
          else
          printf("\n\t\t\t\tReady Go!\n");
          yerr: printf("\n请输入年份:\n");
          scanf("%d",&tempy);
          merr: printf("\n请输入月份:\n");
          scanf("%d",&tempm);
          printf("\n请输入日期:\n");
          scanf("%d",&D);
          herr: printf("\n请输入时间(24小时制):\n");
          scanf("%d",&H);/*对阳历时间的采集*/
          if(tempy>=3200||tempy<=0)
          {
          printf("\n请输入0~3200之间的年份!");
          goto yerr;
          }
          if(H>24||H<1)
          {
          printf("\n请输入1~24之间的数!");
          goto herr;
          }
          if(tempm==2&&D>=3&&D<5)
          {
          printf("\n请输入该年%s是在几号!\n",jq[0]);
          scanf("%d",&temp[0]);
          }
          if(tempm>2||tempm==2&&D>=temp[0])
          Y=tempy;
          else
          Y=tempy-1;/*对年份的修正*/
          switch(tempm)
          {
          case 2:
          {
          if(D>=temp[0])
          M=1;
          else
          M=12;
          acctemp=31;
          break;
          }
          case 3:
          {
          if(D>=5&&D<7)
          {
          printf("\n请输入该年%s是在几号!\n",jq[1]);
          scanf("%d",&temp[1]);
          }
          if(D>=temp[1])
          M=2;
          else
          M=1;
          acctemp=59;
          break;
          }
          case 4:
          {
          if(D>=4&&D<6)
          {
          printf("\n请输入该年%s是在几号!\n",jq[2]);
          scanf("%d",&temp[2]);
          }
          if(D>=temp[2])
          M=3;
          else
          M=2;
          acctemp=30;
          break;
          }
          case 5:
          {
          if(D>=5&&D<7)
          {
          printf("\n请输入该年%s是在几号!\n",jq[3]);
          scanf("%d",&temp[3]);
          }
          if(D>=temp[3])
          M=4;
          else
          M=3;
          acctemp=0;
          break;
          }
          case 6:
          {
          if(D>=5&&D<7)
          {
          printf("\n请输入该年%s是在几号!\n",jq[4]);
          scanf("%d",&temp[4]);
          }
          if(D>=temp[4])
          M=5;
          else
          M=4;
          acctemp=31;
          break;
          }
          case 7:
          {
          if(D>=6&&D<8)
          {
          printf("\n请输入该年%s是在几号!\n",jq[5]);
          scanf("%d",&temp[5]);
          }
          if(D>=temp[5])
          M=6;
          else
          M=5;
          acctemp=1;
          break;
          }
          case 8:
          {
          if(D>=7&&D<9)
          {
          printf("\n请输入该年%s是在几号!\n",jq[6]);
          scanf("%d",&temp[6]);
          }
          if(D>=temp[6])
          M=7;
          else
          M=6;
          acctemp=32;
          break;
          }
          case 9:
          {
          if(D>=7&&D<9)
          {
          printf("\n请输入该年%s是在几号!\n",jq[7]);
          scanf("%d",&temp[7]);
          }
          if(D>=temp[7])
          M=8;
          else
          M=7;
          acctemp=3;
          break;
          }
          case 10:
          {
          if(D>=8&&D<9)
          {
          printf("\n请输入该年%s是在几号!\n",jq[8]);
          scanf("%d",&temp[8]);
          }
          if(D>=temp[8])
          M=9;
          else
          M=8;
          acctemp=33;
          break;
          }
          case 11:
          {
          if(D>=7&&D<8)
          {
          printf("\n请输入该年%s是在几号!\n",jq[9]);
          scanf("%d",&temp[9]);
          }
          if(D>=temp[9])
          M=10;
          else
          M=9;
          acctemp=4;
          break;
          }
          case 12:
          {
          if(D>=6&&D<8)
          {
          printf("\n请输入该年%s是在几号!\n",jq[10]);
          scanf("%d",&temp[10]);
          }
          if(D>=temp[10])
          M=11;
          else
          M=10;
          acctemp=34;
          break;
          }
          case 1:
          {
          if(D>=5&&D<7)
          {
          printf("\n请输入该年%s是在几号!\n",jq[11]);
          scanf("%d",&temp[11]);
          }
          if(D>=temp[11])
          M=12;
          else
          M=11;
          acctemp=0;
          break;
          }
          default:
          {
          printf("\n月份输入有误,请重新输入!\n");
          goto merr;
          }
          }/*对月份的修正*/
          t=Isleapyear(tempy);
          if(tempm<=2)t=0;
          acc=acctemp+D+t;/*计算累积数*/
          ycompute(Y,&ytg,&ydz);
          mcompute(M,ytg,&mtg,&mdz);
          dcompute(tempy,acc,&dtg,&ddz);
          hcompute(H,dtg,&htg,&hdz);
          compute(ytg,ydz,&yny);
          compute(mtg,mdz,&mny);
          compute(dtg,ddz,&dny);
          compute(htg,hdz,&hny);/*数据处理程序段*/
          printf("\n\t\t四柱八字为:\t%s%s\t%s%s\t%s%s\t%s%s\n",tg[ytg-1],dz[ydz-1],tg[mtg-1],dz[mdz-1],tg[dtg-1],dz[ddz-1],tg[htg-1],dz[hdz-1]);
          printf("\n\t\t纳音五行为:\t%s\t%s\t%s\t%s\n",ny[yny-1],ny[mny-1],ny[dny-1],ny[hny-1]);/*屏幕输出*/
          fprintf(fp,"\n\n\t****************************************************************\n");
          fprintf(fp,"\n\t\t您输入的时间为:%d年%d月%d日%d点钟\n",tempy,tempm,D,H);
          fprintf(fp,"\n\t\t \t年柱\t月柱\t日柱\t时柱\n");
          fprintf(fp,"\n\t\t四柱八字为:\t%s%s\t%s%s\t%s%s\t%s%s\n",tg[ytg-1],dz[ydz-1],tg[mtg-1],dz[mdz-1],tg[dtg-1],dz[ddz-1],tg[htg-1],dz[hdz-1]);
          fprintf(fp,"\n\t\t纳音五行为:\t%s\t%s\t%s\t%s\n",ny[yny-1],ny[mny-1],ny[dny-1],ny[hny-1]);/*文本输出*/
          fclose(fp);
          err1: printf("\n再来一遍?(Y/N)\n");
          scanf("%s",&e);
          if(e=='Y'||e=='y');
          else if(e=='N'||e=='n')flag=0;
          else
          {
          printf("对不起,请输入“Y”或“N”中的一个。\n");
          goto err1;
          }
          }
          while(flag);/*使用一个while循环增强程序的可利用性*/
          if((fp=fopen("d:\\四柱纳音测试记录.txt","a"))==NULL)
          {
          printf("操作失败!\n");
          exit(1);
          }
          fprintf(fp,"\n\n\t\t本程序主要献给我的好友章慧,我想祝她生日快乐!\n");
          fprintf(fp,"\n\n\t\t\t\t\t\t\t花与叶工作室\n");
          fprintf(fp,"\n\t\t\t\t\t\t\t制作于7月25日\n");
          printf("\t\t\t\t谢谢使用该程序!\n");
          getch();
          }
          int Isleapyear(int year)/*判断某年是否为闰年,闰年返回1,否则返回0。*/
          {
          int i;
          if((year%400==0)||(year%100!=0)&&(year%4==0))i=1;
          else i=0;
          return i;
          }
          void ycompute(int year,int *tg,int *dz)/*年柱处理子程序*/
          {
          if(year<=3)year+=60;
          year-=3;
          *tg=year%10;
          if(*tg==0)*tg=10;
          *dz=year%12;
          if(*dz==0)*dz=12;

          }
          void mcompute(int month,int ytg,int *tg,int *dz)/*月柱处理子程序*/
          {
          int ym;
          ym=10-ytg;
          ym+=2;
          *dz=month+2;
          if(*dz>12)*dz-=12;
          *tg=ytg+*dz-ym;
          if(*tg>10)*tg-=10;
          if(*tg<0)*tg+=10;
          if(*tg==0)*tg=10;
          }
          void dcompute(int year,int accumulative_number,int *tg,int *dz)/*日柱处理子程序*/
          {
          int cardinal_number;
          int century;
          int total;
          int temp;
          year-=1;
          temp=year%100;
          if(temp==0)temp=100;
          century=(int)(year/100);
          century=(int)(century*44.25);
          century+=15;
          cardinal_number=century%60;/*求基数*/
          total=(int)(temp*5.25);
          total+=cardinal_number;
          total+=accumulative_number;
          *tg=total%10;
          if(*tg==0)*tg=10;
          *dz=total%12;
          if(*dz==0)*dz=12;
          }
          void hcompute(int hour,int dtg,int *tg,int *dz)/*时柱处理子程序*/
          {
          int dh;
          dh=12-dtg;
          hour+=1;
          hour=(int)(hour/2);
          *dz=hour+1;
          if(*dz>12)*dz-=12;
          *tg=dtg+*dz-dh;
          if(*tg>10)*tg-=10;
          if(*tg<0)*tg+=10;
          if(*tg==0)*tg=10;
          }
          void compute(int tg,int dz,int *ny)/*由天干、地支推纳音五行*/
          {
          int i,s;
          if(dz==12)dz=0;
          for(i=0;i<6;i++)
          if((tg+i*10)%12==dz)
          {
          s=tg+i*10;
          break;
          }
          *ny=s+1;
          *ny=(int)(*ny/2);
          }

          • 宇润 2017-05-06 20:22:39

            如果都不对是不可能的,我调试过很多日期,都没问题。而且调试期间发现百度很多网站的计算结果是不对的

            • dama 2018-10-10 09:39:24

              月柱是用节气分的,头疼

            • 5600 2017-05-08 17:12:26

              年柱和月柱都需要传农历的年和月,日柱和时柱都是公历的几号和几时 。这个地儿弄错了!!!

  • 5600 2017-04-17 14:10:39

    596223

    • 龙哥 2017-09-27 11:10:45

      ”日柱和时柱都是公历的几号和几时“这样算出来的也不准确吧?老黄历没有公历之说哦
      我调用别人的一个免费接口,也是说闰月不对,请问你解决了吗?

      • 宇润 2017-09-29 09:07:20

        我写的时候也奇怪,但是当时是给人做项目,按照易语言的结果比较,综合网上的算法得出的。。具体是否正确就真不知道了,只能说符合易语言的计算结果