标题:[原创]经典万年历!LOOK一下!
只看楼主
zhangpeng
Rank: 1
等 级:新手上路
帖 子:31
专家分:0
注 册:2006-4-9
 问题点数:0 回复次数:1 
[原创]经典万年历!LOOK一下!


#include <stdio.h>
#include <string.h>
#include <conio.h>
#include "wnl.h"

#define WEEK_STARTX 4
#define WEEK_STARTY 4

#define YL_DATE_STARTX WEEK_STARTX
#define YL_DATE_STARTY WEEK_STARTY+2

#define NL_DATE_STARTX WEEK_STARTX
#define NL_DATE_STARTY WEEK_STARTY+3

void main()
{
MYDATE structNlDate,structYlDate;
int iWeek;
clrscr();
printf(" Input the year:"); scanf("%d",&structYlDate.iYear);
printf(" Input the month:"); scanf("%d",&structYlDate.iMonth);
structYlDate.iDay=1;
iWeek=GetWeek(structYlDate);
GetOfNongLiDate(&structNlDate,structYlDate);
printfWeekName();
printfDay(iWeek,structYlDate,structNlDate);
printf("\n");
/*printf("month day %d, %d , %d" ,structNlDate.iYear,structNlDate.iMonth,structNlDate.iDay);*/
getch();
}
/*******************************************************************************
根据1900年星期的月份代码及星期与月份年份的关系计算
1900年星期的月份代码
一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月
1 4 4 0 2 5 0 3 6 1 4 6
从设置代码中找规律
平年规律:
有数月代码相同:1和10月,2、3和11月,4和7月,9和12月相同,无相同的只有5、6、8月
代码变化规律:代码相同月份,代码数逐年增加

闰年规律(2004为闰年):
有数月代码相同:1-4-7,2-8,3-11,9-12
代码变化规律:从2月闰日之后有变化,从三月起代码+2
********************************************************************************/
int GetWeek(MYDATE structYlDate)
{
unsigned char u_1900_WeekCode[]={0,
1,4,4,0,2,5,0,3,6,1,4,6};
int iRunNianNum, iPingNianNum,iCalWeek;
/*计算平年和闰年数
注意运算:1901-1900年的间隔为0=1901-1900-1;1902-1900年的间隔为1=1902-1900-1*/
iRunNianNum = (structYlDate.iYear - 1900 - 1) / 4;
iPingNianNum = structYlDate.iYear - 1900 - iRunNianNum;
iCalWeek = u_1900_WeekCode[structYlDate.iMonth] + iRunNianNum * 2 + iPingNianNum;

/*如果为闰年,从2月闰日之后有变化,从三月起代码+2*/
if (structYlDate.iMonth > 2)
{
if ( (structYlDate.iYear%4==0)||
((structYlDate.iYear % 100== 0)&&(structYlDate.iYear % 400 == 0)) )
{
iCalWeek = iCalWeek + 1;
}
}
iCalWeek %=7;
return iCalWeek;
}
void printfWeekName()
{
unsigned char WeekName[][7]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
int i;
printf("\n");
for(i=0;i<7;i++)
{
gotoxy(WEEK_STARTX+i*10,WEEK_STARTY);
printf("%s",WeekName[i]);
}
printf("\n");
printf("\n");
}
void printfDay(int iStartWeekDay,MYDATE structYlDate,
MYDATE structNlDate)
{
int i,j;
int iDayNum=1;
int offsetX=0,offsetY=0;
int iNlMonthDayNum,iMonthDay;
MYDATE nextMonthInfo;
iMonthDay = yl_MonthDays[structYlDate.iMonth];
if( structYlDate.iMonth == 2 )
{
if( (structYlDate.iYear%4==0)||
((structYlDate.iYear % 100== 0)&&(structYlDate.iYear % 400 == 0)) )
{
iMonthDay ++ ;
}
}
for(i=1;i<42;i++)
{
if(i>iStartWeekDay)
{
/*
打印阳历数据
*/
gotoxy(YL_DATE_STARTX+offsetX,YL_DATE_STARTY+offsetY);
printf("%d",iDayNum);
iDayNum++;
/*
打印阴历数据
*/
gotoxy(NL_DATE_STARTX+offsetX,NL_DATE_STARTY+offsetY);
if(structNlDate.iDay == 1)
{
if(structNlDate.iMonthIsRun == 1)
{
printf("闰");
}
printf("%s",nl_MonthName[structNlDate.iMonth]);
if(structNlDate.iMonthDayNum == 30)
{
printf("大");
}
else
{
printf("小");
}
}
else
{
printf("%s" ,nl_DayName[structNlDate.iDay]);
}
structNlDate.iDay++;
if(structNlDate.iDay>structNlDate.iMonthDayNum)
{
GetMonthInfo(&nextMonthInfo,structNlDate);
structNlDate.iYear = nextMonthInfo.iYear;
structNlDate.iMonth = nextMonthInfo.iMonth;
structNlDate.iMonthDayNum = nextMonthInfo.iMonthDayNum;
structNlDate.iMonthIsRun = nextMonthInfo.iMonthIsRun;
structNlDate.iDay=1;
}

/*X向的偏移量增加*/
offsetX+=10;
if( (i % 7) == 0 )
{
offsetX=0;
offsetY+=3;
}

if(iDayNum>iMonthDay)
{
break;
}

}
else
{
gotoxy(YL_DATE_STARTX+offsetX,YL_DATE_STARTY+offsetY);
offsetX+=10;
}
}
}
void GetOfNongLiDate(MYDATE *structNlDate,MYDATE structYlDate)
{
MYDATE structYuanDanDate;/*农历正月初一对应的阳历日期*/
/*int structYuanDanDate.iYear,structYuanDanDate.iMonth,structYuanDanDate.iDay;*/
int nlMonth,nlDay; /*所对应的农历日期*/
unsigned char tmp[3]={0},tmp1[2]={0},runyue[2]={0};
int SepDayNum;/*所要计算的日期距本年新年的天数*/
int RunYue=0,iFirstFlag=1,i;

structYuanDanDate.iYear=structYlDate.iYear;

InitYear:
/*得到新年(农历正月初一)所对应的阳历日期*/
memset(tmp,0,2);
memcpy(tmp,daList[structYuanDanDate.iYear-1900]+14,2);
structYuanDanDate.iMonth = atoi(tmp);
memset(tmp,0,2);
memcpy(tmp,daList[structYuanDanDate.iYear-1900]+16,2);
structYuanDanDate.iDay = atoi(tmp);

/*如果要换算阳历的日期比当年的新年(农历正月初一)的日期早,则应该根据上一年的数据来
计算农历的日期,否则以当年的数据为准即可*/
if( structYlDate.iMonth <= structYuanDanDate.iMonth && iFirstFlag ==1 )
{
if(structYlDate.iMonth == structYuanDanDate.iMonth)
{
if(structYlDate.iDay<structYuanDanDate.iDay && iFirstFlag ==1)
{
iFirstFlag=0;
structYuanDanDate.iYear--;
goto InitYear;
}
}
else
{
iFirstFlag=0;
structYuanDanDate.iYear--;
goto InitYear;
}
}
/*计算给定日期到元旦的天数*/
SepDayNum=GetSepDayNum(structYuanDanDate,structYlDate);
/*根据要计算的日期距新年的天数以及这一年的农历数据计算出所求日期是阳历的月分*/

nlMonth = 1;
nlDay = 1;
memcpy(tmp1,daList[structYuanDanDate.iYear-1900]+12, 1); /*闰月大小月*/
memcpy(runyue,daList[structYuanDanDate.iYear-1900]+13,1);/*闰月月份*/
for(i = 1;i<=SepDayNum;i++)
{
nlDay++;
memset(tmp,0,2);
memcpy(tmp,daList[structYuanDanDate.iYear-1900]+nlMonth-1, 1);
if( (nlDay == 30 +atoi(tmp) ) ||
(RunYue && (nlDay = 30 + atoi(tmp1)) ) )
{
if( (RunYue == 0) && (nlMonth == atoi(runyue)) )
{
RunYue = 1;
}
else
{
RunYue = 0;
nlMonth++;
}
nlDay=1;
}
}
/*
所对应的农历年份与春节年份相同,月份和日期为所计算的值
*/
structNlDate->iYear = structYuanDanDate.iYear;
structNlDate->iMonth = nlMonth;
structNlDate->iDay = nlDay;
structNlDate->iMonthIsRun = RunYue;

if(RunYue != 1)
{
memcpy(tmp,daList[structNlDate->iYear-1900]+structNlDate->iMonth-1,1);
}
else
{
memcpy(tmp,daList[structNlDate->iYear-1900]+12,1);
}

if( atoi(tmp) == 1)
{
structNlDate->iMonthDayNum = 30;
}
else
{
structNlDate->iMonthDayNum = 29;
}

}

int GetSepDayNum(MYDATE structYlDate0 ,
MYDATE structYlDate1 )
{
int iSepDayNum,i;
/*
规定iMonth0和iDay0为基准时间,如果要计算的日期比基准时间小,
则返回无效值-1
*/
if(structYlDate1.iYear < structYlDate0.iYear)
{
return -1;
}
else
{
if(structYlDate1.iYear == structYlDate0.iYear)
{
if(structYlDate1.iMonth <= structYlDate0.iMonth)
{
if(structYlDate1.iMonth == structYlDate0.iMonth)
{
if(structYlDate1.iDay < structYlDate0.iDay )
{
return -1;
}
}
else
{
return -1;
}
}
}
}
/*
需要分3种情况进行分析:
1.要求的日期与春节不同年
2.要求的日期与春节同年,不同月
3.要求的日期与春节同年,同月,不同日
*/
if(structYlDate1.iYear>structYlDate0.iYear)/*不同年*/
{
/*iYear0年不足月的天数*/
iSepDayNum=yl_MonthDays[structYlDate0.iMonth]-structYlDate0.iDay;
/*iYear0年足月的天数*/
for(i=structYlDate0.iMonth+1;i<13;i++)
{
iSepDayNum += yl_MonthDays[i];
}
/*iYear1年足月的天数*/
for(i=1;i<structYlDate1.iMonth;i++)
{
iSepDayNum += yl_MonthDays[i];
}
/*iYear1年不足月的天数*/
iSepDayNum += structYlDate1.iDay;
/*如果iYear0年春节是2月或2月以前,并且该年为闰年,则天数加1*/
if(structYlDate0.iMonth <= 2)
{
if ( (structYlDate0.iYear%4==0)||
((structYlDate0.iYear % 100== 0)&&(structYlDate0.iYear % 400 == 0)) )
{
iSepDayNum++;
}
}
/*如果要求的日期是iYear1年2月以后,并且该年为闰年,则天数加1*/
if(structYlDate1.iMonth > 2)
{
if ( (structYlDate1.iYear%4==0)||
((structYlDate1.iYear % 100== 0)&&(structYlDate1.iYear % 400 == 0)) )
{
iSepDayNum++;
}
}
}
else
{
if(structYlDate1.iMonth >= structYlDate0.iMonth)
{
if(structYlDate1.iMonth == structYlDate0.iMonth)/*同年,同月,不同日*/
{
iSepDayNum = structYlDate1.iDay-structYlDate0.iDay;
}
else/*同年,不同月*/
{
/*不足月的天数*/
iSepDayNum=yl_MonthDays[structYlDate0.iMonth]-structYlDate0.iDay;
/*足月的天数*/
for(i=structYlDate0.iMonth+1;i<structYlDate1.iMonth;i++)
{
iSepDayNum += yl_MonthDays[i];
}
/*不足月的天数*/
iSepDayNum += structYlDate1.iDay;
if(structYlDate0.iMonth == 2)
{
if ( (structYlDate1.iYear%4==0)||
((structYlDate1.iYear % 100== 0)&&(structYlDate1.iYear % 400 == 0)) )
{
iSepDayNum++;
}
}
}
}
}
return iSepDayNum;
}
void GetMonthInfo(MYDATE *structMonthInfo,MYDATE preMonthInfo)
{
unsigned char tmp[2]={0};
int runyue;
memcpy(tmp,daList[preMonthInfo.iYear-1900]+13,1);/*闰月月份*/
runyue=atoi(tmp);
/*
判断某一个月是否为闰月的条件是:
1.上一个月一定不是闰月
2.该月的月份与闰月的月份值相同
否则,该月一定不是闰月

如果该月是闰月,则一定不会涉及到跨年度的问题,如果该月不是闰月,则可能
涉及到跨年度的问题
*/
if( (preMonthInfo.iMonthIsRun != 1) &&
(preMonthInfo.iMonth == runyue) )
{
structMonthInfo->iYear = preMonthInfo.iYear;
structMonthInfo->iMonth = preMonthInfo.iMonth;
structMonthInfo->iDay = preMonthInfo.iDay;
structMonthInfo->iMonthIsRun = 1;
memcpy(tmp,daList[structMonthInfo->iYear-1900]+13,1);/*闰月月份*/
if(atoi(tmp)==1)
{
structMonthInfo->iMonthDayNum = 30;
}
else
{
structMonthInfo->iMonthDayNum = 29;
}
}
else
{
/*
是否跨年度
*/
if(preMonthInfo.iMonth < 12)
{
/*年度不变,月份加1*/
structMonthInfo->iYear = preMonthInfo.iYear;
structMonthInfo->iMonth = preMonthInfo.iMonth+1;
}
else
{
/*年度加1,月份变为1月*/
structMonthInfo->iYear = preMonthInfo.iYear+1;
structMonthInfo->iMonth = 1;
}
structMonthInfo->iDay = preMonthInfo.iDay;

memcpy(tmp,daList[structMonthInfo->iYear-1900]+structMonthInfo->iMonth-1,1);
if(atoi(tmp) == 1)
{
structMonthInfo->iMonthDayNum = 30;
}
else
{
structMonthInfo->iMonthDayNum = 29;
}
structMonthInfo->iMonthIsRun = 0;
}
}


搜索更多相关主题的帖子: 万年历 WEEK LOOK define DATE 
2006-04-23 20:20
zhangpeng
Rank: 1
等 级:新手上路
帖 子:31
专家分:0
注 册:2006-4-9
得分:0 

还请高手指点迷津!


2006-04-24 13:56



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-59546-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016710 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved