数码之家

 找回密码
 立即注册
搜索
查看: 2221|回复: 18

[C51] 通过年月日算出星期(原创)希望高手优化

[复制链接]
发表于 2019-12-14 17:32:11 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  最近在做GPS-DS3231时钟,没有设计调时按键,不知道星期怎么计算,网上也根本找不到51用的。冥思苦想加借鉴,蒙出来一个。现在拿出来希望有人给优化一下。
现在还是小白,好多都不明白。
一开始算今年过去多少天,累加天数串口输出,到255就清0.
现在贴出部分:


                if(Datatable[0]==0xFF && Datatable[5]==0xFF)
      {
                                year=Datatable[2];
                                mon=Datatable[3];
                                day=Datatable[4];
                               
                                aa=(year-20)+(year-17)/4;//每年365天,52星期余1天。因为从20年开始计算闰年
                               

                                switch(mon-1)
                                {
                                        case 0:ri=0;break;//day=0
                                        case 1:ri=3;break;//day=31%7
                                        case 2:ri=3;break;//day=59%7
                                        case 3:ri=6;break;//day=90%7
                                        case 4:ri=1;break;//day=120%7
                                        case 5:ri=4;break;//day=151%7
                                        case 6:ri=6;break;//day=181%7     一开始打算计算总天数最后计算%7,没想到加到255就清0。
                                        case 7:ri=2;break;//day=212%7     只能先总天数%7再计算
                                        case 8:ri=5;break;//day=243%7
                                        case 9:ri=0;break;//day=273%7
                                        case 10:ri=3;break;//day=304%7
                                        case 11:ri=5;break;//day=334%7
                                        default:break;//
                                }
                                if(mon>2&&year%4==0)//还是只取00-99,没打算活几百年。
                                        ri=aa+ri+day+1;//闰年大于2月加1天
                                else
                                        ri=aa+ri+day;
                               
                                week=(ri+2)%7;//20年1月1日为星期3,需要加2


经测试,输出星期是准确的。
转载请注明出处,谢谢!

打赏

参与人数 2家元 +20 收起 理由
人艰不拆了 + 10
家睦 + 10

查看全部打赏

 楼主| 发表于 2019-12-14 17:40:02 来自手机浏览器 | 显示全部楼层
北斗 DS3231 WS2812B 整点流水灯 日期温度 星期课程表
老婆当老师,做个带课程表的放办公室。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2019-12-14 22:28:15 | 显示全部楼层
这个没必要自己琢磨了,都这么多现成的轮子了……下载一份linux源码,扒一下mktime和localtime这两个函数就可以玩转所有时间转换的功能了。:lol:
回复 支持 1 反对 0

使用道具 举报

发表于 2019-12-15 10:52:09 | 显示全部楼层
我用这个,网上下的
u8 PGday(u16 year,u8 month,u8 day)
{//输出0为星期日
          u16 j,count=0;
           u16 MonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
          count = MonthAdd[month-1];
          count = count + day;
          if((year%4 == 0&&year %100 != 0||year % 400 == 0)&& month >= 3)
          count += 1;
          count = count + (year - 1901) * 365;
          for(j = 1901;j < year;j++)
          {
             if(j % 4 == 0 && j % 100 != 0 || j % 400 == 0)
             count++;
          }
         return ((count+1) % 7);
}
回复 支持 反对

使用道具 举报

发表于 2019-12-15 11:17:25 | 显示全部楼层
星期转换我记得写时钟代码时候一行就搞定了,好像没有这么麻烦
回复 支持 反对

使用道具 举报

发表于 2019-12-15 12:45:46 | 显示全部楼层
meteor2003x 发表于 2019-12-15 11:17
星期转换我记得写时钟代码时候一行就搞定了,好像没有这么麻烦

不明白希望指点下,用时钟芯片为什么还要搞星期转换呢,对于DS3231加上按键直接读取设定寄存器0x03不就可以了吗,我做的几个时钟都没有用到转换的,也就是调整用的选择键多按一下的事情,有看到用蔡勒公式W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1弄的,但一直不知道有什么用?
回复 支持 反对

使用道具 举报

发表于 2019-12-15 14:51:33 | 显示全部楼层
很简单,一直用这个
星期一 为 0
***************************************************
char convWeek(int y,char m,char d)
{        
        if(m==1||m==2){m+=12;y--;}
        return (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
}
回复 支持 反对

使用道具 举报

发表于 2019-12-15 15:38:40 | 显示全部楼层
调用万年历函数即可:lol:
回复 支持 反对

使用道具 举报

发表于 2019-12-15 16:23:42 | 显示全部楼层
慕名而来 发表于 2019-12-15 12:45
不明白希望指点下,用时钟芯片为什么还要搞星期转换呢,对于DS3231加上按键直接读取设定寄存器0x03不就可 ...

我那时候弄GPS授时只有公历时间,农历和星期都是转换的,农历查表计算,星期用这个公式
回复 支持 反对

使用道具 举报

发表于 2019-12-15 17:33:57 | 显示全部楼层
慕名而来 发表于 2019-12-15 12:45
不明白希望指点下,用时钟芯片为什么还要搞星期转换呢,对于DS3231加上按键直接读取设定寄存器0x03不就可 ...

调整多按一下按键,这一下按键就被几行程序可以代替的东西,为什么还要多去按那一下呢?设想一下,一个是自动算星期的,一个是手动调的,你会选哪个?道理是没错,自动这俩字就是为了减轻人力,哪怕是按一下按键的事。没有抬杠的意思,就是说一下我自己的理解,其实一开始我也不太理解,有时候写程序时候想想要不要加上星期设置,后来觉得操作怎么简单怎么来,一劳永逸么。
回复 支持 反对

使用道具 举报

发表于 2019-12-15 17:42:52 | 显示全部楼层
楼上有简单的计算程序我就不贴我的了。
如果楼主需要农历和节气的头文件,我可以发一个给你,C51用的
还有你说给你老婆在办公室用,就要注意GPS信号问题,虽然有3231辅助,但也要时不时的拿到窗台旁边进行搜星校时。
回复 支持 反对

使用道具 举报

发表于 2019-12-15 19:45:45 | 显示全部楼层
水表君 发表于 2019-12-15 17:33
调整多按一下按键,这一下按键就被几行程序可以代替的东西,为什么还要多去按那一下呢?设想一下,一个是 ...

原来如此,我以为标配就是按键的,虽然也存有这个计算的现成代码但重来没用上,最近无聊正在玩手里吃灰的时钟芯片,看到此贴就来参合了,你说的也对几行代码的事儿,操作能简单就简单吧况且基本时钟的调节也就星期可以绑定调整。
回复 支持 反对

使用道具 举报

发表于 2019-12-16 08:25:38 | 显示全部楼层
#include <time.h>
回复 支持 反对

使用道具 举报

发表于 2019-12-16 11:58:55 | 显示全部楼层
慕名而来 发表于 2019-12-15 19:45
原来如此,我以为标配就是按键的,虽然也存有这个计算的现成代码但重来没用上,最近无聊正在玩手里吃灰的 ...

如果从实用角度出发,那就是怎么方便怎么来,尽量不去调,我现在做的网络授时时钟,都是无按键设计,简单实用,实际使用时候,只要备电电池有电,有几个时候去调他的
回复 支持 反对

使用道具 举报

发表于 2019-12-16 20:20:06 | 显示全部楼层
水表君 发表于 2019-12-16 11:58
如果从实用角度出发,那就是怎么方便怎么来,尽量不去调,我现在做的网络授时时钟,都是无按键设计,简单 ...

是的,如果是实时或者定时校时就真的不需要按键了,毕竟按键的用途也是校时用的。
回复 支持 反对

使用道具 举报

发表于 2019-12-17 14:27:41 | 显示全部楼层
蔡勒(Zeller)公式:是一个计算星期的公式。
随便给一个日期,就能用这个公式推算出是星期几。

蔡勒公式如下:
W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1
或者是:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

公式中的符号含义如下:
w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六
c:世纪-1(前两位数)
y:年(后两位数)
m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算)
d:日
[ ]代表取整,即只要整数部分。

下面以中华人民共和国成立100周年纪念日那天(2049年10月1日)来计算是星期几,过程如下:
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
=49+[49/4]+[20/4]-2×20+[26×(10+1)/10]+1-1
=49+[12.25]+5-40+[28.6]
=49+12+5-40+28
=54 (除以7余5)
即2049年10月1日(100周年国庆)是星期五。

再比如计算2006年4月4日,过程如下:
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
=6+[6/4]+[20/4]-2*20+[26*(4+1)/10]+4-1
=-12 (除以7余2,注意对负数的取模运算!)
回复 支持 反对

使用道具 举报

发表于 2019-12-17 14:53:33 | 显示全部楼层
这个搭棚可以说是非常厉害了
回复 支持 反对

使用道具 举报

发表于 2019-12-17 15:34:11 | 显示全部楼层
本帖最后由 netbeetle 于 2019-12-17 15:35 编辑

貌似有个叫“基姆拉尔森计算公式”的东西,直接算出星期几。

//基姆拉尔森计算公式根据日期判断星期几
uint8_t CalculateWeekDay(int y, int m,int d)
{
uint8_t iWeek;
if(m==1||m==2) m+=12,y--;
iWeek = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
return iWeek;
}
回复 支持 反对

使用道具 举报

发表于 2019-12-18 10:31:05 | 显示全部楼层
以前做过,确实只有一行代码,3231好像带星期,直接读取就行了,忘了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-20 09:57 , Processed in 0.514801 second(s), 15 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表