2021民间实用万年历-民间通用万年历.doc
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《2021民间实用万年历-民间通用万年历.doc》由会员分享,可在线阅读,更多相关《2021民间实用万年历-民间通用万年历.doc(65页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、2021民间实用万年历|民间通用万年历万年历算法研究及实现第5卷 第4期 中 国 水 运 Vol.5 No.4 2007年 4月 China Water Transport April 2007万年历算法研究及实现张剑锋 陈慕君 摘 要:万年历是一个经典的算法问题,在教学过程中可以作为实例进行分析讲解,具有较高的学习分析价值,也具有一定的实用价值,结合不同的方法,本文有一个系统全面的介绍。 关键词:万年历 算法 阴历 阳历 闰年中图分类号:TP29 文献标识码:A 文章编号:1006-7973(2007)04-0143-02万年历是一个古老而又经典的算法问题,已经有不少的实现方法,但是都多少会
2、存在一些问题和不足,在这里对此算法做一个系统的分析与介绍,先撇去农历与公历之间的转化,只做公历与星期的讨论。注意这样一个事实:从公元元年一月一日开始到现在,每一天都是连续的,而每个星期有七天,也是连续的,也就是说日期和星期是一对一的,没有断档现象。基本思想是:计算出当前天是从公元元年一月一日开始的第几天,再利用星期的周期性来计算公元任何一天是星期几。假设当前年份为y,并忽略闰年,则从公元元年一月一日到y-1年共有365*(y-1)天,加上闰年多出来的天数,即加上1*(y-1)/4-(y-1)/100+(y-1)/400),得365*(y-1)+(y-1)/4-(y-1)/100+(y-1)/4
3、00)。我们再补上从当前1月1日开始到当前天的天数e,即为所求。即365*(y-1)+(y-1)/4-(y-1)/100+(y-1)/400)+e。 它的值即为当前天是从公元元年一月一日开始算起的第几天。补上一个x(x是与公元元年一月一日是星期几有关的一个06的整数),并将这个表达式赋给变量t,即:t=x+365*(y-1)+(y-1)/4-(y-1)/100+(y-1)/400)+e,再用t除以7,余几即为星期几(余0为星期日)。下面讨论x的求法,如果知道公元元年一月一日是星期几,就可以直接得到x的值,但现在公式还没有求出来,不知道公元元年一月一日是星期几。不过没关系,毕竟知道最近的日期是星
4、期几。不妨看一下2001年1月1日是星期几,结果是星期一,代入公式得t=x+730516,用730516除以7,得104355,余数是1,则为了保证2001年1月1日是星期一,取x 为0,所以公元元年一月一日也是星期一。至此,得到了完整的公式:t=365*(y-1)+(y-1)/4-(y-1)/100+(y-1)/400)+e, 再将它做一下改进,我们将公式变形为:t=(52*7+1)*(y-1)+(y-1)/4-(y-1)/100+(y-1)/400)+e, 利用星期的周期性,将52*7+1从公式中删除为: t=(y-1)+(y-1)/4-(y-1)/100+(y-1)/400)+e,T;v
5、oid main( ) int d,m,y,e,t,f;printf(INPUT THE DAY:); scanf(%d,&d);printf(INPUT THE MONTH:); scanf(%d,&m);printf(INPUT THE YEAR:); scanf(%d,&y); switch(m) case 1:e=d;peak; case 2:e=31+d;peak; case 3:e=59+d;peak; case 4:e=90+d;peak; case 5:e=120+d;peak; case 6:e=151+d;peak; case 7:e=181+d;p
6、eak; case 8:e=212+d;peak; case 9:e=243+d;peak; case 10:e=273+d;peak; case 11:e=304+d;peak; case 12:e=334+d;peak; default:return; if(y%4=0&&y%100!=0|y%400=0) if(m2) +e; -y;以下是这种算法的C语言程序: #include char*name=SUN,MON,THU,WED,THU,FRI,SA 收稿日期:2007-3-20作者简介:张剑锋 男(1981-) 河南农业职业学院 教师 (451450) 研究方向:计算
7、机科学技术 144 中 国 水 运 第5卷 t=y+y/4-y/100+y/400+e; f=t%7;printf(TODAY IS %sn,namef); 到此,似乎是问题基本都解决了。我们先不说这个算法本身,我们再来了解一下历法的知识。国际上使用的历法有几十种,其中最主要的有公历、回历和佛历,即所谓三大历法。不管是哪种历法,无非是对年月日的安排。这些安排主要依据天体的运动。西方历法的第一次改革是罗马朱利乌斯凯撒大帝引进的。他采用的四年一闰的闰年方式。由于一个太阳年不刚好是365.25天,而是 365.242199天。到16世纪,每年11分14秒的误差已经累积成10天,也就是历法上多了10天
8、。于是教皇格利戈里八世进行了一次校正。他在1582年2月24日以教皇训令颁布,将1582年10月5日至14日抹掉,并且对原来的闰年方法进行了校正。经过校正的历法叫格利戈里历法,也就是我们现在用的公历。1752年,英国人决定采用格利戈里历法,不过从1582年到那时,历法又多出了1天,所以英国议会在1752年作出决定,抹掉11天1752年9月3日至13日。这是怎么搞的,我们不是说过这样一个事实:从公元元年一月一日开始到现在,每一天都是连续的,而每个星期有七天,也是连续的,也就是说日期和星期是一对一的,没有断档现象。现在居然又出现了特殊状况,我们以前的算法都是错的。不过一个简单的方法就可以证明确实存
9、在着断档用Linux的cal命令。启动你的Linux在#提示符下输入cal 9 1752 你会看到:September 1752Su Mo Tu We Th Fr Sa 1 2 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 有趣吧一个只有19天的九月。那我们的算法也要跟着要大变身了。不用着急,我们分析一下当前的情况:就是在原来的算法的基础上,出现了一个比较特殊的1752年,我们的就针对这个特殊的地方进行局部的调整,看看有什么可以办法解决这个问题。不妨作如下演算:为了一致起见,采用一、二月作为上年的十三、十四月。采用查表的方法建表,并对7取
10、模(表一),再建立函数值表(表二),很显然二者是相同的。三月 0 0 四月 31 3 五月 61 5 六月 92 1 七月 122 3 八月 153 6 三月 0 四月 3 五月 5 六月 1 七月 3 八月 6T;void main() int D,M,Y,A; printf(Day: ); scanf(%d,&D); printf(Month: ); scanf(%d,&M); printf(Year: ); scanf(%d,&Y); if (M = 1) | (M = 2)/*一月、二月当作前一年的十三、十四月*/ M += 12; Y-; if (Y <
11、 1752)|(Y = 1752)&&(M < 9)|(Y = 1752)&&(M = 9)&&(D < 3)/*判断是否在1752年9月3日前*/A = (D + 2*M + 3*(M+1)/5 + Y + Y/4 +5) % 7; /*1752年9月3日前的公式*/else A = (D + 2*M + 3*(M+1)/5 + Y + Y/4 - Y/100 + Y/400) % 7;/*1752年9月3日后的公式*/ printf(TODAY IS %sn,namef); 参考文献1 严蔚敏、吴伟民.数据结构.M.北京:清华大学
12、出版社.1992.2 网冠科技.C语言时尚编程百例.M.北京:机械工业出版社.2004.九月 184 2 十月 214 4 十一月 十二月 十三月 十四月 九月 2 十月 4十一月 十二月 十三月 十四月0 2 5 1245 0 275 2 306 5 337 1表一 表二在处理闰年2月29日的问题上,也有两种方法,第一:把二月排在一年的最后,管他闰不闰,反正是最后一天,这种算法设计的简洁、优美。第二:加了一个if分支,简单易懂,直观有效,且效率并不差。好了,该解决这个“历史遗留问题”了。其实,并没有什么数学公式能算出指定日期是星期几,我们可以试着拼凑一个,不过何必呢?加个if分支不就解决问题
13、了吗?下面就可得到突破1752年9月14日日期限制的C语言程序。/*假设输入的是正确的日期*/ #include char*name=SUN,MON,THU,WED,THU,FRI,SA程序设计工程实训报告万年历系统 仲恺农业工程学院课程设计报告 编写一万年历系统 课程名称 C语言程序设计工程训练及编程比赛 姓 名 Angus院(系) 信息科学与技术学院 专业班级 计算机科学与技术XXX班 学 号 201320244225 指导教师 石玉强 仲恺农业工程学院教务处制 二O一四年六月目 录1 需求分析 . 1 2 系统总框图和功能模块说明 . 12.1 系统界面图 . 1 2.2 功能模块说明
14、. 1 3系统设计 . 1 3.2主要功能函数 . 2 3.3 关键函数的流程图 . 2 4 系统调试 . 4 4 5总结 . 4 源程序清单 . 5 运行环境:电脑型号 技嘉 台式电脑操作系统 Windows 7 旗舰版 64位 SP1 ( DirectX 11 )处理器 英特尔 Xeon(至强) E3-1230 V2 3.30GHz 四核 主板 技嘉 B75M-D3V (英特尔 Ivy Bridge - B75 Express 芯片组) 内存 8 GB ( 威刚 DDR3 1600MHz )主硬盘 希捷 ST500DM002-1BD142 ( 500 GB / 7200 转/分 ) 显卡
15、ATI Radeon HD 7750 Series ( 1 GB / 迪兰恒进 ) 显示器 LG GSM4B6F W1942 ( 19.1 英寸 ) 声卡 瑞昱 ALC887 英特尔 Panther Point High Definition Audio Controller 网卡 瑞昱 RTL8168E PCI-E Gigabit Ethernet NIC / 技嘉 编程环境:Microsoft Visual Studio Ultimate 2013 1 需求分析要求:模仿现实生活中的挂历。当前页以系统当前日期的月份为准显示当前月的每一天(显示出日及对应的星期几)。 当系统日期变到下一月时,
16、系统自动翻页到下一月。 还是适当添加实时时间显示的功能。2 系统总框图和功能模块说明2.1 系统界面图 *显示程序信息* 显示当前年月日 显示当月的日期表 *实时显示当时时间* 界面设计图2.2 功能模块说明打开程序,程序会自动获取系统当前的时间并将系统返回的时间格式进行转换,转换后的年月日格式通过函数绘制出当月的日期表,最后将时间格式一同显示。最后使用函数让整体自动刷新。即可实现实时显示时间日期的功能。 3 系统设计#include 标准输出输入头文件#include Sleep函数的头文件,控制循环的停顿 #include time函数头文件,获取及处理系统时间所用 #include st
17、rlen,strtok,strcpy等函数的头文件,进行对字符串和字符的处理。#include atoi函数的头文件,可以将数组字符串转换为数值。 #include system函数头文件,可以改变背景及前景颜色,清除屏幕等功能3.2主要功能函数daysofmonth(int year, int month) 自定义函数daysofmonth(year,month)通过输入年份year和月份month来计算某年某月的天数。分别有4种情况(28,29,30,31)共4种返回值,通过返回值来确定一个月的天数。cvrt2num(char *diff) 自定义函数cvrt2num(diff)(Conv
18、ert2number),由于通过系统获取的时间包含字符串,在处理过程中比较麻烦,故用此函数来进行对比,将输入的月份转换成数字形式让操作更简便。 3.3 关键函数的流程图Daysofmonth函数流程图:cvrt2num(char *diff)函数流程图: 4 系统调试 4 总结1.字符串的处理问题。通过上网查阅资料找到获取系统时间的方法,不过获得的时间是一段长字符串,其中使用空格隔开,输出格式为*week month day time yearn*,通过使用strtok函数,以输出格式的空格为标示符,将字符串进行分割并存储到二维数组中。其中最后一组year字符串中的最后一个字符多出了一个换行符
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2021 民间 实用 万年历 通用
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内