公历历法

2022-07-09 03:36:19   文档大全网     [ 字体: ] [ 阅读: ]

#文档大全网# 导语】以下是®文档大全网的小编为您整理的《公历历法》,欢迎阅读!
历法,公历


【公历历法】

公历历法很简单,年有润年(LeapYear)和平年之分,平年每月天数恒为: 月份 十一 十二 天数 31 28 31 30 31 30 31 31 30 31 30 31 365天。润年366天,二月多一天,29天。

【润年判断】

如果年份数能被4整除但不能被100整除或者能被400整除者,为润年。

400年刚好一个轮回】

很容易想到每400年内的润年数相等,即刚好一个轮回,400年有多少个润年?被4整除的100个,100整除的有4个,400整除的只有1个,所以一共有100-4+1=97个润年,所以400年共有(365*400+97)天,即146097天,除70

也就是说200111日的星期数与111日的星期数相同,翻出日历一看,星期一,我不知道上帝什么时候造的人,或许是111日。这样一来,任何一个日期我们都可以把它折算到0~399年之内的日期来算,0年的说法不准确,或许没有,但不影响这个数学论,我们只是借它来推一推而已。

【起初的400年】

如果每一年都是平年,即365天,除71,也就是说如果不遇上润年,每往下一年就会使星期数增一。同样的道理,如果遇上润年,则多增一。我们要算的也就是把润年数算出来就行了,很容易,如果是y年(0<=y<400,则遇到的润年数为[y/4]-[y/100]+1,为什么要+1因为0年也是润年(被400整除)然后把y自己身加起来就得到年指数:(y+[y/4]-[y/100])%7它影响着星期的轮转。(其中[]表示取整,%表示取余,%7表示除以7得到的余数)

【月份的变迁】

月份的天数也不一定,所以不好直接用数学公式来表示,所以列一个表,表中对应数为星期的月指数。前面有数据:(假设为平年)

月份 十一 十二 天数 31 28 31 30 31 30 31 31 30 31 30 31 每月对应前面过去的天数: 月份 …… 天数 0 31 31+28 …… 对天数对7除取余得:

月份 十一 十二 天数 0 3 3 6 1 4 6 2 5 0 3 5 用一个数组保存下来:

R[13]={0,0,3,3,6,1,4,6,2,5,0,3,5};

设月为m,则月份的影响指数为R[m],它影响着星期的轮转。

【全部加起来取7的余数】

最后剩下天指数,这很容易,直接加起来就行了,所以最后得到一个总的表达式:(先把年400除取其余数:Year=Year%400

Week=(Year+[Year/4]-[Year/100]+R[Month]+Day+C)%7






最后有一个常数C如何确定这个常数,拿一个平年的正常日期数代进来,和星期数比较就可以确定C

200111日是星期一,所以(1+0-0+0+1+C)%7=1,即(2+C)%7=1 ==> C=6

【遇到润年C会变】

如果没有拿足够的数据来验证,我不敢说C是常数。举几个例子:

200011日星期六,如果C=6,按公式算出来:(0+0-0+0+1+6)%7=0,星期天,错了一天,哪里错了?

前面算月指数的时候是按平年来算的,如果遇到润年,多的一天是在229日,如果在这之前的日期,润年不润,所以年指数会多算一天,如果在这之后,润年已润,年指数已经计算在内,所以月指数同样按平年来算不误,如200051日星期一,按公式:(0+0-0+1+1+6)%7=1,完全正确。

所以改进的做法是先判断是否是在润年而且月份数小于3,如果是,则C=5,否则C=6

流程图






#include //包含stdio函数库

int week(int y,int m,int d); //子函数week明,因为子函数在主函数之前故需要声明

int main() //主函数 {

char wk[7][3] = {{""},{""},{""},{""},{""},{""},{""}}; //字符数组定义

int year, month, day, w; //年、月、日变量定义

scanf("%d %d %d", &year, &month, &day); //输入年、月、

w = week(year, month, day); //子函数调用

printf("%d%d%d %s", year, month, day, wk[w]); //格式输出:XXXXXX 星期X }

int week(int y,int m,int d) //子函数week函数 {

static int r[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; //静态数组 int c,w; //变量定义

y %= 400; //判断是否为闰年

if ((y==0||y%4==0&&y%100!=0)&&m<3) //基姆拉尔森计算公式计算星期几 c = 5; else c = 6;

w = (y+y/4-y/100+r[m]+d+c)%7;

return w; //返回计算得的星期几结果 }

关键函数部分第一位解答得很详细嘛~~~~




本文来源:https://www.wddqxz.cn/22a4751a6c85ec3a87c2c5a8.html

相关推荐