[STM32F4]

【Nucleo-F413ZH创想】生肖图案型万年历 之二

[复制链接]
665|2
手机看帖
扫描二维码
随时随地手机跟帖
jinglixixi|  楼主 | 2017-2-27 16:44 | 显示全部楼层 |阅读模式
      曾听人说相隔六十年的挂历就可以重复来使用,的确就年份而言六十年是一个甲子的轮回,但星期值是否也能完全吻合呢?
这就引出一个关于星期值的推算问题,我们知道每个平年有365天,且每4年会有一个闰年,这样在60年中,共有60/4=15个闰年,共有21915天(60*365+15),以21915%7=5,故星期值会偏移5天,所以星期值是不能完全重合的,也就无法如此来使用。
那如何来按公历时间进行星期值的推算呢?
这就需要有个基准点,以1984年1月1日为例,是星期日且该年为闰年。
X=198511日(异年同日推算),则推算方法为:
日期差d=1985-1984*365+1=366d%7=2+星期日=星期二。
在通常情况下,每年52周,52x7=364,则在平年的情况下,每过一年,则相应日期的星期值会向后推一天。若逢闰年则星期值需向后推二天,以补偿闰年所多出的一天。
X=1985110日(同年异日推算),则推算方法为:
日期差d=年差1985-1984*365+1+日差10-1=366+9=375d%7=4+星期日=星期四。
X=1985312日(异年异日推算),则推算方法为:
首先进行异年同日推算,再进行同年异日推算,则有:
日期差d=年差1985-1984*365+1+日差12-1+月差31+28=366+11+59=436d%7=2+星期日=星期二。
故通用的推算方法为:
日期差d=年差((x-1984*365+x-1984/ 4+1 )+月差(月份积日)+日差(日期-1-闰月前部修正(<2月)
星期值=d%7+星期日。
注:若使推算的范围更广,则可将推算的基点前移即可。
月份: 1   2    3    4    5    6    7    8    9    10    11    12
积日: 0   31   59   90   120  151  181  211  242  272   303   333
X=1988312
日期差d=4*365+2+11+59=1460+2+70=1532d%7=6+星期日=星期六。
X=1988212
日期差d=4*365+2+11+31=1460+2+42=1504-1=1503d%7=5+星期日=星期五。
    星期值推算的程序为:
printf("星期值推算: \r\n");
        printf("1985.1.1\r\n");
        //1984.1.1=星期日        闰年         i=1985->2017
        for(i=1985;i<2017;i++)
        {
        printf("%d年 \r\n",i);               
        t=(i-1984);
        for(j=1;j<13;j++)
        {
        for(b=1;b<29;b++)
    {       
          printf("%d月 \r\n",j);       
          printf("%d日\r\n",b);       
          p=b-1;
          if(j==1)          k=p;
          if(j==2)          k=31+p;
          if(j==3)          k=59+p;  
          if(j==4)          k=90+p;
          if(j==5)          k=120+p;
          if(j==6)          k=151+p;
          if(j==7)          k=181+p;
          if(j==8)          k=212+p;
          if(j==9)          k=243+p;
          if(j==10)  k=273+p;
          if(j==11)  k=304+p;
          if(j==12)  k=334+p;
          if((j<3)&&(t%4==0))  k=k-1;       
          d=(t*365+1+k+t/4)%7;
            printf("星期");
          if(d==0)          printf("日");
          if(d==1)          printf("一");
          if(d==2)          printf("二");
          if(d==3)          printf("三");
          if(d==4)          printf("四");
          if(d==5)          printf("五");
          if(d==6)          printf("六");       
          printf("\r\n");
          }
          }
    }
推算结果验证:
图片1.png
电脑的显示内容

图片2.png
推算的结果

wahahaheihei| | 2017-2-27 16:50 | 显示全部楼层
更牛X的你直接用1900年作为起始年份,我看电脑上的软件都是这样。

使用特权

评论回复
jinglixixi|  楼主 | 2017-2-28 08:43 | 显示全部楼层
wahahaheihei 发表于 2017-2-27 16:50
更牛X的你直接用1900年作为起始年份,我看电脑上的软件都是这样。

把推算基准前移即可,最早的基点可设为公元4年1月1日。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

446

主题

2675

帖子

36

粉丝