原创 新编万年历星期速算法

2006-12-30 01:48 8110 6 14 分类: 软件与OS
匠人:这就是那古老的传说。。。
mood25.gif HotPower 发表于 2004-6-3 18:41 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖举报该贴


      新编万年历星期速算法(HotPower 2004.6.2)
推导过程:
1。平年365天(52周+1天),闰年366天(52周+2天)。平年2月28天,闰年2月29天。
   由于公元1月1日设为星期六,故3月1日为星期三。         ——注意这个“三”
   为使算法达到最简,故本算法以“星期”为计算单位。且选3月1日为基月。
2。每400年整一闰,或每4年且不为百年的一闰。
   百年%4=0闰或(年%4=0并且年<>0)闰。
3。每 4年(3个平年+1个闰年)共208周+5天                  ——注意这个“5天”
   每百年共100*(208周+5天)-1天=5217周+5天              ——注意这个“5天”(整百年暂设为平年)
   每400年共4*(5217周+5天)+1天(整400年闰)=20871周+0天——注意这个“0天”和“1天”(4个整百年只有一个闰年)
   即400年一轮回!(原来万年历400年前是一家)
4。万年3月1日星期算法(记住那个三)
   公式:某年3月1日星期几=(3天+百年%4*5天+年/4*5天+年%4+月星期表+日-1天)%7
         某年3月1日星期几=(百年%4*5天+年/4*5天+年%4+月星期表+日+2天)%7
   或    某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
   
   闰4百年3月1日星期算法(百年%4=0)
   公式:某年3月1日星期几=(年+年/4+月星期表+日+2天)%7
   例:0000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
       1600年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
       2000年3月1日星期几=(0+0/4+0+1+2)%7=3%7=星期三
       2001年3月1日星期几=(1+1/4+0+1+2)%7=4%7=星期四
       2004年3月1日星期几=(4+4/4+0+1+2)%7=8%7=星期一
       2008年3月1日星期几=(8+8/4+0+1+2)%7=13%7=星期六
       2042年3月1日星期几=(42+42/4+0+1+2)%7=55%7=星期六

   平4百年3月1日星期算法(百年%4<>0)
   公式:某年3月1日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
   例:1700年3月1日星期几=(17%4*5+0+0/4+0+1+2)%7=8%7=星期一(注意:1700年是平年)
       1800年3月1日星期几=(18%4*5+0+0/4+0+1+2)%7=13%7=星期六(注意:1800年是平年)
       1900年3月1日星期几=(19%4*5+0+0/4+0+1+2)%7=18%7=星期四(注意:1900年是平年)
       1901年3月1日星期几=(19%4*5+1+1/3+0+1+2)%7=19%7=星期五
       1918年3月1日星期几=(19%4*5+18+18/4+0+1+2)%7=(15+22+3)%7=40%7=星期五
       1958年3月1日星期几=(19%4*5+58/4*5+58%4+3)%7=(15+70+2+3)%7=90%7=星期六
       1988年3月1日星期几=(19%4*5+88/4*5+88%4+3)%7=(15+110+0+3)%7=128%7=星期二
       1999年3月1日星期几=(19%4*5+99/4*5+99%4+3)%7=(15+120+3+3)%7=141%7=星期一
       2100年3月1日星期几=(21%4*5+0/4*5+0%4+3)%7=(5+0+0+3)%7=8%7=星期一(注意:2100年是平年)
       2101年3月1日星期几=(21%4*5+1/4*5+1%4+3)%7=(5+0+1+3)%7=9%7=星期二
       2102年3月1日星期几=(21%4*5+2/4*5+2%4+3)%7=(5+0+2+3)%7=10%7=星期三
       2103年3月1日星期几=(21%4*5+3/4*5+3%4+3)%7=(5+0+3+3)%7=11%7=星期四
       2104年3月1日星期几=(21%4*5+4/4*5+4%4+3)%7=(5+1+0+3)%7=9%7=星期二(注意:2104年是闰年)
       9999年3月1日星期几=(99%4*5+99/4*5+99%4+3)%7=(120+15+3+3)%7=141%7=星期一
   注:按400年一轮回!(400年前是一家)的说法
       1600年,2000年是一样的
       1700年,2100年是一样的
       1800年,2200年是一样的
       1900年,2300年是一样的
       所以,万年历实际上是骗人的,应该叫“四百年历”才是。万只是多的意思罢了。
5. 万年某日星期算法  
   公式:某日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
   通同星期偏差表
   闰年  1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
   天数   31  29  31  30  31  30  31  31  30  31   30   31
   星期   3   6   0   3   5   1   3   6   2   4    0    2
   平年  1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
   天数   31  28  31  30  31  30  31  31  30  31   30   31
   星期   4   0   0   3   5   1   3   6   2   4    0    2
6. 2004年(今年)世上最“弱智”的算法
   先复习以上算法,取公式:
   某年某日星期几=(百年%4*5天+年+年/4+月星期表+日+2天)%7
   通同星期偏差表(闰年表)
        1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
   天数  31  29  31  30  31  30  31  31  30  31   30   31
   星期  3   6   0   3   5   1   3   6   2   4    0    2

   将2004年代入。得(其中百年=20,年=04)
   2004某日星期几=(20%4*5天+4+4/4+月星期表+日+2天)%7
             =(0*5天+4天+1天+月星期表+日+2天)%7
             =(5天+月星期表+日+2天)%7
         =(7天+月星期表+日)%7
         =(月星期表+日)%7
         =(月星期表%7+日%7)%7
   所以,2004年的算法最简单,几乎不用计算。

7.现以今年的重大节日为例:
  2004年元旦    1月表=3  1日=1  故3+1=4 即2004年元旦是星期四
  2004年春节    1月表=3 22日=1  故3+1=4 即2004年春节是星期四
  2004年元宵节  2月表=6  5日=5  故6+5=4 即2004年元宵节是星期四            
  2004年妇女节  3月表=0  8日=1  故0+1=1 即2004年妇女节是星期一            
  2004年植树节  3月表=0 12日=5  故0+5=5 即2004年植树节是星期五            
  2004年投诉节  3月表=0 15日=1  故0+1=1 即2004年投诉节是星期一
  2004年清明节  4月表=3  4日=4  故3+4=0 即2004年清明节是星期天
  2004年五一节  5月表=5  1日=1  故5+1=6 即2004年五一节是星期六
  2004年青年节  5月表=5  4日=4  故5+4=2 即2004年青年节是星期二
  2004年母亲节  5月表=5  9日=2  故5+2=0 即2004年母亲节是星期天
  2004年儿童节  6月表=1  1日=1  故1+1=2 即2004年儿童节是星期二
  2004年端午节  6月表=1 22日=1  故1+1=2 即2004年端午节是星期二
  2004年建党节  7月表=3  1日=1  故3+1=4 即2004年建党节是星期四
  2004年建军节  8月表=6  1日=1  故6+1=0 即2004年建军节是星期天
  2004年父亲节  8月表=6  8日=1  故6+1=0 即2004年父亲节是星期天
  2004年教师节  9月表=2 10日=3  故2+3=5 即2004年教师节是星期五
  2004年中秋节  9月表=2 28日=0  故2+0=2 即2004年中秋节是星期二
  2004年国庆节 10月表=4  1日=1  故4+1=5 即2004年国庆节是星期五
  2004年老人节 10月表=4  6日=6  故4+6=3 即2004年老人节是星期三
  2004年重阳节 10月表=4 22日=1  故4+1=5 即2004年重阳节是星期五
  2004年立冬节 11月表=0  7日=7  故0+7=0 即2004年立冬节是星期天
  2004年冬至节 12月表=2 21日=0  故2+0=2 即2004年冬至节是星期二
8。二十世纪任意日期举例(19%4*5=15)
   公式:某日星期几=(百年%4*5天+年+年/4+平年月星期表+日+2天)%7
                   =(19%4*5天+年+年/4+平年月星期表+日+2天)%7
                   =(15天+年+年/4+平年月星期表+日+2天)%7
   即:  某日星期几=(年+年/4+平年月星期表+日+3天)%7

  1900年元旦      1日=(0/4*5+0%4+1+3)%7=(0+0+4)%7=4
                 1月表=4(平年)    故 4+4=1 即1900年元旦是星期一
  1918年大寒     21日=(18/4*5+18%4+21+3)%7=(20+2+24)%7=4
                 1月表=4(平年)    故 4+4=1 即1918年春节是星期一
  1918年春节     11日=(18/4*5+18%4+11+3)%7=(20+2+14)%7=1
                 2月表=0(平年)    故 0+1=1 即1918年春节是星期一
  1927年元旦      1日=(27/4*5+27%4+1+3)%7=(30+3+4)%7=2
                 1月表=4(平年)    故 4+2=6 即1927年元旦是星期六
  1948年腊八节   18日=(48/4*5+48%4+18+3)%7=(60+21)%7=4
                 1月表=3(闰年)    故 3+4=0 即1927年元旦是星期天
  1949年国庆      1日=(49/4*5+49%4+1+3)%7=(60+1+4)%7=2
                 10月表=4(平年)    故 4+2=6 即1949年国庆是星期六
  1962年劳动节    1日=(62/4*5+62%4+1+3)%7=(75+2+4)%7=4
                  5月表=5(平年)    故 5+4=2 即1962年劳动节是星期二
  1999年12月31日 31日=(99/4*5+99%4+31+3)%7=(120+3+34)%7=3
                 12月表=2(平年)    故 2+3=5 即1999年12月31日是星期五
9.二十一世纪新前年虫算法(20%4*5=0)
   公式:某日星期几=(百年%4*5天+年+年/4+闰年月星期表+日+2天)%7
                   =(20%4*5天+年+年/4+闰年月星期表+日+2天)%7
   即:  某日星期几=(年+年/4+闰年月星期表+日+2天)%7

  2000年元旦      1日=(0+0/4+1+2)%7=(0+0+1+2)%7=3
                 1月表=3(闰年)    故 3+3->6 即2027年元旦是星期六
  2018年大寒     20日=(18+18/4+20+2)%7=(18+4+20+2)%7=2
                 1月表=4(平年)    故 4+2->6 即2018年大寒是星期六
  2018年春节     16日=(18+18/4+16+2)%7=(18+4+16+2)%7=5
                 2月表=0(平年)    故 0+5=5 即2018年春节是星期五
  2027年元旦      1日=(27+27/4+1+2)%7=(3+30+3)%7=1
                 1月表=4(平年)    故 4+1=5 即2027年元旦是星期五
  2048年腊八节   22日=(48/4*5+48%4+22+2)%7=(60+24)%7=0
                 1月表=3(闰年)    故 3+0=3 即2027年腊八是星期三
  2099年12月31日 31日=(99/4*5+99%4+31+2)%7=(120+3+33)%7=2
                 12月表=2(平年)    故 2+2=4 即2099年12月31日是星期四

10。二十二世纪任意日期举例(21%4*5=5)(接缝验证)
   公式:某日星期几=(百年%4*5天+年+年/4+平年月星期表+日+2天)%7
                   =(21%4*5天+年+年/4+平年月星期表+日+2天)%7
                   =(5天+年+年/4+平年月星期表+日+2天)%7
   即:  某日星期几=(年+年/4+平年月星期表+日)%7

  2100年元旦      1日=(0/4*5+0%4+1)%7=(0+0+1)%7=1
                 1月表=4(平年)    故 4+1=4 即2100年元旦是星期五
  2100年1月31日  31日=(0/4*5+0%4+31)%7=(0+0+31)%7=3
                 1月表=4(平年)    故 4+3=0 即2100年1月31日是星期天
  2100年2月1日    1日=(0/4*5+0%4+1)%7=(0+0+1)%7=1
                 2月表=0(平年)    故 0+1=1 即2100年2月1日是星期一
  2100年2月28日  28日=(0/4*5+0%4+28)%7=(0+0+28)%7=0
                 2月表=0(平年)    故 0+0=0 即2100年2月28日是星期天
  2100年3月1日    1日=(0/4*5+0%4+1)%7=(0+0+1)%7=1
                 3月表=0(平年)    故 0+1=1 即2100年3月1日是星期一
  2100年3月31日  31日=(0/4*5+0%4+31)%7=(0+0+31)%7=3
                 3月表=0(平年)    故 0+3=3 即2100年3月31日是星期三
  2100年12月31日 31日=(0/4*5+0%4+31)%7=(0+0+31)%7=3
                 12月表=2(平年)    故 2+3=5 即2101年12月31日是星期五
  2101年元旦      1日=(1/4*5+1%4+1)%7=(0+1+1)%7=2
                 1月表=4(平年)    故 4+2=6 即2101年元旦是星期六
  2101年1月31日  31日=(1/4*5+1%4+31)%7=(0+1+31)%7=4
                 1月表=4(平年)    故 4+4=1 即2101年1月31日是星期一
  2101年2月1日    1日=(0/4*5+1%4+1)%7=(0+1+1)%7=2
                 2月表=0(平年)    故 0+2=2 即2101年2月1日是星期二
  2101年2月28日  28日=(0/4*5+1%4+28)%7=(0+1+28)%7=1
                 2月表=0(平年)    故 0+1=1 即2101年2月28日是星期一
  2101年3月1日    1日=(0/4*5+1%4+1)%7=(0+1+1)%7=2
                 3月表=0(平年)    故 0+2=2 即2101年3月1日是星期二
  2101年3月31日  31日=(0/4*5+1%4+31)%7=(0+1+31)%7=4
                 3月表=0(平年)    故 0+4=4 即2101年3月31日是星期四
  2101年12月31日 31日=(0/4*5+1%4+31)%7=(0+1+31)%7=4
                 12月表=2(平年)    故 2+4=6 即2101年12月31日是星期六
  2104年2月29日  29日=(0/4*5+1%4+29)%7=(0+1+29)%7=2
                 2月表=6(闰年)    故 6+2=1 即2104年2月29日是星期一
  2104年3月1日    1日=(0/4*5+1%4+1)%7=(0+1+1)%7=2
                 3月表=0(闰年)    故 0+2=2 即2104年3月1日是星期二
  2199年12月31日 31日=(99/4*5+99%4+31)%7=(120+3+31)%7=0
                 12月表=2(平年)    故 2+0=2 即2199年12月31日是星期二



zyg: 再来个世纪分离的星期算法
mood25.gif HotPower 发表于 2004-6-8 20:09 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖举报该贴


unsigned char CalcWeekDay (unsigned char century, unsigned char year, unsigned char month ,unsigned char day )
{
    if ( month <= 2)
        {
           month +=12 ;//今年的 1月 2月是去年的“13月14月”
           year--;//注意“去年”2字
           if (year >= 99) {//年为无符号变量
             year = 99;//原年必为0
             century--;//世纪也需-1
           }  
        }
    return ( (century%4*5 + year + year /4  + ( 13 * month - 27 ) / 5   + day)% 7  );
}

unsigned char CalcWeekDay (unsigned char century, unsigned char year, unsigned char month ,unsigned char day )
{
    if ( month <= 2)
        {
           month |=4 ;//今年的 1月 2月是也是去年的“5月6月”的月表
           year--;//注意“去年”2字   
           if (year >= 99) {//年为无符号变量
             year = 99;//原年必为0
             century--;//世纪也需-1
           }  
        }
    return ( (century%4*5 + year + year /4  + ( 13 * month - 27 ) / 5   + day)% 7  );
}

unsigned char CalcWeekDay (unsigned char century, unsigned char year, unsigned char month ,unsigned char day )
{
    if ( month <= 2)
        {
           month +=12 ;//今年的 1月 2月是去年的“13月14月”
           year--;//注意“去年”2字
           if (year >= 99) {//年为无符号变量
             year = 99;//原年必为0
             century--;//世纪也需-1
           }  
        }
    return ( (century%4*5 + year + year /4  + ( 13 * month + 8 ) / 5   + day)% 7  );
}

unsigned char CalcWeekDay (unsigned char century, unsigned char year, unsigned char month ,unsigned char day )
{
    if ( month <= 2)
        {
           month |=4 ;//今年的 1月 2月是也是去年的“5月6月”的月表
           year--;//注意“去年”2字   
           if (year >= 99) {//年为无符号变量
             year = 99;//原年必为0
             century--;//世纪也需-1
           }  
        }
    return ( (century%4*5 + year + year /4  + ( 13 * month + 8 ) / 5   + day)% 7  );
}


先发个"少儿版"的2004年星期算法
mood25.gif HotPower 发表于 2004-6-1 16:18 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖举报该贴


HotPower先不能欺骗"下一代"吧, 给个HotPower星期算法的一个子子集.


   2004某日星期几=(月星期表+日)%7

   通同星期偏差表(闰年表)
        1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
   天数  31  29  31  30  31  30  31  31  30  31   30   31
   星期  3   6   0   3   5   1   3   6   2   4    0    2

现以今年的重大节日为例:
  2004年元旦    1月表=3  1日=1  故3+1=4 即2004年元旦是星期四
  2004年春节    1月表=3 22日=1  故3+1=4 即2004年春节是星期四
  2004年元宵节  2月表=6  5日=5  故6+5=4 即2004年元宵节是星期四            
  2004年妇女节  3月表=0  8日=1  故0+1=1 即2004年妇女节是星期一            
  2004年植树节  3月表=0 12日=5  故0+5=5 即2004年植树节是星期五            
  2004年投诉节  3月表=0 15日=1  故0+1=1 即2004年投诉节是星期一
  2004年清明节  4月表=3  4日=4  故3+4=0 即2004年清明节是星期天
  2004年五一节  5月表=5  1日=1  故5+1=6 即2004年五一节是星期六
  2004年青年节  5月表=5  4日=4  故5+4=2 即2004年青年节是星期二
  2004年母亲节  5月表=5  9日=2  故5+2=0 即2004年母亲节是星期天
  2004年儿童节  6月表=1  1日=1  故1+1=2 即2004年儿童节是星期二
  2004年端午节  6月表=1 22日=1  故1+1=2 即2004年端午节是星期二
  2004年建党节  7月表=3  1日=1  故3+1=4 即2004年建党节是星期四
  2004年建军节  8月表=6  1日=1  故6+1=0 即2004年建军节是星期天
  2004年父亲节  8月表=6  8日=1  故6+1=0 即2004年父亲节是星期天
  2004年教师节  9月表=2 10日=3  故2+3=5 即2004年教师节是星期五
  2004年中秋节  9月表=2 28日=0  故2+0=2 即2004年中秋节是星期二
  2004年国庆节 10月表=4  1日=1  故4+1=5 即2004年国庆节是星期五
  2004年老人节 10月表=4  6日=6  故4+6=3 即2004年老人节是星期三
  2004年重阳节 10月表=4 22日=1  故4+1=5 即2004年重阳节是星期五
  2004年立冬节 11月表=0  7日=7  故0+7=0 即2004年立冬节是星期天
  2004年冬至节 12月表=2 21日=0  故2+0=2 即2004年冬至节是星期二


PARTNER CONTENT

文章评论8条评论)

登录后参与讨论

用户99599 2007-6-4 20:43

啊不好意思,错的是mistakes自己!

MOD(Y,400)×5 - INT(Y/4000)

1 - 0.9688 = 0.0312 × 97 = 3.02...

用户99599 2007-6-3 00:15

不会吧,应该懂英语的,难道还要等几千或几万年Gregorian再世才来解决这个问题。如感兴趣,我的邮箱是yhchen837@fastmail.fm,欢迎交流。

用户99599 2007-5-31 14:00

What years are leap years?

It takes the earth about 365.2422 days to go around the sun, but a normal calendar year is only 365 days. The extra fraction of a day adds up: circling the sun four times takes 1460.9688 days, but four calendar years would only be 1460 days. That .9688 is almost a whole day, so every four years we add an extra day to our calendar, February 29. We call that year leap year. To make things easier, leap years are always divisible by four: 2004 and 2008 will both be leap years.

For hundreds of years, people used a calendar called the Julian calendar that followed this rule, adding a leap year every four years. However, because .9688 isn't exactly a whole day, the Julian calendar slowly began to disagree with the real seasons. In 1582, Pope Gregory fixed this problem by ordering everyone to use a new set of rules. These rules are named the Gregorian calendar, after him. They work like this:

    The Gregorian Calendar
    Rule Examples
    Every fourth year is a leap year. 2004, 2008, and 2012 are leap years.
    However, every hundredth year is not a leap year. 1900 and 2100 are not leap years.
    Every four hundred years, there's a leap year after all. 2000 and 2400 are leap years.

People in English-speaking countries didn't start using the Gregorian calendar until 1752. Some countries, such as Iran, still use other systems.

答案(线索)就在里面,我想你一定能找出来!

雁塔菜农 2007-5-29 21:21

哈哈~~~这里的"百年"指年大于99的任何数,万年肯定在此~~~

参见:http://www.ednchina.com/blog/hotpower/30078/message.aspx

用户99599 2007-5-29 14:22

一万年后的今天是星期几

个人觉得这是一个简单的小问题,你呢?

用户99599 2007-5-29 14:12

如果真是这样,还不如运用下面这个小学生都懂的通用公式,更为直接了当。

 Y+Y/4+Y/400-Y/100,当然这只是千年公式不是万年公式!

雁塔菜农 2007-5-29 13:09

非常感谢您的参与!!!不过心算和计算机笨算很不同~~~

http://www.ednchina.com/blog/hotpower/30078/message.aspx

用户99599 2007-5-28 19:15

江小鸥:此法过于麻烦,我可用一法口算很快得出

是的,那就让我们来化简一下吧,但道理只有一个,你的也不例外。

千年某日星期速算法

公式:W = ( Y + M + D ) %7

Y = 百年%4*5天+年+年/4,M = 月星期表,D = 日。

月星期表1到12月
闰年   2   1   2   5   0   3   5   1   3   6    4    4
平年   6   2   2   5   0   3   5   1   3   6    4    4

心算时Y、 D可以分别先%7。

由于公元1月1日设为星期六,故3月1日为星期三。         ——注意这个“三”
为使算法达到最简,故本算法以“星期”为计算单位。且选3月1日为基月。

这个公元1月1日指哪一年?有必要选3月为基月吗?

9999年3月1日星期几=(99%4*5+99/4*5+99%4+3)%7=(120+15+3+3)%7=141%7=星期一。万年历实际上是骗人的,应该叫“四百年历”才是。万只是多的意思罢了。

是的,这个万年历星期速算法也是骗人的,因为9999年3月1日是星期六不是星期一。所谓的万年历是指它的算法适用万年,而不是指其对象的周期,所以把它改为千年。周期有大小之分,星期的最小周期是28年,这对心算尤为有用。

以上纯属个人观点,不一定对,JUST FOR YOUR REFERENCE!


   

相关推荐阅读
雁塔菜农 2012-04-05 17:51
2012年度新唐Cortex-M0助学开发套件有约束条件赠送申报贴
2012年度新唐Cortex-M0助学套件从4月起每月有约束条件发放16套。 申报人必须是21ic或 EDNC 会员 并具备1月的会龄。 申报时必须注明“遵守约束条件,缴纳250元订金,上...
雁塔菜农 2012-04-05 17:04
2012年度Cortex-M0助学园地推广框图
...
雁塔菜农 2012-04-01 17:59
2012年度Cortex-M0助学园地奖励计划细则
抢楼请点击:菜地公告:即日起创建《菜农Cortex-M0助学园地》(盖楼入口) 每月10号和25号的下午2:50进行2次抢楼,规则同去年12月的疯狂抢楼活动。 奖品由21IC、北航、广州迪圣...
雁塔菜农 2012-02-03 08:19
菜农谋略:搞定牛人宋俊德,对女牛人孙昌旭说:“记住,俺是雁塔菜农~~~ ”
http://www.baidu.com/s?wd=%B2%CB%C5%A9%D0%A6%CC%B8%A1%B6%D0%C2%C0%CB%C3%FB%C8%CB%D0%A7%D3%A6%A1%B7...
我要评论
8
6
关闭 站长推荐上一条 /3 下一条