/*written by WalterJ
if you want to copy one ,plz send a email to 18zcjiang18@stu.edu.cn*/
//----------Some Statements---------//
//+------------------------------------------------+
//| the data is what i search in the internet |//
//| if there are something wrong,plz tell me |//
//+----------------------------------------------+
//+------------------------------------------------+
//| 数据.h的数据来自网络 |//
//| 如果有什么错,请及时告诉我 |//
//+----------------------------------------------+
/*formula from zellar formula
and some formulas come from the internet
*/
#include "tou.h"
#include "shuju.h"
#include <stdio.h>
#include <Windows.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
char *Riming[30]={"初一","初二","初三","初四","初五","初六","初七","初八","初九","初十","十一","十二","十三","十四","十五","十六","十七","十八","十九","二十","廿一","廿二","廿三","廿四","廿五","廿六","廿七","廿八","廿九","三十"};
char *Yueming[12]={"正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","冬月","腊月"};
char *Tiangan[10]={"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
char *Dizhi[12]={"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
char *Shengxiao[12]={"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" };
char *Jieqi[24]={"冬至", "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪"};
char *Xingqi[7]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
char *Shujiu[9]={"一九","二九","三九","四九","五九","六九","七九","八九","九九"};
char *Meiyu[2]={"入梅","出梅"};
char *Sanfu[3]={"初伏","中伏","末伏"};
unsigned short Non_leapday[13]={0,31,59,90,120,151,181,212,243,273,304,334,365};
unsigned short Leapday[13]={0,31,60,91,121,152,182,213,244,274,305,335,366};
int IsLeapYear(short sYear);//判断闰年,参数:年份,返回值:0-平年,1-闰年
int GetNon_leapday(short sYear, unsigned short wMonth, unsigned short wDay,int *nDays);//计算日期在年内的序数,参数:年,月,日,年内序数,返回值:0-失败,1-成功
int GetDateFromOrdinal(short sYear,short sOrdinal,unsigned short* wMonth,unsigned short* wDay);//从年内序数计算月、日,参数:年,年内序数,月,日,返回值:0-失败,1-成功
int DateCheck(short sYear,unsigned short wMonth,unsigned short wDay);//检验年、月、日的合法性,参数:年,月,日,返回值:0-失败,1-成功
short LunarGetNewYearOrdinal(short sLunarYear);//获取农历新年的公历年内序数,参数:农历年,返回值:农历新年的公历年内序数
unsigned short LunarGetDaysofMonth(short sLunarYear,unsigned short wLunarMonth,int bLeapMonth);
/*获取农历月的天数,参数:农历年,农历月,是否为闰月,返回值:该农历月的天数,为0代表参数无效*/
int LunarExpandDX(short sLunarYear,int iDayOfMonth[15]);
//展开大小月数据表(某一年的),参数:农历年,从上一年十一月开始到当前年份(闰)十二月的每月天数,返回值:0-失败,1-成功
unsigned short LunarGetLeapMonth(short sLunarYear);
//获取农历某一年的闰月情况,参数:农历年,返回值,该年的闰月月份,0表示无闰月
int GetMonthInfo(unsigned short wYear,unsigned int* puData);//获取农历月份信息
int Gongli2Nongli(short sYear,unsigned short wMonth,unsigned short wDay,short* sLunarYear,unsigned short* wLunarMonth,unsigned short* wLunarDay,int * bLeapMonth);
//公历转农历,参数:公历年、月、日,农历年、月、日,是否为闰月,返回值:0-失败,1-成功
int Nongli2Gongli(short sLunarYear,unsigned short wLunarMonth,unsigned short wLunarDay,int bLeapMonth,short* sYear,unsigned short* wMonth,unsigned short* wDay);
//农历转公历,参数:家历年、月、日,是否为闰月,公历年、月、日,返回值:0-失败,1-成功
int GetJieQi(short sYear,unsigned short wMonth,unsigned short wJieQi[2]);
//得到指定年份的节气信息,首个是小寒
unsigned short GetDayOfWeek(short sYear,unsigned short wMonth,unsigned short wDay);
//计算星期,返回-1表示输入的年月日不正确或者超出年份范围
unsigned short GetDaysOfMonth(short sYear,unsigned short wMonth);
//计算某个月的天数,返回天数,如果返回0表示年或月有误
unsigned short G_HolidayShow(short sYear,unsigned short wMonth,unsigned short wDay);
//公历节日及节气显示,参数:公历年、公历月、公历日
int L_HolidayShow(int sLYear,int iLMonth,int iLDay,int iLeapMonth);
//农历节日及杂项显示,参数:农历年、农历月、农历日、农历闰月
int GetExtremeSeason(short sYear,short* sYijiu,unsigned short* wChuFu,unsigned short* wMoFu);
//查询某一年的数九及三伏,参数:公历年、上一年冬至(即一九)、初伏、末伏
int GetMeiYu(short sYear,unsigned short* wRuMeiOrd,unsigned short* wChuMeiOrd);
//查询某一年的入梅、出梅,参数:公历年,入梅,出梅
int IsLeapYear(short sYear) //真的就是闰年,假的就不是闰年
{
if (sYear%4==0 && sYear%100!=0 || sYear%400==0)//判断闰年的条件
{
return TRUE;
}else
{
return FALSE;
}
}
int GetNon_leapday(short sYear, unsigned short wMonth, unsigned short wDay,int *nDays)
{
//从日期算出距离元旦的天数(新历的)
int ret=0;
if (DateCheck(sYear,wMonth,wDay)==0)//对输入的日期进行检查
{
return 0;
}
ret=IsLeapYear(sYear);//判断是否为闰年
if (ret==-1)
{
return 0;
}
if (ret==1)
{
*nDays=Leapday[wMonth-1]+wDay-1;//元旦为序数0,因此减1 新历距离元旦的天数
}else
{
*nDays=Non_leapday[wMonth-1]+wDay-1;
}
return 1;
}
int GetDateFromOrdinal(short sYear,short sOrdinal,unsigned short* wMonth,unsigned short* wDay)
{
//从年内序数计算日期
int ret=0,i=0;
if (sOrdinal<0) //虽然年内序数不可能小于零,但是还是要判断一下。
{
return FALSE;
}
ret=IsLeapYear(sYear);
if (ret==1)
{
if (sOrdinal>=366)//超出了该年的总天数
{
return FALSE;
}
}else
{
if (sOrdinal>=365)
{
return FALSE;
}
}
if (ret!=-1)
{
//年符合,则计算;
*wMonth=0; //要找出的月份
for (i=0;i<12;i++)
{
if (ret==1)
{
if (sOrdinal>=Leapday[i] &&sOrdinal<Leapday[i+1]) //通过循环,比较前面的数组,找出月份
{
*wMonth=i+1; //要进一位,因为要比变量i多一个
*wDay=sOrdinal-Leapday[i]+1; //计算出它在那个月是第几号
break;
}
}else //如果不是闰月
{
if (sOrdinal>=Non_leapday[i] && sOrdinal<Non_leapday[i+1])
{
*wMonth=i+1;
*wDay=sOrdinal-Non_leapday[i]+1; //道理和上面一样→_→
break;
}
}
}
}else //如果各种不合法就全部跳过
{
*wDay=0;
*wMonth=0;
return FALSE;
}
return TRUE;
}
int DateCheck(short sYear,unsigned short wMonth,unsigned short wDay)
{
if (sYear<START_YEAR || sYear>=END_YEAR || wMonth>12|| wMonth<1 || wDay<1 || wDay>31) //判断合法性,即看看输入的年月日是否合法
{
return 0;
}
if (wMonth==4 || wMonth==6 || wMonth==9 || wMonth==11)
{
if (wDay==31)
{
return 0; //基本上,天数是正常的都返回0,因为天数一定是31.30.29.28四个数之间取一个
}
}else if (wMonth==2)
{
if (IsLeapYear(sYear)==0)
{
if (wDay>28)
{
return 0;
}
}else
{
if (wDay>29)
{
return 0;
}
}
}
return 1; //天数的长度不合法就返回1
}
short LunarGetNewYearOrdinal(short sLunarYear)
{
unsigned int uData=0;
if (GetMonthInfo(sLunarYear,&uData)==FALSE) //如果获取不到农历的月份信息,差不多就是月份输入不合法,但是还有一个历史原因
{
return 0;
}
return (short)((uData>>17)&0x3F);//取出农历新年的年内序数 即Udata和 0011 1111 ,因为显示春节的是14-22位置 所以通过逻辑与运算保留下来
}
unsigned short LunarGetDaysofMonth(short sLunarYear,unsigned short wLunarMonth,int bLeapMonth) //获取农历月份的信息 获取每一个农历月的信息
{
int i=0;// 循环变量
unsigned int DX_data=0;//该年大小月情况 先定义全部是小月
unsigned int uData=0; //要取出来的数据
int Acc_LeapMonth=0; //查看哪一个月为闰月
if (sLunarYear==START_YEAR-1)//农历还在起始年份的前一年 就是春节前后可能会出现问题 然后因为往前推一年它肯定在12月左右,然后他返回上一年可能是10.11.12,所以下面要判断是否会出现闰月 其实10月