公历和回历相互转换算法在嵌入式系统下的实现

来源 :电子世界 | 被引量 : 0次 | 上传用户:qq540531049
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  【摘要】为了方便广大中国穆斯林的生活,提出了一种基于Windows CE操作系统的公历和回历相互转换算法,该算法采用C++语言在Visual Studio 2005集成开发环境下实现,给出了程序流程图和部分源代码,并在飞凌OK6410开发板上实现了设计功能。
  【关键词】嵌入式;公历;回历;转换;算法
  1.引言
  伊斯兰教历,又称为回历。目前中国市面上的回历大多是印刷品,很少有相关电子产品的面世,利用本文设计成果制作出的万年历将给广大中国穆斯林群众的宗教和日常生活带来便利。
  2.硬件实现
  笔者的设计是一款带有回历查询功能的万年历,其选用基于ARM11芯片的飞凌OK6410开发板为硬件平台,软件开发采用了VS2005集成开发环境,并安装了OK6410 SDK编译软件,采用C++语言编程,最终在Windows CE嵌入式系统下完成。
  3.算法思想
  3.1 历法介绍
  公历又称为格里历,它的前身是“儒略历”。儒略歷于公元前46年编制,其历以公元前45年1月1日为历元,取回归年长度为365.25天。该历法的闰年规则是每隔3年置1闰年。儒略历一直使用至1582年10月4日才被废除,代替它的新历就是格里历,格里历修改了闰年规则,凡公元年数能被4整除的即闰年,但公元年数后边带两个“0”的世纪年,仅能被400整除的年份仍为闰年,其他世纪年被调整为平年,取回归年的长度为365.2425天。罗马教皇格里高利十三世于1582年10月15日颁发了格里历,一直使用至今。
  回历是纯太阴历。其历法为:平年354天,闰年355天。一年为12个月,奇数月为大月30天;偶数月为小月29天;十二月,平年为29天,闰年为30天。每30年为一个循环周期,每个循环周期中平年19个,闰年11个。每30年的第2、5、7、10、13、16、18、21、24、26、29各年为闰年,其余各年为平年。该历元年元旦相当于儒略历622年7月16日,取每年平均长度为354.3667天。
  3.2 转换的关键
  虽然两种历法依照各自的规律运行,但是不管采取哪一种历法,总天数是不变的,转换算法的核心是先算出总的天数,然后再按照各自的规律进行推算,最终得出准确的日期。
  从上面的历法介绍,我们知道公历在1582年10月5日之前指的是儒略历,1582年10月14日之后,指的是格里历,而1582年10月5日至10月14日之间的日期是不存在的。这是公历和回历转换过程需要注意的,因为儒略历的算法和格里历的算法是不同的。
  3.3 公历转换回历
  公历转换成回历分为三个步骤:
  首先判断公历日期是否大于1582年10月14日。
  其次,要计算出具体的总天数。当公历日期大于1582年10月14日时,采用格里历历法计算总天数。当公历日期小于1582年10月14日时,采用儒略历历法计算总天数。两种历法计算总天数的公式[2]如下:
  (注:转换前公历日期的年月日依次标记为Y、M、D)
  格里历总天数={1461*[Y+4800+(M—14)/12]}/4+{367*[M—2—(M—14)]}/12—3*{[Y+4900+(M—14)/12]/100}/4+D —32075
  儒略历总天数=367*Y—7*[Y+5001+(M—9)/7]/4+275*M/9+D+1729777
  最后按照回历的历法规则推算出准确的日期。下面介绍一下推算的公式:(设整数变量L、J、S和N)
  L=总天数—1948440+10632
  N=(L—1)/10631
  J=[(10985—L)/5316]*[(50*L)/17719]+(L/5670)*[(43*L)/15238]
  S=L—[(30—J)/15]*[(17719*J)/50]—(J/16)*[(15238*J)/43]+29
  转换后的回历日期年月日依次标记为整数变量H_Y、H_M和H_D
  H_Y=30*N+J—30 H_M=(24*S)/709 H_D=S—(709*H_M)/24
  3.4 回历转换公历
  回历转换成公历也分为三个步骤:
  首先计算要转换回历日期所对应的儒略日总天数。回历日期计算儒略日数的公式如下:(注:转换前回历日期的年月日依次标记为HY、HM、HD。)
  儒略日总天数=(11*HY+3)/30+354*HY+ 30*HM—(HM—1)/2+HD+1948440—385
  其次要判断儒略日总天数是否大于2299160,这里的2299160是公历1582年10月4日所对应的儒略日总天数。
  最后按照公历的历法进行推算出准确的公历日期。这里说明一下,当儒略日总天数大于2299160时采用格里历历法进行计算,否则采用儒略历历法进行计算。下面介绍一下推算过程:
  (1)按照格里历历法进行推算(设整数变量L、N、I、S和J)
  N=[4*(儒略日总天数+68569)]/146097
  L=儒略日总天数+68569—(146097*N+3) /4
  I=[4000*(L+1)]/1461001
  S=L—(1461*I)/4+31 J=(80*S)/2447
  转换后的公历日期年月日依次标记为整数变量G_Y、G_M和G_D
  G_Y=100*(N—49)+I+J/11 G_M=J+2—12*J/11 G_D=S—(2447*J)/80
  (2)按照儒略历历法进行推算(设整数变量L、N、I、K和J)
  K=(儒略日总天数+1402—1)/1461
  L=儒略日总天数+1402—1461*K
  N=(L—1)/365—L/1461
  I=L—365*N+30 J=(80*I)/2447   转换后的公历日期年月日依次标记为整数变量G_Y、G_M和G_D
  G_Y=4*K+N+J/11—4716 G_M=J+2—12*J/11 G_D=I—(2447*J)/80
  4.软件实现
  4.1 公历转换回历
  图1是公历转换为回历的流程图和部分源代码
  部分代码如下:
  if((_year>1582)||((_year==1582)&& (_month>10))||((_year==1582)&&(_month==10)&&(_day>14))){jd=(1461*(_year+4800+(_month—14)/12))/4+(367*(_month—2—12*((_month—14)/12)))/12—(3*((_year+4900+(_month—14)/12)/100))/4+_day—32075;}
  else{jd=367*_year—(7*(_year+ 5001+(_month—9)/7))/4+(275*_month)/9+_day+1729777;}
  4.2 回历转换为公历
  图2是回历转换为公历的流程图和部分源代码。
  部分代码如下:
  jd=(11*_huiyear+3)/30+354*_huiyear+30*_huimonth—(_huimonth—1)/2+_huiday+1948440—385;
  if(jd>2299160)
  {l=jd+68569;
  n=(4*l)/146097;
  l=l—(146097*n+3)/4;
  i=(4000*(l+1))/1461001;
  l=l—(1461*i)/4+31;
  j=(80*l)/2447;
  }
  else
  {
  j=jd+1402;
  k=(j—1)/1461;
  l=j—1461*k;
  n=(l—1)/365—l/1461;
  i=l—365*n+30;
  j=(80*i)/2447;
  }
  4.3 查詢功能的实现
  查询功能主要是使用了上述的回历转公历算法,一旦获取了回历年份,该回历年的伊斯兰教重大节日就可以查询出对应的公历日期。伊斯兰教的三个重大节日开斋节、古尔邦节和圣纪节在回历中都有明确的日期,它们依次是10月1日、12月10日和3月12日,所以将查询的回历年份加上节日对应的回历日期,直接代入我们前面介绍的回历转换公历的算法,即可以得到准确的公历日期。
  4.4 在嵌入式系统下程序运行的结果
  经测试,程序在飞凌OK6410开发板上可以正确实现公历592年6月18日以后的所有公历日期和回历日期进行相互转换,查询功能运行正常,达到了设计的目的。
  5.结束语
  本设计主要实现了三大功能,首先是正常显示并可以修改当前时间(包含公历、回历的年月日和时分秒信息),第二是实现回历日期和公历日期的相互查询,第三是输入回历任意年份可以查询该回历年伊斯兰教重大节日所对应的公历日期。但是本设计还需要完善一些功能,比如每天五次礼拜的倒计时提醒和中国的农历以及一些公历节日的查询等功能,才能成为一款真正适合中国穆斯林的万年历产品。
  参考文献
  [1]乌志鸿.1500年回中西历历谱[M].银川:宁夏人民出版社,2011:13—19.
  [2]J.Thomann.Conversion of Islamic and Christian dates[DB/OL].http://www.oriold.uzh.ch/static/hegira.html,2006—05—26.
其他文献
<正> 自维科创立历史哲学以来,历史必然性问题一直是西方历史哲学关注的中心问题,至今仍是当代西方历史哲学争论的焦点;全面而科学地解决历史必然性问题是马克思主义的历史哲