专注电子技术学习与研究
当前位置:单片机教程网 >> STM32 >> 浏览文章

stm32通过年月日计算星期

作者:佚名   来源:本站原创   点击数:  更新时间:2014年04月26日   【字体:

 1.我们先谈谈的怎样算是否是闰年:

最根本的原因是:地球绕太阳运行周期为365天5小时48分46秒(合365.24219天)即一回归年(tropical year)。公历的平年只有365日,比回归年短约0.2422 日,所余下的时间约为四年累计一天,故四年于2月加1天,使当年的历年长度为366日,这一年就为闰年。现行公历中每400年有97个闰年。按照每四年一个闰年计算,平均每年就要多算出0.0078天,这样经过四百年就会多算出大约3天来。因此每四百年中要减少三个闰年。所以公历规定:年份是整百数时,必须是400的倍数才是闰年;不是400的倍数的年份,即使是4的倍数也是平年。
这就是通常所说的:四年一闰,百年不闰,四百年再闰。例如,2000年是闰年,1900年则是平年。
 
经过计算验证真是这么回事,验证如下:
365.24219*400(年)=146096.876约等于146097(天)
365*303+366*97=146097(天)
真的是 四年一闰,百年不闰,四百年再闰 ,每400年有97个闰年303个平年。
 
以下代码是c算法:判断是否为闰年
 
//year:年份
//返回值:该年份是不是闰年.1,是.0,不是
u8 Is_Leap_Year(u16 year)
{    
    if(((year%4==0)&&(year0!=0))||(year@0==0)) 
    { 
        return 1;  
    }else return 0; 
}
 
 
2.通过年月日计算星期的方法
方法概述:
           只需要知道三个代码
           日期代码+月份代码+年份代码
           就可以秒算任意年份任意日期的星期数
方法:
           日期代码就是指日期数,例如1月10日的日期代码就是10,10月1日的日期代码就是1
 
           月份代码,table[12]={6,2,2,5,0,3,5,1,4,6,2,4};//非闰年
                    table[12]={5,1,2,5,0,3,5,1,4,6,2,4};//闰年
 
           年份代码,只需将其年份的后两位数对4取模,然后与年份的后两位数相加,在对7取余数,
                     得到的余数就是年份代码,例如2010年的年份代码是 ([10/4]+10)%7=5,2011年的
                     的年份代码是([11/4]+11)%7=6
 
通过以上三个参数就可以秒算星期了:
 
           (日期代码+月份代码+年份代码)%7=星期数
           week[7]={0,1,2,3,4,5,6};//星期日-星期六
           例如:2014年3月30日 日期代码30 月份代码2 年份代码3 (30+2+3)%7=0 则是星期日
                 2008年8月 8日 北京奥运会开幕时间,日期代码8 月份代码1 年份代码3 (8+1+3)%7=5星
                 期五,ok都是正确的。
 
           u8 RTC_Get_Week(u16 year,u8 month,u8 day)
          {
               static u8 no_leap_year[12]={6,2,2,5,0,3,5,1,4,6,2,4};//非闰年
               static u8 leap_year[12]={5,1,2,5,0,3,5,1,4,6,2,4};//闰年  
               u8 temp2;
               u8 yearL;
               yearL=year0;
               yearL=(yearL/4+yearL)%7;
               temp2=Is_Leap_Year(year)?leap_year[month-1]:no_leap_year[month-1]; 
               return ((day+temp2+yearL)%7); 
          }
 
 
那么这样计算日期的原理是什么呢?接下来我们探索一下吧!
泰勒公式:
         W=[C/4]-2C+y+[y/4]+[26(m+1)/10]+d-1 (其中[ ]为取整符号)
         W=W%7
 
       
         其中,W是所求日期的星期数.如果求得的数大于7,可以减去7的倍数,直到余数小于7为止.c是公元年份
         的前两位数字,y是已知公元年份的后两位数字;m是月数,d是日数.方括[ ]表示只截取该数的整数部
         分。
         还有一个特别要注意的地方:所求的月份如果是1月或2月,则应视为前一年的13月或14月.所以公式中m
         的取值范围不是1-12,而是3-14.  
         后还有一点,工元1582年罗马教皇曾经下令修改历法,把这一年的10月4日(星期4)的下一天改为10月15
         日.所以在1582年以前的日子,不能加以套用.
 
         u8 RTC_Get_Week(u16 year,u8 month,u8 day)
         {
             u16 W;
             u8 m;
             u8 yearH=year/100,yearL=year0;
             if(month<3)m=month+12;
             else m=month;
             W=((yearH/4)-(2*yearH)+yearL+(yearL/4)+(26*(m+1)/10)+day-1)%7; 
             return ((u8)W); 
         }
 
        以上那两个程序子函数都可以计算出星期 
 
关闭窗口

相关文章