教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 高等教育 >

阳历到阴历的转换

来源:网络收集 时间:2024-05-06
导读: /*************************************************************************************************** 哈尔滨市闲人无事发呆有限公司 鼓 捣 所 鼓捣总部 Q Q:958415720 Email:yiwanfuweng@126.com 说 明: 经过几天日子的鼓捣,弄出来了这个万年历阳历

/*************************************************************************************************** 哈尔滨市闲人无事发呆有限公司 鼓 捣 所 鼓捣总部 Q Q:958415720 Email:yiwanfuweng@126.com

说 明: 经过几天日子的鼓捣,弄出来了这个万年历阳历转换阴历的转换代码,由于网上很多的代码写的

很乱,起初也不懂关于一些天文的知识,看的迷糊,让我很是无奈就想还是自己写吧偶尔在网上 找到了一个PDF文档叫《公历与农历日期的转换》 让我明白了许多 从而就开始花了一天的时间写 出来了。希望想要做万年历的人拿去用 这是在VC++ 6.0 平台的 直接就可以移植到51,AVR,STM32等等上 的。

作 者: 崔殿川

***************************************************************************************************/

#include

#include \ //年份数据表包含头文件

#include \数据类型宏定义包含头文件(UINT8 UINT16 UINT32....)

UINT8 LunarYearNum=0,LunarMonNum=0,LunarDayNum=0;//转化回来的阴历数值就存在相应的变量中(全局的)

UINT16 DayDataBase[12]={0,32,59,90,120,151,181,212,243,273,304,334};

/**********************************************************************************

函 数 名:获取农历的大小月份

入口参数:Mon: 当年的月份数(农历的0~13) YearOffsetAdd: 年份数据表里的偏移地址 返 回 值:0:大月份(30天) 1:小月份(29天) 说 明:大小月的获取主要是从年份数据表里三个字节的高13位当中获取 如果对应为是1则

是大月30天,小月29天

************************************************************************************/

UINT8 GetLunBig_LitMon(UINT8 Mon,UINT16 YearOffsetAdd) { UINT8 i=0;

(YearDataBase[YearOffsetAdd][(Mon<=9)?(Mon/5):((Mon<=12)?(Mon/10):(Mon/5))]&((Mon/5)?((Mon==13)?(0x80):(0x80>>(Mon-5))):(0x08>>(Mon-1))))? (i=1):(i=0); return (i); }

/**********************************************************************************

函 数 名:公历到农历的转换

入口参数:对应着公历(阳历)的年(0~99),月(0~12),日(0~31) 返 回 值:0

***********************************************************************************/

UINT8 Solar2Luner(UINT8 SolarYearNum,UINT8 SolarMonNum,UINT8 SolarDayNum) { UINT8 LeapMonVal=0; //农历闰月天数值变量

UINT8 NewYearToYuanDan_Mon=0,NewYearToYuanDan_Day=0; //定义春节所在的月份数(不是1月就是2月) UINT8 YearFlag=0,MonPointer=0; //农历年的缓存标志和月份的偏移量 UINT8 temp=0; //春节距离元旦的天数

UINT16 TarGetDayT0YuanDan=0,YearOffsetAdd=0; //目标日期到元旦天数和年数据表的偏移地址

YearOffsetAdd=(SolarYearNum-1); //获取数据表地址

NewYearToYuanDan_Mon=(YearDataBase[YearOffsetAdd][2]&0x60)>>5; //计算春节所在的月份(不是1月就是2月)

NewYearToYuanDan_Day=(YearDataBase[YearOffsetAdd][2]&0x1f); //从年数据表里获取最后一个字节的第五位只要是计算春节到元旦的日期(Day的天数值) (NewYearToYuanDan_Mon==1)?(temp=NewYearToYuanDan_Day-1):(temp=NewYearToYuanDan_Day+31-1); //temp这才是通过上面得到的春节所在的月份之后最终计算出来春节距离元旦的总天数

TarGetDayT0YuanDan=DayDataBase[SolarMonNum-1]+SolarDayNum-1;//得到目标日期到元旦天数

if ((SolarMonNum>2) && !(SolarYearNum%4))//如果是闰年则加目标天数1 TarGetDayT0YuanDan+=1;

//==============================转化分两块(以春节作为转换中心) 目标日期距离春节前或者春节后=========================//

if(TarGetDayT0YuanDan>=temp) //目标日期在春节之后 {

TarGetDayT0YuanDan-=temp; //求2个天数的差值 SolarMonNum=1;

MonPointer=1; //这时目标值一定是在一月

(GetLunBig_LitMon(MonPointer,YearOffsetAdd))?(LeapMonVal=30):(LeapMonVal=29); //判断闰月的月份是大月还是小月 while(TarGetDayT0YuanDan>=LeapMonVal) //目标日期大于等于闰月(大小月)天数 { TarGetDayT0YuanDan-=LeapMonVal; MonPointer+=1; (GetLunBig_LitMon(MonPointer,YearOffsetAdd))?(LeapMonVal=30):(LeapMonVal=29); if(SolarMonNum==YearDataBase[YearOffsetAdd][0]>>4) //获取第一字节的高四位 (闰月月份的获取) { YearFlag=~YearFlag; if(!YearFlag) SolarMonNum+=1; } else SolarMonNum+=1; }

SolarDayNum=TarGetDayT0YuanDan+1; //最后农历日期天数的获取 }

else //目标日期在春节前 {

temp-=TarGetDayT0YuanDan; SolarYearNum-=1; YearOffsetAdd-=3; SolarMonNum=12;

(YearDataBase[YearOffsetAdd][0]>>4)?(MonPointer=13):(MonPointer=12);

(GetLunBig_LitMon(MonPointer,YearOffsetAdd))?(LeapMonVal=30):(LeapMonVal=29);

while(temp>LeapMonVal) {

temp-=LeapMonVal; MonPointer-=1; if(!YearFlag) SolarMonNum-=1;

if(SolarMonNum==NewYearToYuanDan_Day) YearFlag=~YearFlag;

(GetLunBig_LitMon(MonPointer,YearOffsetAdd))?(LeapMonVal=30):(LeapMonVal=29);

}

SolarDayNum=LeapMonVal-temp+1; //最后农历日期天数的获取 }

LunarYearNum=SolarYearNum; LunarMonNum =SolarMonNum; LunarDayNum =SolarDayNum;

return (0); }

/*********************************************************************************************** -函 数 名:星期修正

-入口参数:对应着公历(阳历)的年(0~99),月(0~12),日(0~31) -返 回 值:当天的星期 说 明: 公历日是非常有规律的所以公历日所对应的星期天可以通过计算直接得到理论上公元0 年1 月1 日为星期日 只要求得公历日离公元0 年1 月1 日的日子数除7 后的余数就是星期天为了简化计算采用月校正法根据公历 的年月日可直接计算出星期天其算法是日期年份所过闰年数月校正数之和除7 的余数就是星期天但如果是在 闰年又不到3 月份上述之和要减一天再除7 其1~12月的校正数据为6,2,2,5,0,3,5,1,4,6,2,4在本程序中采 用1 个字节表示年份闰年数也只计算1900 年以后的闰年数所以实际校正数据也和上述数据不同

详见PDF《公历与农历日期的转换》文档

************************************************************************************************/

#ifdef WEEKREVISE

UINT8 WeekDataBase[12]={6,2,2,5,0,3,5,1,4,6,2,4}; //月修正数据表

UINT8 WeekRevise(UINT8 SolarYearNum,UINT8 SolarMonNum,UINT8 SolarDayNum) {

return (!(SolarYearNum%4) && SolarMonNum<3)?(((SolarDayNum+SolarYearNum+(SolarYearNum/4)+WeekDataBase[SolarMonNum-1])%7)-1):((SolarDayNum+SolarYearNum+(SolarYearNum/4)+WeekDataBase[SolarMonNum-1])%7); }

#endif

int main() {

Solar2Luner(13,3,23);

printf(\ return 0; }

//***************************************************************************** 下面是数据类型宏定义.h文件

******************************************************************************* #ifndef _MYTYPE_H_ #define _MYTYPE_H_

#define UINT8 unsigned char #define UINT16 unsigned int #define UINT32 unsigned long

#define INT8 char #define INT16 int #define INT32 long

#endif

//***************************************************************************** 下面是年份数据表h文件

因为这里是在VC平台上的 就没有把数据表定义在ROM里 如果大家想要移植到51或者AVR等等处理器上 请自己更改、、、

******************************************************************************* #define WEEKREVISE //如果不使用星期修正注释掉这里

unsigned char YearDataBase[99][3]= {

{0x4d,0x4A,0xB8}, //2001 {0x0d,0x4A,0x4C}, //2002

阳历到阴历的转换.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/616670.html(转载请注明文章来源)
上一篇:优秀教师继续教育学习心得体会
下一篇:没有了
Copyright © 2020-2021 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)