万年历的编程思路
最后,附上一份...知道我之前回答的地址。
/question/9433604.html
万年历,但不是阴历。
如何计算星期几?
发布于2005-10-11 21:43:00。
如何计算星期几?
-泽勒公式
历史上的某一天是哪一天?未来是哪一天?关于这个问题有很多公式(两个一般公式和一些分段公式),其中最著名的是泽勒公式。
即w = y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1。
公式中的符号有如下含义:w:周;c:世纪-1;y:年份(两位数);m:月(m大于等于3,但小于等于14,即在丘勒公式中,一年中的1和二月应视为13,上一年中的14,例如2003年的1应视为2002年的1。d:日;[]代表四舍五入,即只取整数部分。(c是世纪数减一,y是年份的后两位数,m是月份,d是天数。
65438+10月和2月要按上一年的65438+3月和65438+4月计算,这时C和Y都按上一年计算。)
计算出的w除以7,余数就是星期几。如果余数为0,则是星期天。
以65438+2049年10月1日(100周年国庆)为例,流程如下:
泽勒公式:w = y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1。
=49+[49/4]+[20/4]-2×20+[26× (10+1)/10]+1-1
=49+[12.25]+5-40+[28.6]
=49+12+5-40+28
=54(除以7和5)
也就是2049年6月10(100国庆)是星期五。
你的生日是哪一天(你出生的时候,今年,明年)?不妨试一试。
但上述公式只适用于1582 10 10月15之后的情况(当时教皇将朱利叶斯·凯撒制定的儒略历改为公历,也就是今天使用的公历)。
过程的演绎:(对推理不感兴趣的可以跳过)
周制度是一项具有古老传统的制度。据说因为圣经创世纪规定上帝用了六个
这一天是创世纪,第七天是休息日,所以人们以七天为一个周期来安排自己的工作和生活。
活着,周日是休息日。从实用的角度来看,以七天为一个周期也是合适的。地方
虽然中国传统的工作周期是十天(如王波《王腾亭序》中的“十休”),也就是说
意思是官员每十天工作一个周期,第十天休息),但后来也采用了西周制。
在日常生活中,我们经常会遇到知道今天是什么日子的问题。有时候,我们也想知道
道教历史上的某一天是星期几?通常,解决这个问题的有效方法是看日历,但我们从来不这样做。
随身携带一个日历,更不用说,一个有几千年历史的万年历。如果你想从事计算机编程
提前计算星期几,存储万年历更不现实。这个时候有办法打通吗
你通过了什么公式?今天是星期几?
答案是肯定的。其实我们经常这样做。先举个简单的例子。比如,知道吗
由于2004年5月的1是星期六,因此不难计算出2004年5月31日是世界无烟日。
走吧。我们可以从1数到31,同时数周,最后可以算出5月31是星期一。
其实用数学计算,不用掰手指。我们知道一周是一个七天的周期,所以五月1是一个星。
7天后的5月8日,也是周六。在日期上,8-1=7,是7的倍数。同样,五月15
5月22日和5月29日也是星期六,它们的日期和5月1的差分别是14、21和28。
是7的倍数。5月31呢?31-1=30,虽然不是7的倍数,但31除以7,余数是2。
也就是说,5月31的一周是5月1的一周之后两天。星期六后两天是星期一。
这个简单的计算告诉我们一个计算星期的基本思路:首先要知道要计算的日子。
前一天是星期几?以这一天为计算标准,相当于一次计算。
“起源”其次,我知道我要计算的日期和这个确定的日期之间有多少天,用这个日期除以7。
余数表示要计算的一周之后的第几天。如果余数是
0,表示这两天的星期是一样的。显然,如果作为“起源”的这一天被选为星期天,那么
余数正好等于星期几,所以计算更方便。
但是直接计算两天之间的天数还是比较繁琐。比如7月29日,1982,2004年5月。
1天的间隔是7947天,不能一下子算出来。包括三个时期:1,1982年7月29日。
该日期之后一年的剩余天数;二、1983-2003,二十一整年的所有日子;第三,从2004年开始
元旦到5月的天数1。第二段比较好算。等于21 * 365+5 = 7670天。添加它的原因是。
5,因为这个时期有五个闰年。第一段和第三段比较麻烦,比如第三段,需要放
将五月前四个月的天数加起来,加上日期值,即31+29+31+30+1 = 122天。同样,第一个
一个周期需要把7月以后5个月的天数加起来,加上7月剩余的天数,一个* * *就是155天。
所以* * *之间的总天数是122+7670+155=7947天。
仔细想想,如果选择“起源”日的日期为65438+2月31,那么第一段时间也是1。
对于全年来说,这样一来,第一期和第二期就可以合在一起,全年的总和正好相当于两个。
两个日期之间的年份差减一。如果“起源”日期被进一步选择为1公元前65438+31二月(或天文学
全年的总数正好是你要计算的那一天的年份减一,科学家用2月0日作为65438+31。这
样本简化后,你只需要计算两个时间段:一是这么多整年的总天数;第二,你要算的日子是这一天
一年中的哪一天?无独有偶,按照公历的年月设置,这向后推,公元前1 65438+2月31正好是。
星期天,也就是说,总天数除以7的余数正好是星期几。所以现在的问题是
只有一个:这么多整年有多少闰年。这就需要了解公历的闰规则。
我们知道,公历平均一年是365天,闰年是366天。设置闰的方法是被4整除的年份在
二月加一天,但不是能被100整除的闰,是能被400整除的闰。所以,像1600,2000,2400。
每年都是闰年,而1700、1800、1900、2100都是正常年份。根据公历,公元前1年也是闰年。
因此,对于从公元前1年(或公元0年)12 31年到某日Y年的所有整年。
闰年的数目等于
[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400],
[...]表示只取整数部分。第一项表示需要加上被4整除的年数,第二项表示需要去掉。
可被100整除的年数,第三项表示需要加上可被400整除的年数。y应该减1的原因是
示例中,我们得到了计算星期几的第一个公式:
w =(Y-1)* 365+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+d .(1)
其中d是一年中这一天的累计天数。计算出来的W是65438+公元前0年(或公元0年)65438+二月。
31和今天之间的天数。将w除以7,余数是多少,这一天就是一周中的某一天。例如,让我们
在2004年5月计算1:
w =(2004-1)* 365+[(2004-1)/4]-[(2004-1)/100]+[(2004-1)/400]+
(31+29+31+30+1)
= 731702,
731702/7 = 104528 ...6,余数是6,表示这一天是星期六。这是符合事实的。
上面的公式(1)虽然很精确,但是计算出来的数字太大,使用起来不方便。年轻人
仔细想想。实际上,天数w只是用来得到除以7后的余数。这启发了我们
不能简化这个w值,只要找一个余数和它一样的更小的数,用数论里的术语。
一般来说,即使你找到一个更小的正整数与其全等,你仍然可以计算出精确的周数。
很明显,W之所以这么大,是因为公式中的第一项(Y-1)*365太大了。事实上,
(Y-1)* 365 =(Y-1)*(364+1)
= (Y-1) * (7*52+1)
= 52 * (Y-1) * 7 + (Y-1),
这个结果的第一项是7的倍数,除以7余数是0,所以(Y-1)*365除以7的余数实际上是
余数等于Y-1除以7。这种关系可以表示为:
(Y-1)*365 ≡ Y-1 (mod 7)。
其中≡是数论中同余的符号,mod 7表示用7作为模(即除数)。
这种情况下≡号两边的数全等。因此,可以用(Y-1)代替(Y-1)*365,这样我们就可以得到
介绍了计算星期几的著名且最常见的公式:
w =(Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+d .(2)
这个公式虽然好用很多,但不是最好的公式,因为累计天数D的计算也比较麻木。
恼火。有没有可能直接用月数和日期来计算?答案也是肯定的。让我们看一看每一个
一个月中的天数如下所示:
月份:65438+二月,三月,四月,五月,七月,八月,九月,65438+十月,65438+十月,65438+二月。
-
天数:31 28(29)31 30 31 30 31 31 30 31。
如果从所有这些天中减去28(=4*7),不会影响W除以7的余数。所以我们可以再买一个。
表格:
月份:65438+二月,三月,四月,五月,七月,八月,九月,65438+十月,65438+十月,65438+二月。
-
剩余天数:30 (1) 323232323
年均积累:3 368 11 13 16 19 21 24 26 29。
闰年累计:3 479 12 14 17 20 22 25 27 30
如果我们仔细观察,会发现3月到7月这5个月中,除了1和2月,其余的日子都是3,2,3,2。
3;8月到65438+2月这五个月的天数也是3,2,3,2,3,只是重复而已。在相应的累计天数中,
上个月累计天数和上个月累计天数之差减28就是这个重复。正是因为这个规律
存在,平年和闰年的累计天数可以很容易地用一个数学公式来表示:
╭d;(当m = 1时)
d = { 31+d;(当m = 2时)(3)
╰[13 *(M+1)/5]-7+(M-1)* 28+d+I .(M≥3时)
其中[...]仍然意味着只取整数部分;m和d分别是要计算的月和日;平均年份i=0,闰年
i=1 .表达式M≥3需要说明一下:[13*(M+1)/5]-7是上表二中计算的。
平均累积值加上(M-1)*28是要计算的日期所在月份之前所有月份的总天数。这是一个
非常巧妙的用整数运算实现3,2,3,2,3循环的方法。例如,对于2004年5月1,有:
d =[13 *(5+1)/5]-7+(5-1)* 28+1+1
= 122,
这是2004年5月1日的累计天数。
如果我们做一个改变,把65438+十月和二月看成是前一年的“65438+三月”和“65438+四月”,不仅还是
但是,它符合这个公式,也正因为如此,闰日成为最后一个“年”的最后一天(a * * *有14个月)
日已成为D的一部分,因此平闰年的影响已被去除,公式简化为:
d =[13 *(M+1)/5]-7+(M-1)* 28+d .(3≤M≤14)(4)
上述计算星期几的公式可以进一步简化为:
w =(Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+[13 *(M+1)/5]-7
+ (M-1) * 28 + d。
因为-7和(M-1)*28都可以被7整除,所以如果去掉这两项,W除以7的余数保持不变。
公式变为:
w =(Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+[13 *(M+1)/5]+d。
(5)
当然,需要注意的是,65438+10月和2月已经被视为前一年的65438+3月和65438+4月,所以计算65438+10月和2月的天数。
的一周,除了m,都是13或者14计算,y年也减一。例如,2004年6月65438+10月1是一个星期四,所以用这个。
一个公式来计算,有:
w =(2003-1)+[(2003-1)/4]-[(2003-1)/100]+[(2003-1)/400]+[13 *(13+1)/5]
+ 1
= 2002 + 500 - 20 + 5 + 36 + 1
= 2524;
2524/7 = 360 ...4.这是符合实际的。
公式(5)已经是从年、月、日计算星期几的公式了,但还不是最简洁的。今年,
有一些方法可以改进副本的处理。让我们用这个公式来计算每个世纪第一年三月的那一周1,并列出
该表如下:
年份:1 (401,801,…,2001)101(501,901,…,265438+。
-
第4周2
====================================================================
年份:201 (601,1001,…,2201) 301 (701,11065438)
-
周:0 5
如你所见,这一周每四个世纪重复一次。如果我们加上301 (701,1101,…,2301)。
3月1的周数视为-2(根据数论中余数的定义,-2和5除以7的余数相同,所以可以是
做这样的变换),那么这个重复序列恰好是4,2,0,-2的等差数列。因此,我们
计算每个世纪第一年的3月1的一周,可以得到以下公式:
W = (4 - C模4) * 2 - 4。(6)
其中c是本世纪的世纪数减一,mod代表模运算,即求余数。例如,对于2006年3月5438+0
1天,C=20,则:
W = (4 - 20 mod 4) * 2 - 4
= 8 - 4
= 4.
将公式(6)代入公式(5),经过变换,我们可以得到:
(Y-1)+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]≦( 4-C mod 4)* 2-1
(mod 7)。(7)
因此,公式(5)中的(y-1)+[(y-1)/4]-[(y-1)/100]+[(y-1)/400)。
每个世纪第一年的星期几可以用(4-C mod 4) * 2-1代替。这个公式写道
出来的是:
w =(4-C mod 4)* 2-1+[13 *(M+1)/5]+d .(8)
用计算每个世纪第一年的日期和星期的公式,计算本世纪其他年份的日期和星期的公式。
很容易得到。因为在一个世纪里,以00结尾的年份是最后一年,所以不用再考了。
考虑“闰一百年,闰四百年”的规律,我们只需要考虑“闰四年”的规律。用公式模拟(1)
将该方法简化为公式(2),我们可以容易地从公式(8)得到比公式(5)更简单的任意计算。
一天是一周中的某一天公式:
w =(4-C mod 4)* 2-1+(y-1)+[y/4]+[13 *(M+1)/5]+d .(9)
其中y是年份的最后两位数。
如果考虑到模运算不是四则运算,我们可以进一步重写(4-C mod 4) * 2。
转换成只包含四个运算的表达式。因为世纪的商q减一c除以四和余数r之间有如下关系:
4q + r = C,
其中r是C mod 4,因此,有:
r = C - 4q
= C - 4 * [C/4]。(10)
规则
(4 - C mod 4) * 2 = (4 - C + 4 * [C/4]) * 2
= 8 - 2C + 8 * [C/4]
≦[C/4]-2C+1(mod 7)。(11)
将公式(11)代入(9),我们得到:
w =[C/4]-2C+y+[y/4]+[13 *(M+1)/5]+d-1。(12)
这个公式可以通过从世纪数、年份的后两位数、月数和天数中减去1,然后除以7来计算W,余数为
几个标明是什么日子,唯一需要改变的是把65438+十月和二月当作前一年的65438+三月和65438+四月。
c和y都是基于前一年的年份。因此,一般认为这是计算任意一天是星期几的最好方法。
公式。这个公式是由德国数学家克里斯蒂安·泽勒首先提出的,1822 -
1899)是在1886推导出来的,所以俗称泽勒公式。为了方便口头计算,
其中[13 * (M+1)/5]常写成[26 * (M+1)/10]。
现在我们来数一下2004年5月1的那一周。很明显,C=20,y=4,M=5,d=1,代入乐彩。
公式,有:
w =[20/4]-40+4+1+[13 *(5+1)/5]+1-1
= -15.
注意,负数不能按照习惯的余数概念计算,只能按照数论中余数的定义计算。为了方便起见
要计算的话,我们可以加7的整数倍使其成为正数,比如加70得到55。
除以7,剩下的6表示这一天是星期六。这与实际相符,也与公式(2)计算的结果相符。
果实是一致的。
最后需要注意的是,以上公式都是基于公历的闰法则。
是的。对于儒略历,乐彩也引入了相应的公式:
w = 5-C+y+[y/4]+[13 *(M+1)/5]+d-1。(13)
========================================
(2005-10-20 22:25:00) - (4575252)
计算任意一天的星期几的几种算法。
最近在论坛上看到有人问周算法,我特意整理了一下。这些算法都是从网上搜来的,算法的实现是我在项目里写的。希望对大家有帮助。
一:常用公式
w =[Y-1]+[(Y-1)/4]-[(Y-1)/100]+[(Y-1)/400]+D
y是年数,D是今年的累计天数,即今年的这一天是哪一天?
二:泽勒公式。
w = y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
公式中的符号有如下含义:w:周;c:世纪;y:年份(两位数);m:月(m大于等于3,但小于等于14,即在丘勒公式中,一年中的1和二月应视为13,上一年中的14,例如2003年的1应视为2002年的1。d:日;[]代表四舍五入,即只取整数部分。
与一般计算公式相比,泽勒公式大大降低了计算的复杂性。
第三,泽勒公式的改进
作者:冯思远
与另一个通用公式相比,泽勒公式大大降低了计算的复杂性。但作者给出的通用计算公式似乎更简洁(包括运算过程)。现在公式如下所示:
W=[y/4]+r (y/7)-2r(c/4)+m'+d
公式中的符号有以下含义:r()代表余数,即仅余数部分;m '是m的修正数,现在我们给出1到12 '的修正数从1到12 '如下:(1 ',10 ')= 6;(2',3',11')=2;(4',7')=5;5'=0;6'=3;8'=1;(9 ',12')=4(注:在作者给出的公式中,年份运行时y为1 ' = 5;2'=1)。其他符号的含义与泽勒公式中的符号相同。
四:金·拉森计算公式
我给这个公式起了名字,哈哈,希望大家不要见怪。
w =(d+2 * m+3 *(m+1)/5+y+y/4-y/100+y/400)mod 7
在公式中,d表示日期中的天数,m表示月数,y表示年数。
注意:该公式与其他公式有所不同:
将1月和2月视为前一年的第13个月和第14个月。例如,如果是2004-1-10,则转换为:2003-13-10,并代入公式进行计算。