如何求某一天是星期几?

QmStar 2001-07-30 03:23:04
加精
...全文
599 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hsentao 2002-01-26
  • 打赏
  • 举报
回复
几年中国银行软件研发中心到西安来招聘,就出了一道类似的题目,让写流程图,只要你想到先算出当前天与已知日期的天数差,在利用星期的周期性,就可以算出当前日期是星期几了,只是你在算当前日期与已知日期的天数差的时候,要注意到润年和润月以及各个月份天数不同就容易了。
zwfwind 2001-12-28
  • 打赏
  • 举报
回复
A=(y+[y/4]-[y/100]+[y/400]+x ) mod 7
就是这个最简单啦!!
^_^
Suddy 2001-08-01
  • 打赏
  • 举报
回复
我从来不算这些,明明在库函数里有的东西
Arter 2001-08-01
  • 打赏
  • 举报
回复
高斯--泽勒公式:

A=(y+[y/4]-[y/100]+[y/400]+x ) mod 7
星期几:A
(A=0 为星期 天!)
公元年: y
天数 :x ( 由当年月份和日期定,即距离当年初的天数。例:2001/3/1 x=31+28+1 )
andrew80 2001-07-31
  • 打赏
  • 举报
回复
贴出来吧:
再谈星期的计算

“让我们看看1752年9月14号这个星期四吧,我们的公式最远只能推算到这里了。”
——Kim S. Larsen

“从公元元年1月1日开始到现在,每一天都是连续的。”
——于鹏

“西方历法的第一次改革是罗马朱利乌斯·凯撒大帝引进的。他采用的四年一闰的闰年方式。由于一个太阳年不刚好是365.25天,而是 365.242199…天。到16世纪,每年11分14秒的误差已经累积成10天,也就是历法上多了10天。于是教皇格利戈里八世进行了一次校正。他在1582年2月24日以教皇训令颁布,将1582年10月5日至14日抹掉,并且对原来的闰年方法进行了校正。经过校正的历法叫格利戈里历法,也就是我们现在用的公历。1752年,英国人决定采用格利戈里历法,不过从1582年到那时,历法又多出了1天,所以英国议会在1752年作出决定,抹掉11天——1752年9月3日至13日。”

日期的限制是Kim S. Larsen算法的问题吗?不。
公元元年1月一日开始到现在,每一天都是连续的吗?不。
一个简单的方法就可以证明上述事实——用Linux的cal命令。启动你的Linux在#提示符下输入
cal 9 1752
你会看到:
September 1752
Su 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天的九月。
让我们来看看这两个算法,Kim S. Larsen博士的算法和于鹏同学的算法在本质上其实是相同的。只不过在实现的细节上略有不同。如果让两个算法去计算同一天(无论在1752年9月14日之前还是之后)是星期几,二者的答案肯定是相同的。让我们来分析一下吧。
首先,他们把日期对星期的决定作用都分为年、月、日三个决定因素。对于年的因素,从两者的计算公式 就能看出是相同的;对于日的因素,两者都是直接计入,故也是相同的;而对于月的因素,Kim S. Larsen博士构造了一个公式,(一个非常巧妙的公式,)通过以月份为自变量算出的函数值作为对星期的影响量。而于鹏同学采用了查表的方法,即先构造好一个以月份为索引的表对于相应的月份,通过查表得出其对星期的影响量。(以switch语句实现)不妨作如下演算:(为了一致起见,采用一、二月作为上年的十三、十四月。这是一个非常聪明的方法。)用于鹏同学的方法建表,并对7取模(表一)。再建立Kim S. Larsen函数 的函数值表(表二)。很显然二者是相同的。


三月 0 0 三月 0
四月 31 3 四月 3
五月 61 5 五月 5
六月 92 1 六月 1
七月 122 3 七月 3
八月 153 6 八月 6
九月 184 2 九月 2
十月 214 4 十月 4
十一月 245 0 十一月 0
十二月 275 2 十二月 2
十三月 306 5 十三月 5
十四月 337 1 十四月 1

表一 表二

其次,在处理闰年2月29日的问题上,两者的做法略有不同,但效果还是相同的。Kim S. Larsen博士采用的方法相当高明,他把二月排在一年的最后,管他闰不闰,反正是最后一天。而于鹏同学加了一个if分支,直观有效。
大师不愧为大师,设计的算法简洁、优美;而于鹏同学的算法,简单易懂,并且效率并不差。
好了,该解决这个“历史遗留问题”了。其实,并没有什么数学公式能算出指定日期是星期几,我们可以试着拼凑一个,不过何必呢?加个if分枝不就解决问题了吗?(Kim S. Larsen算法+于鹏思想)对Kim S. Larsen 博士的程序作一些必要的添加,可得到突破1752年9月14日日期限制的C语言程序。
/*C++Builder5下编译通过*/
/*假设输入的是正确的日期*/
#include <stdio.h>
char *name[] = { "Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
void main(){
int D,M,Y,A;
printf("Day: "); fflush(stdout);
scanf("%d",&D);
printf("Month: "); fflush(stdout);
scanf("%d",&M);
printf("Year: "); fflush(stdout);
scanf("%d",&Y);
if ((M == 1) || (M == 2)){/*一月、二月当作前一年的十三、十四月*/
M += 12;
Y--;
}
if ((Y < 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("It's a %s.\n",name[A]);
}

另外:
1.公元1年1月1日是星期六。
2.如果有朋友对这个问题感兴趣,或是有什么好的算法,欢迎和我联系。我的联系方法是:andrew80@163.net。
3.据说现行公历2800年左右还会有一天的误差,那时程序又要修正了。:)
lifanxi 2001-07-31
  • 打赏
  • 举报
回复
嘻嘻,看看<十万个为什么>数学卷吧。上面有公式的。好像与frman的差不离,记不清了。
ExitWindows 2001-07-31
  • 打赏
  • 举报
回复
up
Puma_zcx 2001-07-31
  • 打赏
  • 举报
回复
今年四月份的《程序员》杂志上有解答.
xiaolun 2001-07-31
  • 打赏
  • 举报
回复
Agree with upstairs.
andrew80 2001-07-30
  • 打赏
  • 举报
回复
哈!上面这种方法不完全正确。
看看今年四月份的《程序员》杂志吧!
frman 2001-07-30
  • 打赏
  • 举报
回复


请注意这样一个事实,即从公元元年一月一日开始到现在,每一天都是连续的,而每个星期有7天,也是连续的,也就是说日期和星期是一对一的,没有断档现象。我的基本思想是计算出当前天是从公元元年一月一日开始的第几天,再利用星期的周期性来计算公元任何一天是星期几。
假设当前年份为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)/400)。我们再补上从当前1月1日开始到当前天的天数e,即为所求。即:365*(y-1)+((y-1)/4-(y-1)/100+(y-1)/400)+e。它的值即为当前天是从公元元年一月一日开始算起的第几天。补上一个x(x是与公元元年一月一日是星期几有关的一个0~6的整数),并将这个表达式赋给变量t,即:t=x+365*(y-1)+((y-1)/4-(y-1)/100+(y-1)/400)+e再用t除以7,余几即为星期几(余0为星期日)。
下面讨论x的求法,如果知道公元元年一月一日是星期几,就可以直接得到x的值,但现在公式还没有求出来,不知道公元元年一月一日是星期几。不过没关系,毕竟知道最近的日期是星期几。不妨看一下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

以下是这种算法的C语言程序:

#include<stdio.h>
char *name[]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
void main(void)
{
int d,m,y,e,t,f;
printf("请输入日:");
fflush(stdout);
scanf("%d",&d);
printf("请输入月:");
fflush(stdout);
scanf("%d",&m);
printf("请输入年:");
fflush(stdout);
scanf("%d",&y);
switch(m)
{
case 1:e=d;break;
case 2:e=31+d;break;
case 3:e=59+d;break;
case 4:e=90+d;break;
case 5:e=120+d;break;
case 6:e=151+d;break;
case 7:e=181+d;break;
case 8:e=212+d;break;
case 9:e=243+d;break;
case 10:e=273+d;break;
case 11:e=304+d;break;
case 12:e=334+d;break;
default:return;
}
if(y%4==0&&y%100!=0||y%400==0)
if(m>2)
++e;
--y;
t=y+y/4-y/100+y/400+e;
f=t%7;
printf("这一天是 %s\n",name[f]);
}

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧