论坛风格切换切换到宽版
  • 2291阅读
  • 3回复

万年历星期的算法 [复制链接]

上一主题 下一主题
离线邓福强
 
发帖
34
只看楼主 倒序阅读 0楼 发表于: 2007-12-19
本人初学单片机,想写个万年历,但不知星期的算法,网上的算法看不明白,思前想后自己开发了一个算法。如要植入单片机还可以优化,请自己优化!我下面只是给大家一个思路好理解。

从2000/1/1------2099/12/31测试通过。



#include <reg52.h>

unsigned char week(unsigned int,unsigned char,unsigned char);

unsigned char week(unsigned int year,unsigned char month,unsigned char day)
{
  unsigned char m,d,temp,week;
  unsigned int y;

  m=1,d=1,week=6;y=2000; //初始化2000/01/01是星期六

  while(y!=year)   //處理年(2000開始++)
    {
            week++;     //是上一年的星期的下一天 公式:365%7=1
           if(week>6)   //如是星期六
            week=0;   //回到0(星期日)
           if(y%4==0)   //判斷是否是閏年,閏年2月是29天 公式:366%7=2
           //如真是是要計算萬年用if(((y%4==0)&&(y%100!=0))||(y%400==0))) 這是減少編譯代碼長度
              {
            week++;           //星期多加一天
            if(week>6)         //如是星期六
                week=0;           //回到0(星期日)
          }
                y++;       //下一年的1月1日
    }
  while(m!=month)   //處理月(1月開始++)    
      {
      switch(m)
              {
        case 1:
        case 3:
                  case 5:
        case 7:
                  case 8:
                  case 10:
        case 12: temp=31%7;break; //大月天數

                  case 2:{             //閏月天數
                          if(y%4==0)     //判斷是否是閏年,閏年2月是29天 公式:366%7=2
                                   //如真是是要計算萬年用if(((y%4==0)&&(y%100!=0))||(y%400==0))) 這是減少編譯代碼長度
                                    temp=29%7;
                                   else temp=28%7;
                                   break;
                              }
        case 4:
                  case 6:
                  case 9:
                  case 11:temp=30%7;break;       //小月天數
              }
      while(temp)         //處理月
              {
        week++;
            if(week>6)       //如是星期六
                week=0;         //回到0(星期日)
                  temp--;        
              }
    m++;               //處理月

      }

  while(d!=day)     //處理日(從1日開始++)      
    {
        week++;
           if(week>6)   //如是星期六
            week=0;   //回到0(星期日)
           d++;
    }
  return week;     //返回星期
}


void main()
{

unsigned char temp;
temp=week(2099,12,31);
while(1);
}
在线BG4UVR
发帖
11213
只看该作者 1楼 发表于: 2007-12-19
我这样计算星期(同样只适用于2000-2099年)
  1. //计算星期
  2. unsigned char week(unsigned char year, unsigned char mon, unsigned char day)
  3. {
  4.   const prog_uchar weekdays[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
  5.   return (6-1 + (year>>2) + year + weekdays[mon-1] + day + (((year & 3) || mon > 2)? 1 : 0)) % 7;
  6. }
离线邓福强
发帖
34
只看该作者 2楼 发表于: 2007-12-19
'
我这样计算星期(同样只适用于2000-2099年)
  1. //计算星期
  2. unsigned char week(unsigned char year, unsigned char mon, unsigned char day)
  3. {
  4.   const prog_uchar weekdays[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
  5.   return (6-1 + (year>>2) + year + weekdays[mon-1] + day + (((year & 3) || mon > 2)? 1 : 0)) % 7;
  6. }
'


你这程式我试过了,ok!我是初学者,我写的程式不在见笑。但是我不明白你的程式其中原理。能否解释。。。。。。

谢谢!
在线BG4UVR
发帖
11213
只看该作者 3楼 发表于: 2007-12-19
带上注释,这样应该能清楚些

  1. //计算星期
  2. unsigned char week(unsigned char year, unsigned char mon, unsigned char day)
  3. {
  4.   const prog_uchar weekdays[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
  5.                           // 31 28 31 30 31 30 31 31 30 31 30
  6.   return (6-1 + (year>>2) + year + weekdays[mon-1] + day + (((year & 3) || mon > 2)? 1 : 0)) % 7;
  7.   //完整的计算星期的公式:
  8.   //(year>>2) - (year / 100) + (year/400) + year +
  9.   //   weekdays[mon-1] + day + ((!isleap(year) || mon > 2)? 1 : 0)) % 7;
  10. }