求某一天是星期几

hemy818 2009-08-31 01:15:57
以下这六行代码 求某一天是星期几 相信不少朋友都看过
本菜水平太次 请懂的朋友给我详细解释一下 谢谢

int DayOfWeek(int y, int m, int d)
{
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
...全文
517 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
低头路过 2011-07-03
  • 打赏
  • 举报
回复
我对于这个帖子和回了这个帖子的同仁们表示崇高的敬意!生民不息,学习不止!!
dengxian 2009-10-09
  • 打赏
  • 举报
回复
学习了...
f22fbi 2009-08-31
  • 打赏
  • 举报
回复
将系统的时间设置到那一天,获取是星期几,然后再设置回来
my578009030 2009-08-31
  • 打赏
  • 举报
回复
学习。。。
selooloo 2009-08-31
  • 打赏
  • 举报
回复
代码本身没什么难懂的,
就y -= m < 3;稍显复杂,等价于if(m<3) y=y-1;(m<3成立的话表达式的值是1)
与其解释算法,不如解释规律,这段代码的精炼之处就在于static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};这组数据
把0到50年每月1日星期几打印出来就不难发现其中的规律
1,2月份星期,3-12月份星期呈现不同规律的循环,5年或6年或11年循环1次,而0,3和2, 5, 0, 3, 5, 1, 4, 6, 2, 4遵循着相同规律,而且0,3每次都出现在2, 5, 0, 3, 5, 1, 4, 6, 2, 4的下一年的1,2月份。从中可以找出很多这样的规律数组,但只有0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4能满足(y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;的要求。因为0,3与2, 5, 0, 3, 5, 1, 4, 6, 2, 4差1年,所以当月份小于3时就令年减1,使它和2, 5, 0, 3, 5, 1, 4, 6, 2, 4对齐。

(y + y/4 - y/100 + y/400 + t[m-1] + d) % 7就是蔡勒公式,只是把起始年改成0年,并对天数D进行了优化
lrujie 2009-08-31
  • 打赏
  • 举报
回复
int DayOfWeek(int y, int m, int d)
{
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
//(26 * (M+1) / 10)%7 -1,1、2月份M分别为13、14,即是连上一年的12月份,其他为各月的数值。(ttp://zthdd.bokee.com/6189963.html,1楼提供的)
y -= m < 3;
//1、2月算上一年的13、14月份,所当年减去一年。
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
//y 是为经过的平年数,
// (y/4 - y/100 + y/400)为总共经过的闰年数,闰年的总天比平年总天数多一天,

}
紫色动力 2009-08-31
  • 打赏
  • 举报
回复
mark
thy38 2009-08-31
  • 打赏
  • 举报
回复
学习了!
niimp2 2009-08-31
  • 打赏
  • 举报
回复
学习了
happysalay 2009-08-31
  • 打赏
  • 举报
回复
mLee79这个解释的已经比较清楚了,如果不嫌我再罗嗦两句:
知道一天是周几只需2个条件:
1、历史上某一天(如今天)是周几
2、你要查询的日期与你已知日期差的天数。
先说static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};怎么来的
你这个程序可以认为是以某年1月1日(周一为基准的),所以t[0] = t[1-1] = 0;
1月有31天,31%7=3,所以呢,t[1] = 3,这样推下来就得到
{0,3,3,6,1,4,6,2,5,7,3,5}
怎么计算天数呢?有了这个数据就不用考虑几月了,把月份差异算是即可,但要考虑到润年,于是有
(y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
y-= m<3什么意思呢?
润年是多一天,但是只有三月以后才多啊,前两个月没有,于是y-=m<3。
不是润年也要减啊,于是干脆从三月开始都减一,于是有了
{0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}
hemy818 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 jamesf1982 的回复:]
引用 9 楼 hemy818 的回复:
不要给我新的代码
把我原代码解释一下就好了
因为这个代码优雅 我才喜欢的


我觉得1L讲的很清楚了,非常好的方法
[/Quote]

有很多细节没讲清楚
真要是叫你写 代码你不一定写出来

我不再说了 按时结帖就是了
james_hw 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hemy818 的回复:]
不要给我新的代码
把我原代码解释一下就好了
因为这个代码优雅 我才喜欢的
[/Quote]

我觉得1L讲的很清楚了,非常好的方法
hemy818 2009-08-31
  • 打赏
  • 举报
回复
不要给我新的代码
把我原代码解释一下就好了
因为这个代码优雅 我才喜欢的
wustzrx 2009-08-31
  • 打赏
  • 举报
回复
unsigned char CaculateWeek()
{
unsigned short tmp;
unsigned char year,month,day;
unsigned short month_max[]={
0,
0,
31,
31+28,
31+28+31,
31+28+31+30,
31+28+31+30+31,
31+28+31+30+31+30,
31+28+31+30+31+30+31,
31+28+31+30+31+30+31+31,
31+28+31+30+31+30+31+31+30,
31+28+31+30+31+30+31+31+30+31,
31+28+31+30+31+30+31+31+30+31+30,
31+28+31+30+31+30+31+31+30+31+30+31
};

tmp = 6+year+(3+year)/4+month_max[month]+day-1;

if ((year%4 == 0) && (month>2))
tmp = tmp+1;

return tmp%7;
}
hmlog 2009-08-31
  • 打赏
  • 举报
回复
日期问题我一般用Julian Day,这些公式都是用数论推导出来的,复制下来存放好就行了。
hemy818 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lovefqing 的回复:]
没看懂,我测试了一下,是正确的,这段代码估计是别人优化过后的代码了,如果不知道思想,光通过代码去猜测,并不是那么容易,能用就可以了,不用管它是什么意思。
[/Quote]

我喜欢算法 这个东西搞不懂 我会很难过的 真的
老A四十二号 2009-08-31
  • 打赏
  • 举报
回复
没看懂,我测试了一下,是正确的,这段代码估计是别人优化过后的代码了,如果不知道思想,光通过代码去猜测,并不是那么容易,能用就可以了,不用管它是什么意思。
mLee79 2009-08-31
  • 打赏
  • 举报
回复
简单可以这样弄:

求某天相对于 0000-1-1 (这天并不存在,现行历法从 1752-9-3 开始的,如果存在,这天实际上应该是 1-1-1 BC) 的天数:

const int mds[] = { 365 , 396 , 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
if( m <= 2 ) --y;
return y*365 + y/4 - y/100 + y/400 + mds[m-1] + d

并且 0000-1-1 这一天如果存在,它就应该是周六, 把 mds 的各项加上 6 ,然后将公式里的所有系数全部对7取模,就是你的公式了。。。

Paradin 2009-08-31
  • 打赏
  • 举报
回复
顶一个。以前没想过。
james_hw 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 mstlq 的回复:]
http://zthdd.bokee.com/6189963.html
蔡勒公式的由来……

楼主的式子应该是用t[m-1]替代了[26 * (M+1) / 10]%7
[/Quote]

好方法,以前都是直接调系统接口获取,第一次了解到这个公式
加载更多回复(1)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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