你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

RTC时钟,万年历的星期是如何计算的,你知道吗

[复制链接]
风大了吗 发布时间:2015-5-29 12:54
算法如下:
- S5 A* t) }" B% S7 [4 f3 X# D8 k  基姆拉尔森计算公式
4 D; g+ `8 s8 ]. f- F3 {+ J; K  W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
" O- P& |3 F4 i; x4 Y  在公式中d表示日期中的日数,m表示月份数,y表示年数。
( `9 b+ [3 k- m1 T' s7 N  注意:在公式中有个与其他公式不同的地方:
( c- g$ Y8 z) P; w" d  把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
, p+ V, d% R' H- L; C  代码如下:, z! v6 S1 J2 q6 w
  //y-年,m-月,d-日期$ @3 D' a' ^, [$ H. ^8 q0 b3 d
  string CaculateWeekDay(int y,int m, int d)
  X( ]1 A6 j* B# e/ E8 X  {
; u) w' y. v  ^& E  if(m==1||m==2) {
: P% L7 T$ s. a5 J! X( y0 U  m+=12;9 n# B# u$ L/ T) }
  y--;7 d2 l0 h- H) X8 t4 n
  }
) @. w( z/ |1 p9 h# t# z  int week=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
% v' s7 m/ c  i  string weekstr="";
6 @9 s, [0 Q% h  switch(week)
: B! ~7 P# t+ H  {
3 R$ X8 [) @1 r# l5 t  case 0: weekstr="星期一"; break;% F5 Z8 T! R( |- ?
  case 1: weekstr="星期二"; break;: K. y: T3 r' @* `( B, |5 b9 I
  case 2: weekstr="星期三"; break;
0 Q3 l) |/ ^. A% E1 w6 A4 D+ P  case 3: weekstr="星期四"; break;: ?0 l. b  R4 v" B5 V
  case 4: weekstr="星期五"; break;; L! l" L/ K, q- s' Y( P3 L
  case 5: weekstr="星期六"; break;
/ F1 i' |3 n7 g9 o, j  case 6: weekstr="星期日"; break;
& [' q, I: G- p8 @5 p. i7 R  }. F0 D! v6 T0 Z
  return weekstr;; t& a9 G: H9 V
  }
大苏苏注:用来算现在真实日期的星期是没有问题的。
这个公式主要是以:“通常,每过1年,同一日期是星期几就要向后推1天”,是理解这个公式的关键。
要想知道某年某月某日是星期几,首先,要知道这一年元旦以公元元年元旦是星期一为起点,
有时候,想知道公元某年某月某日是星期几,可以用下面的公式算出来:                
# S8 K# E& K3 f* v
     这里的方括号表示只取商的整数部分。式中:
7 ~2 ^9 x1 i* H- z. d6 J
( e3 c4 h; ^2 y, X+ e: D# h# \5 z0 Z
  x:这一年是公元多少年。
  y:这一天是这一年的第几天。
  s:星期几。不过要先除以7,再取余数。没有余数是星期日,余数是1、2、3、4、5、6,
    分别是星期一、星期二、星期三、星期四、星期五、星期六。
比如,今年国庆节(2010年10月1日)是星期几?
  x=2010。
  y=31+28+31+30+31+30+31+31+30+1=31×5+30×3+28+1=274。
  s=2010-1+502-20+5+274=2770,2770÷7余5。
所以,今年国庆节是星期五。
如果,你只想知道这个公式怎样用,到这儿就可以了。而要想知道这个公式的道理是什么,那可就说来话长了。
“星期制”是公元321年3月7日,古罗马皇帝君士坦丁宣布开始实行的,并且规定这一天为星期一。实际上,就是把公元元年元旦(公元1年1月1日)规定为星期一。(相当于公式中的x=1,y=1,所以s=1。)
通常1年有365天,365÷7=52……1,就是说比52个星期多1天。所以,同一个日期,下一年是星期几,就要比上一年向后推1天。比如,上一年元旦是星期三,下一年元旦就是星期四。
通常,每过1年,同一日期是星期几就要向后推1天”,是理解这个公式的关键。
要想知道某年某月某日是星期几,首先,要知道这一年元旦以公元元年元旦是星期一为起点,已经把星期几向后推了多少天,还要知道这一天是这一年的第几天。而要知道这一年元旦已经把星期几向后推了多少天,可以从公元元年到这一年已经过了多少年算起,先按1年向后推1天计算,再根据闰年的规定进行调整。
闰年的规定是:年份是4的倍数的一般都是闰年,其中,年份是整百数的一般不是闰年,只有年份是400的倍数的才是闰年。
现在,可以解释公式中各部分的含义了。

    这样一来,s就是在公元元年元旦是星期一的基础上,需要把这一天是星期几向后推的总天数。所以,s除以7取余数,就能说明这一天是星期几。1 n% f8 M" F$ O. u6 [5 s; Y3 j% B
上面的叙述是有点啰嗦,不过,通过对公式的解读,重温一下闰年的规定,顺便了解一点星期制的由来,还是值得的。何况这个公式的确很管用。比如,你想知道自己出生的那天是星期几,就可以算一算。再比如,你想知道爸妈的金婚纪念日是星期几,也可以预先算出来。不是挺有意思吗?
在1900-2099期间倒是一致。
6 [4 s  ^9 I. R! E3 ?$ r; `8 i% f; _) l, |
如果换做汉唐的时间就出问题了。
4 O$ o8 p7 R8 N) W6 e  N/ ^& x& H) e/ s& Y: ~8 M) w) Q" y( [: `5 k
“不受1900-2099年的限制”有待商榷 。
. z; r" x" _/ ^4 K8 a6 X
3 }, `3 _  x8 o% d1 O  A翻了下许老师的代码,下面这段代码必须有,否则到明朝时间就错了。' _9 n9 X8 B. V. `  q# j1 z
[size=1em][size=1em]view sourceprint?' T% Z+ d3 J6 s' g7 R  a
[size=1em][size=1em]
01
if(A>2299161)
8 `  m5 c! T+ j: f
[size=1em]
02
    {

2 d( A2 G+ F7 ^1 F' }7 s& Y0 b[size=1em]
03
        Da=floor((A-1867216.25)/36524.25);

% @  e8 A& G3 q- ^& K[size=1em]
04
        A+=1+Da-floor(Da/4.0);
" f) d$ ?$ b7 ^! f2 D
[size=1em]
05
    }
# @: W; _: H: D! f/ E: r" t
[size=1em]
06
     
  q+ f: v6 ~$ c# e
[size=1em]
07
    A     +=1524;                  //向前移4年零2个月
9 W! s2 L4 f) m
[size=1em]
08
    dt.Y =(int)floor((A-122.1)/365.25);  //年

8 \2 B7 L7 `# O4 c9 W[size=1em]
09
    Da      =A-floor(365.25*dt.Y);  //去除整年日数后余下日数
3 w8 S# P; w; G9 z! G
[size=1em]
10
    dt.M =(int)floor(Da/30.6001);        //月数

/ l1 ]7 x; ]( k+ Z) v+ t[size=1em]
11
    dt.D =(int)Da-(int)floor(dt.M*30.6001);      //去除整月日数后余下日数
- _' U5 U& ]6 D, \, ]" m
[size=1em]
12
    dt.Y-=4716; dt.M--;

* N. I: g+ @! n$ }3 e! L" ?( l* n, W; L" @" o
4 {' {7 Z  s8 U' _2 [8 X  ?

% _3 I" S' A# ?$ D
3 R+ z* p. ^  h不过STM32的RTC显示时钟只能从1970~2106年,强行穿越到明朝是要出问题的。# R" h( ]/ O! J& C/ E( n* s
3 M" b$ O; H  S
收藏 2 评论6 发布时间:2015-5-29 12:54

举报

6个回答
lkl0305 回答时间:2015-5-29 13:24:48
多谢分享
Paderboy 回答时间:2015-5-29 13:42:35
多谢分享
wh854997179 回答时间:2015-5-29 13:44:25
谢谢分享!
安臣 回答时间:2015-5-29 13:45:27
多谢分享!
qianfan 回答时间:2015-5-29 13:54:59
图贴的不行,
lcdi 回答时间:2015-5-29 14:32:27
所以只是日历而不是万年历

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版