本程序实际上是我的博客的<LPCARM之RTC应用举例及日期校验和星期自动调节祥解>
本贴主要是回复网友江小鸥的高论,我非常感谢!!!
见: http://www.ednchina.com/blog/hotpower/11893/message.aspx#19407
回复网友江小鸥:
非常感谢您的参与!!!不过心算和计算机笨算很不同~~~
不需查表算法程序摘录如下:
/*----------------------------------------------------------------------------------------
0000年~9999年星期算法(菜农自创)
-----------------------------------------------------------------------------------------*/
unsigned int GetDow(unsigned int y, unsigned int m, unsigned int d)
{
unsigned int w, c;
if (m <= 2){
m |= 4;//1月2月同5月六月表
y--;
}
c = y / 100;
c &= 0x03;//百年%4
y %= 100;
w = ((c | (c << 2)) + (y + (y >> 2)) + (13 * m + 8)/ 5 + d) % 7;//(星期=百年%4*5+年+年/4+(13*月+8)/5+日)%7
return w;//返回星期
}
/*----------------------------------------------------------------------------------------
附赠0000年~9999年月最大天数算法(菜农自创)
-----------------------------------------------------------------------------------------*/
int GetDom(unsigned int y, unsigned int m)
{
int dn;
dn = GetDow(y, m + 1, 1) - GetDow(y, m, 1);//m+1=13表示明年的1月
if (dn < 0) dn += 7;
return dn + 28;//返回当月的最大天数
}
用户99599 2007-6-7 18:55
这里介绍一种不用查表的公式:Zeller's Rule
The following formula is named Zeller's Rule after a Reverend Zeller. [x] means the greatest integer that is smaller than or equal to x. You can find this number by just dropping everything after the decimal point. For example, [3.79] is 3. Here's the formula:
f = k + [(13*m-1)/5] + D + [D/4] + [C/4] - 2*C.
(k + [(13*m-1)/5] + D + [D/4] + [C/4] - 2*C)mod 7
k日、m月、D年、C百年。谁会推导这个公式?(不难的)
Now let's substitute our example numbers into the formula.
f = k + [(13*m-1)/5] + D + [D/4] + [C/4] - 2*C
= 29 + [(13*11-1)/5] + 63 + [63/4] + [20/4] - 2*20
= 29 + [28.4] + 63 + [15.75] + [5] - 40
= 29 + 28 + 63 + 15 + 5 - 40
= 100.
Once we have found f, we divide it by 7 and take the remainder (if the remainder is negative, add 7). A remainder of 0 corresponds to Sunday, 1 means Monday, etc. For our example, 100 / 7 = 14, remainder 2, so January 29, 2064 will be a Tuesday.
雁塔菜农 2007-5-29 21:16
哈哈~~~那是阿莫站长送个我的自留地~~~
http://www.ouravr.com/bbs/bbs_list.jsp?bbs_id=1033&bbs_page_no=1
实际上这个算法的优点是不查表.
我反常规地"排表"为3月起头,即
3,4,5,6,7,8,9,10,11,12,1,2
而且1,2刚好与5,6表相同,这样就彻底地抛开了表的束缚~~~
用机器语言表述如下:
if (m <= 2){
m |= 4;//1月2月同5月六月表
y--;
}
这句是"精华"~~~
用户1079511 2007-5-29 14:51
好东西,收下了。敢问一声“菜农”是OURAVR上的吗?