久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7149|回復: 6
打印 上一主題 下一主題
收起左側

51單片機陽歷轉農歷(僅僅是陽歷轉陰歷例程)

  [復制鏈接]
跳轉到指定樓層
樓主
ID:310680 發表于 2018-12-30 22:31 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
之前要做一個萬年歷,從論壇上輾轉多處,最終發現以下這個陽歷轉換陰歷的程序比較簡單,數據帶入可以直接使用,不過測試發現轉換有問題,后面進行仿真調試找到問題所在,從而進而修改。不知道是我復制出錯,還是自己不經意間修改才導致問題出現,已經修復,需要陽歷轉陰歷的可以拿去。找不到具體來源,因此無法標志引用鏈接地址,如有侵權,聯系刪除。
問題所在:在SPDATE GetSpringDay(uchar GreYear,uchar GreMon,uchar GreDay)函數里面的參數定義,把Offset1定義為uchar類型,后面計算時Offset1數值溢出,將uchar改為uint后,數據不在溢出,進行上機測試,轉換成功。
  1. //公曆轉農曆(1901-2100)
  2. //亦木明 2008.1.11
  3. //2018.12.30清楓城主測試,發現存在問題,通過仿真一步步走找出問題所在,并作出修正
  4. //原文在哪忘了,只知道作者有“亦木明”的標注,如有侵權聯系刪除
  5. #include "12c5a60s2.h"//可修改為51的頭文件   


  6. #define TRUE  1
  7. //公歷年對應的農歷數據,每年三字節,
  8. //格式第一字節BIT7-4 位表示閏月月份,值為0 為無閏月,BIT3-0 對應農歷第1-4 月的大小
  9. //第二字節BIT7-0 對應農歷第5-12 月大小,第三字節BIT7 表示農歷第13 個月大小
  10. //月份對應的位為1 表示本農歷月大(30 天),為0 表示小(29 天).
  11. //第三字節BIT6-5 表示春節的公歷月份,BIT4-0 表示春節的公歷日期
  12. //每年的數據對應在數組中的位置庫 (200-(2100-year)-1)*3+Offset1  
  13. //0x09,0x2d,0x47, //2008  0x47 01000111
  14. //0x4d,0x4A,0xB8, //2001

  15. typedef struct spdate
  16. {
  17.         char         cYear;
  18.         char        cMon;
  19.         char        cDay;
  20. }SPDATE;


  21. uchar code Data[]={

  22. 0x04,0xAe,0x53, //1901  0        (200-(2100-1901)-1)*3=0
  23. 0x0A,0x57,0x48, //1902        3   (200-(2100-1902)-1)*3=3
  24. 0x55,0x26,0xBd, //1903        6        (200-(2100-1903)-1)*3=3
  25. 0x0d,0x26,0x50, //1904        9   (200-(2100-year)-1)*3
  26. 0x0d,0x95,0x44, //1905        12        
  27. 0x46,0xAA,0xB9, //1906        15
  28. 0x05,0x6A,0x4d, //1907
  29. 0x09,0xAd,0x42, //1908
  30. 0x24,0xAe,0xB6, //1909
  31. 0x04,0xAe,0x4A, //1910
  32. 0x6A,0x4d,0xBe, //1911
  33. 0x0A,0x4d,0x52, //1912
  34. 0x0d,0x25,0x46, //1913
  35. 0x5d,0x52,0xBA, //1914
  36. 0x0B,0x54,0x4e, //1915
  37. 0x0d,0x6A,0x43, //1916
  38. 0x29,0x6d,0x37, //1917
  39. 0x09,0x5B,0x4B, //1918
  40. 0x74,0x9B,0xC1, //1919
  41. 0x04,0x97,0x54, //1920
  42. 0x0A,0x4B,0x48, //1921
  43. 0x5B,0x25,0xBC, //1922
  44. 0x06,0xA5,0x50, //1923
  45. 0x06,0xd4,0x45, //1924
  46. 0x4A,0xdA,0xB8, //1925
  47. 0x02,0xB6,0x4d, //1926
  48. 0x09,0x57,0x42, //1927
  49. 0x24,0x97,0xB7, //1928
  50. 0x04,0x97,0x4A, //1929
  51. 0x66,0x4B,0x3e, //1930
  52. 0x0d,0x4A,0x51, //1931
  53. 0x0e,0xA5,0x46, //1932
  54. 0x56,0xd4,0xBA, //1933
  55. 0x05,0xAd,0x4e, //1934
  56. 0x02,0xB6,0x44, //1935
  57. 0x39,0x37,0x38, //1936
  58. 0x09,0x2e,0x4B, //1937
  59. 0x7C,0x96,0xBf, //1938
  60. 0x0C,0x95,0x53, //1939
  61. 0x0d,0x4A,0x48, //1940
  62. 0x6d,0xA5,0x3B, //1941
  63. 0x0B,0x55,0x4f, //1942
  64. 0x05,0x6A,0x45, //1943
  65. 0x4A,0xAd,0xB9, //1944
  66. 0x02,0x5d,0x4d, //1945
  67. 0x09,0x2d,0x42, //1946
  68. 0x2C,0x95,0xB6, //1947
  69. 0x0A,0x95,0x4A, //1948
  70. 0x7B,0x4A,0xBd, //1949
  71. 0x06,0xCA,0x51, //1950
  72. 0x0B,0x55,0x46, //1951
  73. 0x55,0x5A,0xBB, //1952
  74. 0x04,0xdA,0x4e, //1953
  75. 0x0A,0x5B,0x43, //1954
  76. 0x35,0x2B,0xB8, //1955
  77. 0x05,0x2B,0x4C, //1956
  78. 0x8A,0x95,0x3f, //1957
  79. 0x0e,0x95,0x52, //1958
  80. 0x06,0xAA,0x48, //1959
  81. 0x7A,0xd5,0x3C, //1960
  82. 0x0A,0xB5,0x4f, //1961
  83. 0x04,0xB6,0x45, //1962
  84. 0x4A,0x57,0x39, //1963
  85. 0x0A,0x57,0x4d, //1964
  86. 0x05,0x26,0x42, //1965
  87. 0x3e,0x93,0x35, //1966
  88. 0x0d,0x95,0x49, //1967
  89. 0x75,0xAA,0xBe, //1968
  90. 0x05,0x6A,0x51, //1969
  91. 0x09,0x6d,0x46, //1970
  92. 0x54,0xAe,0xBB, //1971
  93. 0x04,0xAd,0x4f, //1972
  94. 0x0A,0x4d,0x43, //1973
  95. 0x4d,0x26,0xB7, //1974
  96. 0x0d,0x25,0x4B, //1975
  97. 0x8d,0x52,0xBf, //1976
  98. 0x0B,0x54,0x52, //1977
  99. 0x0B,0x6A,0x47, //1978
  100. 0x69,0x6d,0x3C, //1979
  101. 0x09,0x5B,0x50, //1980
  102. 0x04,0x9B,0x45, //1981
  103. 0x4A,0x4B,0xB9, //1982
  104. 0x0A,0x4B,0x4d, //1983
  105. 0xAB,0x25,0xC2, //1984
  106. 0x06,0xA5,0x54, //1985
  107. 0x06,0xd4,0x49, //1986
  108. 0x6A,0xdA,0x3d, //1987
  109. 0x0A,0xB6,0x51, //1988
  110. 0x09,0x37,0x46, //1989
  111. 0x54,0x97,0xBB, //1990
  112. 0x04,0x97,0x4f, //1991
  113. 0x06,0x4B,0x44, //1992
  114. 0x36,0xA5,0x37, //1993
  115. 0x0e,0xA5,0x4A, //1994
  116. 0x86,0xB2,0xBf, //1995
  117. 0x05,0xAC,0x53, //1996
  118. 0x0A,0xB6,0x47, //1997
  119. 0x59,0x36,0xBC, //1998
  120. 0x09,0x2e,0x50, //1999         
  121. 0x0C,0x96,0x45, //2000
  122. 0x4d,0x4A,0xB8, //2001
  123. 0x0d,0x4A,0x4C, //2002
  124. 0x0d,0xA5,0x41, //2003
  125. 0x25,0xAA,0xB6, //2004
  126. 0x05,0x6A,0x49, //2005
  127. 0x7A,0xAd,0xBd, //2006
  128. 0x02,0x5d,0x52, //2007
  129. 0x09,0x2d,0x47, //2008
  130. 0x5C,0x95,0xBA, //2009
  131. 0x0A,0x95,0x4e, //2010
  132. 0x0B,0x4A,0x43, //2011
  133. 0x4B,0x55,0x37, //2012
  134. 0x0A,0xd5,0x4A, //2013
  135. 0x95,0x5A,0xBf, //2014
  136. 0x04,0xBA,0x53, //2015
  137. 0x0A,0x5B,0x48, //2016
  138. 0x65,0x2B,0xBC, //2017
  139. 0x05,0x2B,0x50, //2018
  140. 0x0A,0x93,0x45, //2019
  141. 0x47,0x4A,0xB9, //2020
  142. 0x06,0xAA,0x4C, //2021
  143. 0x0A,0xd5,0x41, //2022
  144. 0x24,0xdA,0xB6, //2023
  145. 0x04,0xB6,0x4A, //2024
  146. 0x69,0x57,0x3d, //2025
  147. 0x0A,0x4e,0x51, //2026
  148. 0x0d,0x26,0x46, //2027
  149. 0x5e,0x93,0x3A, //2028
  150. 0x0d,0x53,0x4d, //2029
  151. 0x05,0xAA,0x43, //2030
  152. 0x36,0xB5,0x37, //2031
  153. 0x09,0x6d,0x4B, //2032
  154. 0xB4,0xAe,0xBf, //2033
  155. 0x04,0xAd,0x53, //2034
  156. 0x0A,0x4d,0x48, //2035
  157. 0x6d,0x25,0xBC, //2036
  158. 0x0d,0x25,0x4f, //2037
  159. 0x0d,0x52,0x44, //2038
  160. 0x5d,0xAA,0x38, //2039
  161. 0x0B,0x5A,0x4C, //2040
  162. 0x05,0x6d,0x41, //2041
  163. 0x24,0xAd,0xB6, //2042
  164. 0x04,0x9B,0x4A, //2043
  165. 0x7A,0x4B,0xBe, //2044
  166. 0x0A,0x4B,0x51, //2045
  167. 0x0A,0xA5,0x46, //2046
  168. 0x5B,0x52,0xBA, //2047
  169. 0x06,0xd2,0x4e, //2048
  170. 0x0A,0xdA,0x42, //2049
  171. 0x35,0x5B,0x37, //2050
  172. 0x09,0x37,0x4B, //2051
  173. 0x84,0x97,0xC1, //2052
  174. 0x04,0x97,0x53, //2053
  175. 0x06,0x4B,0x48, //2054
  176. 0x66,0xA5,0x3C, //2055
  177. 0x0e,0xA5,0x4f, //2056
  178. 0x06,0xB2,0x44, //2057
  179. 0x4A,0xB6,0x38, //2058
  180. 0x0A,0xAe,0x4C, //2059
  181. 0x09,0x2e,0x42, //2060
  182. 0x3C,0x97,0x35, //2061
  183. 0x0C,0x96,0x49, //2062
  184. 0x7d,0x4A,0xBd, //2063
  185. 0x0d,0x4A,0x51, //2064
  186. 0x0d,0xA5,0x45, //2065
  187. 0x55,0xAA,0xBA, //2066
  188. 0x05,0x6A,0x4e, //2067
  189. 0x0A,0x6d,0x43, //2068
  190. 0x45,0x2e,0xB7, //2069
  191. 0x05,0x2d,0x4B, //2070
  192. 0x8A,0x95,0xBf, //2071
  193. 0x0A,0x95,0x53, //2072
  194. 0x0B,0x4A,0x47, //2073
  195. 0x6B,0x55,0x3B, //2074
  196. 0x0A,0xd5,0x4f, //2075
  197. 0x05,0x5A,0x45, //2076
  198. 0x4A,0x5d,0x38, //2077
  199. 0x0A,0x5B,0x4C, //2078
  200. 0x05,0x2B,0x42, //2079
  201. 0x3A,0x93,0xB6, //2080
  202. 0x06,0x93,0x49, //2081
  203. 0x77,0x29,0xBd, //2082
  204. 0x06,0xAA,0x51, //2083
  205. 0x0A,0xd5,0x46, //2084
  206. 0x54,0xdA,0xBA, //2085
  207. 0x04,0xB6,0x4e, //2086
  208. 0x0A,0x57,0x43, //2087
  209. 0x45,0x27,0x38, //2088
  210. 0x0d,0x26,0x4A, //2089
  211. 0x8e,0x93,0x3e, //2090
  212. 0x0d,0x52,0x52, //2091
  213. 0x0d,0xAA,0x47, //2092
  214. 0x66,0xB5,0x3B, //2093
  215. 0x05,0x6d,0x4f, //2094
  216. 0x04,0xAe,0x45, //2095
  217. 0x4A,0x4e,0xB9, //2096
  218. 0x0A,0x4d,0x4C, //2097
  219. 0x0d,0x15,0x41, //2098
  220. 0x2d,0x92,0xB5, //2099
  221. 0x0d,0x53,0x49, //2100
  222. };

  223. uchar code Mon1[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,
  224.                                   0,31,29,31,30,31,30,31,31,30,31,30,31};

  225. SPDATE Spdate;
  226. //獲得當年春節的公曆日期
  227. SPDATE GetSpringDay(uchar GreYear,uchar GreMon,uchar GreDay)
  228. {
  229.         //0x09,0x2d,0x47, //2008  0x47 01000111
  230.         int day;
  231.     uchar i,Flag,F;
  232.         uint Offset1;//出現問題在這里,原本定義為uchar類型,下面計算時超出范圍導致錯誤,進行修改為uint類型后,驗證正常
  233.         unsigned char L=0x01,Flag1=1;
  234.         unsigned int  Temp16,L1=0x0800;
  235.         //第三字節BIT6-5 表示春節的公歷月份,BIT4-0 表示春節的公歷日期
  236.         Spdate.cYear=GreYear ;
  237.         Spdate.cMon=(Data[(200-(100-GreYear)-1)*3+2]&0x60)>>5; //計算春節公歷月份
  238.         Spdate.cDay=(Data[(200-(100-GreYear)-1)*3+2])&0x1f;    //計算春節公歷日期

  239.         //判斷平年,閏年
  240.         if( (!(GreYear%4) && (GreYear%100)) || !(GreYear%400) ) Flag=1;
  241.         else Flag=0;
  242.         
  243.         if(Spdate.cMon>GreMon)                                                                //春節離公歷日期的天數
  244.         {
  245.            day=Mon1[Flag][GreMon]-GreDay;
  246.            for(i=GreMon+1;i<=Spdate.cMon-1;i++)
  247.                         day+=Mon1[Flag][i];
  248.            day+=Spdate.cDay;
  249.            F=1;
  250.         }
  251.         else if(Spdate.cMon<GreMon) //春節的月份小於目標的月份
  252.         {
  253.                 day=Mon1[Flag][Spdate.cMon]-Spdate.cDay;  
  254.                 for(i=Spdate.cMon+1;i<=GreMon-1;i++)
  255.                         day+=Mon1[Flag][i];
  256.                 day+=GreDay;                                //          000000000000000000000000000000000000000000000000000000000000000000
  257.                 F=0;
  258.         }
  259.         else
  260.         {
  261.                 if(Spdate.cDay>GreDay)
  262.                 {
  263.                         day=Spdate.cDay-GreDay;
  264.                         F=1;
  265.                 }
  266.                 else if(Spdate.cDay<GreDay)
  267.                 {
  268.                         day=GreDay-Spdate.cDay;
  269.                         F=0;
  270.                 }
  271.                 else day=0;
  272.         }                 

  273.         Spdate.cYear=Spdate.cYear;
  274.         Spdate.cMon=1;
  275.         Spdate.cDay=1;

  276.         if(!day) return Spdate ;

  277.         if(F)    //春節在公歷日期后
  278.         {
  279.                 Spdate.cYear--;
  280.                 Spdate.cMon=12;
  281.                 //這邊Offset1計算會出現超范圍,因此把uchar類型改為uint后正常
  282.                 Offset1=(200-(100-Spdate.cYear)-1)*3;
  283.                 while(TRUE)
  284.                 {
  285.                         //格式第一字節BIT7-4 位表示閏月月份,值為0 為無閏月,BIT3-0 對應農歷第1-4 月的大小
  286.                         //第二字節BIT7-0 對應農歷第5-12 月大小,第三字節BIT7 表示農歷第13 個月大小
  287.                         //0x4d,0x4A,0xB8, //2001
  288.                         if(Data[Offset1+1]&L)
  289.                                 day-=30;
  290.                         else
  291.                                 day-=29;
  292.                         L<<=1;
  293.                         if(((Data[Offset1+0]&0xf0)>>4)==Spdate.cMon && Flag1)//(Data[Offset1+0]&0xf0)>>4判斷是否是閏月1平月0
  294.                         {
  295.                                 Flag1=0;
  296.                                 if(Data[Offset1+2]&0x80) day-=30; else day-=29;
  297.                                 continue;
  298.                         }
  299.                         if(day>0) Spdate.cMon--;
  300.                         else break;
  301.                         
  302.                         
  303.                 }
  304.                 Spdate.cDay=-day+1;
  305.         }
  306.         
  307.         if(!F)
  308.         {
  309.                 Spdate.cMon=1;
  310.                 //這邊Offset1計算會出現超范圍,因此把uchar類型改為uint后正常
  311.                 Offset1=(200-(100-Spdate.cYear)-1)*3;
  312.                 Temp16=(Data[Offset1+0]<<8)+Data[Offset1+1];
  313.                 while(TRUE)
  314.                 {
  315.                         if(Temp16 & L1) day-=30; else day-=29;
  316.                         if(day>=0)
  317.                                 Spdate.cMon++;
  318.                         else if(day<0)
  319.                         {
  320.                                 if(Temp16 & L1) day+=30; else day+=29;
  321.                                 break;
  322.                         }
  323.                         L1>>=1;
  324.                         //格式第一字節BIT7-4 位表示閏月月份,值為0 為無閏月,BIT3-0 對應農歷第1-4 月的大小
  325.                         //第二字節BIT7-0 對應農歷第5-12 月大小,第三字節BIT7 表示農歷第13 個月大小
  326.                         if(((Data[Offset1+0]&0xf0)>>4)==(Spdate.cMon-1) && Flag1) //閏月
  327.                         {
  328.                                 Flag1=0;
  329.                                 Spdate.cMon--;
  330.                                 if(Temp16 & L1) day-=30; else day-=29;
  331.                                 if(day>=0)
  332.                                         Spdate.cMon++;
  333.                                 else if(day<0)
  334.                                 {
  335.                                         if(Temp16 & L1) day+=30; else day+=29;
  336.                                         break;
  337.                                 }
  338.                                 L1>>=1;
  339.                         }
  340.                 }
  341.                 Spdate.cDay=day+1;
  342.         }
  343.     return Spdate;
  344. }

  345. bit YearFlag(uchar cYear) //判斷平年,閏年
  346. {
  347.    if( (!(cYear%4) && (cYear%100)) || !(cYear%400) ) return 1; else return 0;
  348. }

  349. //目標日期是星期幾
  350. uchar GetWeekDay(uchar cYear,uchar cMon,uchar cDay)
  351. {
  352.         char i;
  353.         int  Sum=0,tmpyear=2000+cYear;
  354.         for(i=1;i<=cMon-1;i++)
  355.                 Sum+=Mon1[YearFlag(cYear)][i];
  356.         Sum+=cDay-1;
  357.         
  358.         return (((tmpyear-1)+(tmpyear-1)/4-(tmpyear-1)/100+(tmpyear-1)/400+Sum)%7)+1;
  359. }

  360. void main()
  361. {
  362.         for(;;)
  363.         {
  364.         GetSpringDay(18,12,30);        //輸入數據為十進制,不是BCD碼格式,這個請注意

  365.         }
  366. }

  367. /*****************************************************************************

  368. 首先要能記住十大天干和十二地支,
  369. 十天干:  甲、乙、丙、丁、戊、己、庚、辛、壬、癸;
  370. 十二地支:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥;

  371. 天干地支紀年法首先是天干在前,地支在后,比如今年2005就為-乙酉年,先來算算天干,
  372. 有個公式:
  373. 4、 5、 6、 7、 8、 9、 0、 1、 2、 3 對應的十天干就是
  374. 甲、乙、丙、丁、戊、己、庚、辛、壬、癸,
  375. 數字為年代的最后的一位數字,比如今年是2005,最后一位是5,對應的天干就是乙;

  376. 地支的算法:用年代數除以12,后面的余數就代表某個地支,
  377. 余數分別為:4、 5、 6、 7、 8、 9、 10、 11、 0(能整除)、1、 2、3.
  378. 代表地支為:子、丑、寅、卯、辰、巳、午、 未、 申、酉、戌、亥.
  379. 比如2005年為例:年代末尾數為5,對應的天干為乙,2005除以12,余數為1,對應的地支為酉,所以2005年為乙酉年。

  380. ******************************************************************************/
復制代碼

全部資料51hei下載地址:
4545456.rar (10.77 KB, 下載次數: 108)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏10 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:205015 發表于 2019-4-13 08:49 | 只看該作者
感謝代碼開源分享,嘗試一下。
回復

使用道具 舉報

板凳
ID:350962 發表于 2019-10-29 23:57 | 只看該作者
本帖最后由 ac9979 于 2019-11-5 22:09 編輯

前段時間用STC15L104W改了一個時鐘,增加了農歷顯示功能,參照了你的程序,但是文件大小超出了范圍,只好想辦法精簡程序,發現如果農歷年和陽歷不是同一年,可以遞歸調用本函數 GetSpringDay(GreYear+1, GreMon+12, GreDay),代碼會少30%,這個判斷就不需要了:  if(F)    //春節在公歷日期后{ ……} 。
具體代碼如下:





typedef unsigned int u16;  //16位無符號整型數
typedef unsigned char u8;  //8位無符號整型數


u8 dn(u8 yy,u8 mm,u8 dd);                                   //公歷轉農歷函數
u8 temp;
u8 NonY=0;                                                     //農歷年
u8 NonM=0;                                                     //農歷月
u8 NonD=0;                                                     //農歷日


u16 nday[]={0,31,59,90,120,151,181,212,243,273,304,334,365,396};     //第n-1月有多少天

       
//公歷年對應的農歷數據,每年三字節,
//格式第一字節BIT7-4 位表示閏月月份,值為0 為無閏月,BIT3-0 對應農歷第1-4 月的大小
//第二字節BIT7-0 對應農歷第5-12 月大小,第三字節BIT7 表示農歷第13 個月大小
//月份對應的位為1 表示本農歷月大(30 天),為0 表示小(29 天).
//第三字節BIT6-5 表示春節的公歷月份,BIT4-0 表示春節的公歷日期       


u8 code Data[]={   
0x0C,0x96,0x45, //2000
0x4d,0x4A,0xB8, //2001
0x0d,0x4A,0x4C, //2002
0x0d,0xA5,0x41, //2003
0x25,0xAA,0xB6, //2004
0x05,0x6A,0x49, //2005
0x7A,0xAd,0xBd, //2006
0x02,0x5d,0x52, //2007
0x09,0x2d,0x47, //2008
0x5C,0x95,0xBA, //2009
0x0A,0x95,0x4e, //2010
0x0B,0x4A,0x43, //2011
0x4B,0x55,0x37, //2012
0x0A,0xd5,0x4A, //2013
0x95,0x5A,0xBf, //2014
0x04,0xBA,0x53, //2015
0x0A,0x5B,0x48, //2016
0x65,0x2B,0xBC, //2017
0x05,0x2B,0x50, //2018
0x0A,0x93,0x45, //2019
0x47,0x4A,0xB9, //2020
0x06,0xAA,0x4C, //2021
0x0A,0xd5,0x41, //2022
0x24,0xdA,0xB6, //2023
0x04,0xB6,0x4A, //2024
0x69,0x57,0x3d, //2025
0x0A,0x4e,0x51, //2026
0x0d,0x26,0x46, //2027
0x5e,0x93,0x3A, //2028
0x0d,0x53,0x4d, //2029
0x05,0xAA,0x43, //2030
0x36,0xB5,0x37, //2031
0x09,0x6d,0x4B, //2032
0xB4,0xAe,0xBf, //2033
0x04,0xAd,0x53, //2034
0x0A,0x4d,0x48, //2035
0x6d,0x25,0xBC, //2036
0x0d,0x25,0x4f, //2037
0x0d,0x52,0x44, //2038
0x5d,0xAA,0x38, //2039
0x0B,0x5A,0x4C, //2040
0x05,0x6d,0x41, //2041
0x24,0xAd,0xB6, //2042
0x04,0x9B,0x4A, //2043
0x7A,0x4B,0xBe, //2044
0x0A,0x4B,0x51, //2045
0x0A,0xA5,0x46, //2046
0x5B,0x52,0xBA, //2047
0x06,0xd2,0x4e, //2048
0x0A,0xdA,0x42, //2049
0x35,0x5B,0x37, //2050
0x09,0x37,0x4B, //2051
0x84,0x97,0xC1, //2052
0x04,0x97,0x53, //2053
0x06,0x4B,0x48, //2054
0x66,0xA5,0x3C, //2055
0x0e,0xA5,0x4f, //2056
0x06,0xB2,0x44, //2057
0x4A,0xB6,0x38, //2058
0x0A,0xAe,0x4C, //2059
0x09,0x2e,0x42, //2060
0x3C,0x97,0x35, //2061
0x0C,0x96,0x49, //2062
0x7d,0x4A,0xBd, //2063
0x0d,0x4A,0x51, //2064
0x0d,0xA5,0x45, //2065
0x55,0xAA,0xBA, //2066
0x05,0x6A,0x4e, //2067
0x0A,0x6d,0x43, //2068
0x45,0x2e,0xB7, //2069
0x05,0x2d,0x4B, //2070
0x8A,0x95,0xBf, //2071
0x0A,0x95,0x53, //2072
0x0B,0x4A,0x47, //2073
0x6B,0x55,0x3B, //2074
0x0A,0xd5,0x4f, //2075
0x05,0x5A,0x45, //2076
0x4A,0x5d,0x38, //2077
0x0A,0x5B,0x4C, //2078
0x05,0x2B,0x42, //2079
0x3A,0x93,0xB6, //2080
0x06,0x93,0x49, //2081
0x77,0x29,0xBd, //2082
0x06,0xAA,0x51, //2083
0x0A,0xd5,0x46, //2084
0x54,0xdA,0xBA, //2085
0x04,0xB6,0x4e, //2086
0x0A,0x57,0x43, //2087
0x45,0x27,0x38, //2088
0x0d,0x26,0x4A, //2089
0x8e,0x93,0x3e, //2090
0x0d,0x52,0x52, //2091
0x0d,0xAA,0x47, //2092
0x66,0xB5,0x3B, //2093
0x05,0x6d,0x4f, //2094
0x04,0xAe,0x45, //2095
0x4A,0x4e,0xB9, //2096
0x0A,0x4d,0x4C, //2097
0x0d,0x15,0x41, //2098
0x2d,0x92,0xB5, //2099
};


u8 dn(u8 yy,u8 mm,u8 dd)
{
        u16        nyear=2000+yy;              //僅計算2000~2099年
        bit RunY=0;                     //公歷閏年標志
        bit Flag1=1;                    //農歷閏月標志
        u8 SpM;                         //春節公歷月份
        u8 SpD;                         //春節公歷日期
        u8 SpN;                                                                                                  //春節是本公歷年第幾天
       
        u8 RunM=0;                                                                            //農歷閏月月份       
       
        int Diff;
        int day;
       
        u16 CuN;                                                            //當前日期是本公歷年第幾天
        u16 Offset1;
        u16 Temp16;
        u16 L1=0x8000;
       
       

       
       
       
        SpM=(Data[yy*3+2]&0x60)>>5; //計算春節公歷月份       
        SpD=(Data[yy*3+2])&0x1f;    //計算春節公歷日期       
        SpN=nday[SpM-1]+SpD;                                //計算春節是本年第幾天,因為春節永遠在公歷3月前,所以不用考慮2月是28天還是29天
       
        //判斷本公歷年是否閏年
        if ( nyear %4 ==0   &&         nyear % 100 !=0 )
                RunY=1;
        if ( nyear % 400 ==0   )
                RunY=1;
       
        //計算當前日期本公歷年第幾天
        if ( RunY==1 && mm > 2 )
                CuN=nday[mm-1]+dd+1;         
        else
                CuN=nday[mm-1]+dd;
       
               
        Diff=CuN-SpN;                                                                   //計算當前日期與春節相差多少天
       
       
        if( Diff >=0 )       
        {       
                        NonY=yy;
                        day=Diff;
                        NonM=1;
                        Offset1=(yy)*3;       
               
                        //格式第一字節BIT3-0 對應農歷第1-4 月的大小
                        //第二字節BIT7-0 對應農歷第5-12 月大小,第三字節BIT7 表示農歷第13 個月大小
                        Temp16=((Data[Offset1+0]&0x0f)<<12)+(Data[Offset1+1]<<4)+((Data[Offset1+2]&0xf0)>>4);                                                                


                        while ( 1 )
                        {
                                                        if(Temp16 & L1) day-=30; else day-=29;
                               
                                                        if(day>=0)
                                                                        NonM++;
                                                        else if(day<0)
                                                        {
                                                                        if(Temp16 & L1) day+=30; else day+=29;
                                                                        break;
                                                        }
                                                        L1>>=1;
                                                       
                                                        //格式第一字節BIT7-4 位表示閏月月份,值為0 為無閏月
                                                        if(((Data[Offset1+0]&0xf0)>>4)==(NonM-1) && Flag1) // 閏月,幸好從來不閏正月
                                                        {
                                                                                        Flag1=0;
                                                                                        NonM--;
                                                                                        RunM=NonM;                                                                                       
                                                        }
                        }
                        NonD=day+1;       
                       
        }
        else   //如果當前日期還在春節前,則農歷還是上一年,公歷月份增加12個月,然后遞歸調用
        {
                        RunM = dn( yy-1,mm+12,dd );               
               
        }



        return(RunM);       
}

       
       

void main()
{

        temp=dn( 18 ,10 ,12 );   //調用公歷轉農歷函數,返回值為閏月月份,如果日期在閏月之前,則返回值為0;
               
        if( temp == NonM )
                                        ;                //表示此月是閏月
        else
                                        ;
       
       
}
  

Clock.rar

2.07 KB, 下載次數: 41, 下載積分: 黑幣 -5

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

地板
ID:268118 發表于 2019-11-2 00:35 | 只看該作者
感謝兩位版主的分享。
回復

使用道具 舉報

5#
ID:584814 發表于 2020-2-16 20:05 | 只看該作者
星期也可以通過日期來計算的,而且算法簡單(蔡勒Zeller公式)。
回復

使用道具 舉報

6#
ID:721769 發表于 2021-6-6 17:57 | 只看該作者
基姆拉爾森 星期計算公式& 蔡勒 星期計算公式, 其實都是大同小異的

  1. /*        @funciton: Calculate weekday in KimLarsen formula
  2.         @parameters: year, month, day
  3.         @return: weekday
  4. */
  5. int calculateWeekByKimLarsen(int year, int month, int day)
  6. {
  7.         int iY = year, iM = month, iD = day, iWeekDay;

  8.         if (1 == iM || 2 == iM){   
  9.         iM += 12;
  10.         iY--;
  11.     }
  12.     iWeekDay = (iD + 1 + iM*2 + 3*(iM+1)/5 + iY + iY/4 - iY/100 + iY/400) % 7;

  13.     return iWeekDay;
  14. }

  15. /*        @funciton: Calculate weekday in Zella formula
  16.         @parameters: year, month, day
  17.         @return: weekday
  18. */
  19. int calculateWeekByZella( int year , int month, int day )
  20. {
  21.         int c,y,week;

  22.         if (month == 1 || month == 2){
  23.                 year--;
  24.                 month += 12;
  25.         }
  26.         c = year / 100;
  27.         y = year - c * 100;
  28.         week = y + y/4 + c/4 - 2*c + 26*(month+1)/10 + day - 1;
  29.         while (week<0){
  30.                 week += 7;
  31.         }
  32.         week %= 7;

  33.         return (week);
  34. }
復制代碼
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品一区二区三区中文字幕 | 日韩成人在线网站 | 欧美一区视频 | 成人性视频免费网站 | 欧美一二三四成人免费视频 | 国产黄色一级电影 | 99国内精品| 国产精品成人久久久久 | www.五月天婷婷.com | 亚洲精品一区二区 | 在线中文字幕av | 成人在线免费电影 | 国产精品黄 | 日韩欧美一区二区三区免费看 | 成人精品一区二区三区中文字幕 | 亚洲精品视频在线 | 欧美日韩亚洲国产 | 色网在线观看 | 国产传媒毛片精品视频第一次 | 91精品国产综合久久福利软件 | 日韩av啪啪网站大全免费观看 | 国产精品一二区 | 精品一区二区三区视频在线观看 | 综合久久综合久久 | 国产激情视频网站 | 精品国产欧美 | 日韩精品av一区二区三区 | 国偷自产av一区二区三区 | 香蕉久久av| 91精品国产91久久久久青草 | 99av成人精品国语自产拍 | 在线观看亚洲专区 | 亚洲精品久久久一区二区三区 | 久久一区二区三区电影 | 一区二区精品视频 | 成人免费网站 | 美女视频网站久久 | 国产粉嫩尤物极品99综合精品 | 国产一区二区三区四区hd | 狠狠操狠狠干 | 亚洲免费观看视频 |