公历转农历、生肖、干支纪年、节气算法研究和C程序实现
[本文發布于https://blog.csdn.net/Stack_/article/details/119980697,未經許可不得轉載,轉載須注明出處]
一、參考文章
陽歷轉陰歷算法概述
1900年至2100年公歷、農歷互轉Js代碼
農歷的那些事兒(一)
香港天文臺農歷數據(txt版)
香港天文臺農歷數據(pdf版)
二、關于農歷
查閱了大量關于公歷轉農歷的博文之后,明確了:所謂的公歷轉農歷算法即系基于查表法推算。因為農歷無明顯規律,數據需要天文臺觀測得到,因此無法用公式將公歷轉成農歷。
如果愿意花錢,可以每天發請求從特定網站獲取json文本并解析得到這些數據。不像時間和天氣信息,免費的農歷服務都是些小網站在提供,有些已經停止了這些服務,或者即將關停。
要制表就需要公歷 - 農歷對照數據。
官方網站 - 香港天文臺,僅此一家在網上公開了公歷 - 農歷對照數據。
都說內地僅紫金山天文臺有發布農歷數據,前幾年也發布了農歷國標,但數據在哪呢?
三、制表 (年月日)
上面的博文的數據均來自香港天文臺,香港天文臺公開的數據范圍為1901年至2100年。
上面的博文的博主已將對照數據按一定格式轉成了十六進制數據制成了表,發布在博文內或者GitHub上。在此感謝那兩位博主。
/* 經文本對比,兩組數據的1933年、1996年、2033年、2057年、2060年有區別 */ /* 遂和天文臺的數據對比,嗯。。。兩組數據你錯我就對 */ /* 注意只對比了有區別的這幾個年份,并沒有驗證所所有年份數據 */ /* 1900年的數據兩個都對,第二組只包含了1900年的農歷十一、十二月份 */ /* 1900年1月31日為正月初一 */ /* 1901年2月19日為正月初一 */ @ CSDN Tyrion.Mon uint32_t NongLi_Info[] = {0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-19090x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-19190x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-19290x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939 //1933有誤0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-19490x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-19590x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-19690x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-19790x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-19890x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999 //1996有誤0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-20090x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-20190x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-20290x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-20390x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-20490x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059 //2057有誤0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069 //2060有誤0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-20790x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-20890x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-20990x0d520 //2100 };uint32_t LUNAR_INFO[] = {0x00010, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-19090x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-19190x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-19290x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-19390x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-19490x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-19590x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-19690x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-19790x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-19890x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, //1990-19990x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-20090x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-20190x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-20290x05aa0, 0x076a3, 0x096d0, 0x026fb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039 //2033有誤0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-20490x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06aa0, 0x1a6c4, 0x0aae0, //2050-20590x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-20690x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-20790x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-20890x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-20990x0d520 //2100 };
每個32位數據各代表一年,其中bit0 - bit16共17位有意義。
| bit [3:0] | 數值范圍為0 - C 。0 代表此年不存在閏月,非零表示此年有閏月,具體數值 1 - C 表示閏月月份 |
| bit [15:4] | bit 15 - bit 4 分別代表此年的1 - 12月,為 0 表示此月為小月(29日),為 1 表示大月(30日) |
| bit16 | 在bit [3:0] 為 0 時忽略;其值僅在bit [3:0]不為 0 時有效,為1時表示該年閏月為大月,為 0 時表小月 |
| 每隔開兩三年出現一次閏年,閏年比非閏年多出一個月,例如某年為閏年,閏月月份為5月,則在5月和6月之間增加一個閏月,稱為閏5月 | 某年閏月為大月還是小月需要根據bit16確定 |
四、干支紀年
根據 天干 :甲、乙、丙、丁、戊、己、庚、辛、壬、癸 以及 地支 : 子(鼠)、丑(牛)、寅(虎)、卯(兔)、辰(龍)、巳(蛇)、午(馬)、未(羊)、申(猴)、酉(雞)、戌(狗)、亥(豬) 混合編排,60年一個輪回。
以立春還是正月初一作為干支紀年上一年和下一年的界限,眾說紛紜。小米手機的日歷是以正月初一作為界限。
1901年和2021年都是辛丑年,辛丑條約距今已120年。
五、二十四節氣
參考文章
二十四節氣的日期數學計算公式
計算公式基本都與這一篇相同,20世紀與22世紀的數據不全。
六、程序實現
實現了根據公歷年月日計算出農歷月日、生肖、干支紀年、節氣,在VS CODE上驗證過一小部分,不保證不會出錯。
#include <stdio.h> #include <stdint.h> #include <math.h>uint32_t LUNAR_INFO[] = {@ CSDN Tyrion.Mon0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-19090x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-19190x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-19290x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-19390x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-19490x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-19590x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-19690x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-19790x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-19890x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, //1990-19990x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-20090x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-20190x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-20290x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-20390x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-20490x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06aa0, 0x1a6c4, 0x0aae0, //2050-20590x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-20690x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-20790x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-20890x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-20990x0d520 //2100 };typedef struct {uint16_t year;uint8_t month;uint8_t date;uint8_t week;uint8_t hour;uint8_t minute;uint8_t second; } Solar_t; //公歷typedef struct {uint8_t has_leap_month; // 1 此年有閏月, 0 無/* 如果有閏月下面2個才有意義 */uint8_t leapWhichMonth; // 此年閏月是哪個月份uint8_t leapMonthis_30days; // 1 此年閏大月, 0 閏小月uint8_t month; // 當前農歷月份uint8_t is_leap_month; // 1 當前農歷月是閏月 0非閏月uint8_t date; // 當前農歷日uint8_t animal; // 此農歷年生肖 1 - 12 : 鼠 - 豬uint8_t tian_gan; // 1-10甲、乙、丙、丁、戊、己、庚、辛、壬、癸uint8_t di_zhi; // 1-12子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥 } Lunar_t; //農歷/*** @brief 計算公歷年份是閏還是平* @note * @param * @retval * @author PWH @ CSDN Tyrion.Mon* @date 2021/6*/ uint8_t IsLeapYear(uint16_t year) {if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)return 1; //是閏年return 0; //是平年 }/*** @brief 計算公歷兩個日期的間隔天數* @note Solar2的年月日必須晚于Solar1或相等* @param * @retval * @author PWH @ CSDN Tyrion.Mon* @date 2021/6*/ uint32_t Calc_Solar_DateInterval(Solar_t *Solar1, Solar_t *Solar2) {int16_t i = 0;uint8_t MonthDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};uint32_t TotalDays1 = 0; //Solar1uint32_t TotalDays2 = 0; //Solar2uint32_t TotalDays = 0; //記錄間隔總天數/* 計算從Solar1->year 1月1日到Solar1->month Solar2->date的總天數 */MonthDays[1] = (IsLeapYear(Solar1->year) ? 29 : 28);for (i = 1; i < Solar1->month; i++){TotalDays1 += MonthDays[i - 1]; //累計1月到month-1月的天數}TotalDays1 += Solar1->date; //最后加上month月已達天數,和值即為本年1月1日到輸入日期的天數/* 計算從Solar2->year 1月1日到Solar2->month Solar2->date的總天數 */MonthDays[1] = (IsLeapYear(Solar2->year) ? 29 : 28);for (i = 1; i < Solar2->month; i++){TotalDays2 += MonthDays[i - 1];}TotalDays2 += Solar2->date;/* 如果為同一年 */if (Solar1->year == Solar2->year){TotalDays = TotalDays2 - TotalDays1;}else{/* 計算兩個年份之間的年份的總天數 */for (i = Solar1->year + 1; i < Solar2->year; i++){TotalDays += (IsLeapYear(i) ? 366 : 365);}/* Solar1->year剩余天數 + 兩年之間年份總天數 + Solar2->year已過天數 */TotalDays += ((IsLeapYear(Solar1->year) ? 366 : 365) - TotalDays1 + TotalDays2);}printf("TotalDays = %d\r\n", TotalDays);return TotalDays; }/*** @brief 計算此農歷年是否有閏月* @note * @param * @retval -1 輸入錯誤* 0 無閏月* 1 有閏月* @author PWH @ CSDN Tyrion.Mon* @date 2021/6*/ int8_t Calc_thisLunarYear_HasLeapMonth(uint16_t SolarYear, Lunar_t *Lunar) {if (SolarYear < 1900 || SolarYear > 2100) return -1;/* 為 0 或者大于12, 無閏月 */if ((LUNAR_INFO[SolarYear - 1900] & 0x0000000f) == 0 || (LUNAR_INFO[SolarYear - 1900] & 0x0000000f) > 12){Lunar->has_leap_month = 0;return 0;}/* 存在閏月 */Lunar->has_leap_month = 1;Lunar->leapWhichMonth = LUNAR_INFO[SolarYear - 1900] & 0x0000000f; // bit3-bit0 該年閏月月份Lunar->leapMonthis_30days = (LUNAR_INFO[SolarYear - 1900] >> 16) & 0x00000001; // bit16 閏月為大還是小 1大0小return 1; } /*** @brief 計算此年農歷月(非閏月)的天數* @note * @param * @retval -1 輸入錯誤* 正確值為29或30* @author PWH @ CSDN Tyrion.Mon* @date 2021/6*/ int8_t Calc_thisLunarMonth_Days(uint16_t SolarYear, uint8_t LunarMonth) {if (SolarYear < 1900 || SolarYear > 2100) return -1;if (LunarMonth < 1 || LunarMonth > 12) return -1;/* 農歷1月bit15, 2月bit14,12月bit4 */if ( ( LUNAR_INFO[SolarYear - 1900] >> ((12 - LunarMonth) + 4) ) & 0x00000001 ){return 30;}else{return 29;} } /*** @brief 根據間隔天數計算農歷月日* @note 1900/1/31為正月初一,鼠年,以此為起點* @param * @retval * @author PWH @ CSDN Tyrion.Mon* @date 2021/6*/ int8_t Calc_Lunar_From_DateInterval(uint32_t DateInterval, Lunar_t *LU) {uint16_t SolarYear = 1900;uint32_t DI_temp = 0;int8_t err;LU->has_leap_month = 0;LU->leapWhichMonth = 0;LU->leapMonthis_30days = 0;LU->is_leap_month = 0; //1900農歷1月非閏月LU->month = 1; //1900正月初一始LU->date = 1;LU->animal = 1; //鼠LU->tian_gan = 7; //庚LU->di_zhi = LU->animal; //子while (1){/* 查詢此年是否存在閏月,閏月為閏幾月,閏大月還是閏小月 */err = Calc_thisLunarYear_HasLeapMonth(SolarYear, LU);if (err == -1) return -1; //輸入參數有誤/* 如果當前月為閏月 */if (LU->is_leap_month == 1){/* 為大月,則加30日,否則29日 */DI_temp += LU->leapMonthis_30days ? 30 : 29;}else /* 當前月非閏月 */{ /* 查詢非閏月月份的天數 */DI_temp += Calc_thisLunarMonth_Days(SolarYear, LU->month);}/* 總天數已達, 當前月即是目標農歷月 */if (DI_temp >= DateInterval){/* 如果當前月為閏月 */if (LU->is_leap_month == 1){LU->date = (LU->leapMonthis_30days ? 30 : 29) - (DI_temp - DateInterval);}else{LU->date = Calc_thisLunarMonth_Days(SolarYear, LU->month) - (DI_temp - DateInterval);}return 1;}/* 未達 *//* 此年有閏月 并且今年未到過閏月 */if ((LU->has_leap_month == 1) && (LU->is_leap_month == 0)){/* 如果此年閏月月份和當前月一樣, 此時應該在當前月和下一個月之間插入一個閏月 *//* 因為上面的步驟已累加了閏月前一個月份的天數,所以直接跳到閏月,并標記當前月為閏月 */if (LU->leapWhichMonth == LU->month){LU->is_leap_month = 1; //標記現在是閏月,如果當前月是5月,匹配上了,那這個閏月就是閏5月printf("SolarYear %d LEAP MONTH is %d\r\n", SolarYear, LU->leapWhichMonth);}else{LU->month += 1;}}/* 此年有閏月且今個月為閏月 或者 此年無閏月 */else if ( ((LU->has_leap_month == 1) && (LU->is_leap_month == 1))|| (LU->has_leap_month == 0) ){LU->is_leap_month = 0; //閏月下一個月為非閏月LU->month += 1;}/* 溢出處理, 生肖, 天干地支 */if (LU->month > 12){if (++SolarYear > 2100) return -1;LU->month = 1;if (++LU->animal > 12){LU->animal = 1;}if (++LU->tian_gan > 10){LU->tian_gan = 1;}}LU->di_zhi = LU->animal;} }/*** @brief 公歷年月日轉農歷月日* @note * @param * @retval * @author PWH @ CSDN Tyrion.Mon* @date 2021/6*/ int8_t Solar2Lunar(Solar_t *so, Lunar_t *lu) {Solar_t solar_1900;/* 1900/1/31為正月初一,鼠年,以此為起點 */solar_1900.year = 1900; /* 不 */solar_1900.month = 1; /* 要 */solar_1900.date = 31; /* 改 */return Calc_Lunar_From_DateInterval(Calc_Solar_DateInterval(&solar_1900, so) + 1, lu); }/*** @brief 計算某個公歷年的24節氣對應日期* @note 2月 立春 雨水* 3月 驚蟄 春分* 4月 清明 谷雨* 5月 立夏 小滿* 6月 芒種 夏至* 7月 小暑 大暑* 8月 立秋 處暑* 9月 白露 秋分* 10月 寒露 霜降* 11月 立冬 小雪* 12月 大雪 冬至* 1月 小寒 大寒* @param * @retval * @author PWH @ CSDN Tyrion.Mon* @date 2021/6*/ int8_t Calc_24SolarTerms(uint16_t SolarYear, uint8_t *Array_24SolarTermDate) {uint8_t i = 0;uint8_t Y = SolarYear % 100; //年份后兩位double D = 0.2422;double C_20xx[] = //21世紀24個節氣的C值{3.87, 18.73, 5.63, 20.646, 4.81, 20.1,5.52, 21.04, 5.678, 21.37, 7.108, 22.83,7.5, 23.13, 7.646, 23.042, 8.318, 23.438,7.438, 22.36, 7.18, 21.94, 5.4055, 20.12};if (SolarYear < 2001 || SolarYear > 2099) return -1;for (i = 0; i < 24; i++){if (i <= 1 || i >= 22)Array_24SolarTermDate[i] = ((uint16_t)(Y * D + C_20xx[i])) - ((Y - 1) / 4);elseArray_24SolarTermDate[i] = ((uint16_t)(Y * D + C_20xx[i])) - (Y / 4);/* 例外 */if (SolarYear == 2026 && i == 1){Array_24SolarTermDate[i] -= 1; //例外:2026年計算得出的雨水日期應調減一天為18日。}else if (SolarYear == 2084 && i == 3){Array_24SolarTermDate[i] += 1; //例外:2084年的計算結果加1日。}else if (SolarYear == 1911 && i == 6){Array_24SolarTermDate[i] += 1; //例外:1911年的計算結果加1日}else if (SolarYear == 2008 && i == 7){Array_24SolarTermDate[i] += 1; //例外:2008年的計算結果加1日}else if (SolarYear == 1902 && i == 8){Array_24SolarTermDate[i] += 1; //例外:1902年的計算結果加1日}else if (SolarYear == 1928 && i == 9){Array_24SolarTermDate[i] += 1; //例外:1928年的計算結果加1日。}else if ((SolarYear == 1925 || SolarYear == 2016) && i == 10){Array_24SolarTermDate[i] += 1; //例外:1925年和2016年的計算結果加1日。}else if (SolarYear == 1922 && i == 11){Array_24SolarTermDate[i] += 1; //例外:1922年的計算結果加1日。}else if (SolarYear == 2002 && i == 12){Array_24SolarTermDate[i] += 1; //例外:2002年的計算結果加1日。}else if (SolarYear == 1927 && i == 14){Array_24SolarTermDate[i] += 1; //例外:1927年的計算結果加1日。}else if (SolarYear == 1942 && i == 15){Array_24SolarTermDate[i] += 1; //例外:1942年的計算結果加1日。}else if (SolarYear == 2089 && i == 17){Array_24SolarTermDate[i] += 1; //例外:2089年的計算結果加1日。}else if (SolarYear == 2089 && i == 18){Array_24SolarTermDate[i] += 1; //例外:2089年的計算結果加1日。}else if (SolarYear == 1978 && i == 19){Array_24SolarTermDate[i] += 1; //例外:1978年的計算結果加1日。}else if (SolarYear == 1954 && i == 20){Array_24SolarTermDate[i] += 1; //例外:1954年的計算結果加1日。}else if ((SolarYear == 1918 || SolarYear == 2021) && i == 21){Array_24SolarTermDate[i] -= 1; //例外:1918年和2021年的計算結果減1日。}else if (SolarYear == 1982 && i == 22){Array_24SolarTermDate[i] += 1; //例外:1982年計算結果加1日,2019年減1日。}else if (SolarYear == 2019 && i == 22){Array_24SolarTermDate[i] -= 1; //例外:1982年計算結果加1日,2019年減1日。}else if (SolarYear == 2082 && i == 23){Array_24SolarTermDate[i] += 1; //例外:2082年的計算結果加1日}}return 1; } int main(void) {uint8_t i;Solar_t solar_1;Lunar_t Lunar_1;uint8_t Array_24SoTermDate[12];solar_1.year = 1901;solar_1.month = 9;solar_1.date = 4;Solar2Lunar(&solar_1, &Lunar_1);printf("has_leap_month = %d\r\n", Lunar_1.has_leap_month);printf("leapWhichMonth = %d\r\n", Lunar_1.leapWhichMonth);printf("leapMonthis_30days = %d\r\n", Lunar_1.leapMonthis_30days);printf("month = %d\r\n", Lunar_1.month);printf("is_leap_month = %d\r\n", Lunar_1.is_leap_month);printf("date = %d\r\n", Lunar_1.date);printf("animal = %d\r\n", Lunar_1.animal);printf("tiangan = %d, dizhi = %d\r\n", Lunar_1.tian_gan, Lunar_1.di_zhi);if (Calc_24SolarTerms(2008, Array_24SoTermDate) != -1){for (i = 0; i < 24; i++)printf("SolarTerm %d: date %d\r\n", i, Array_24SoTermDate[i]);}while (1){/* code */}return 0; }
總結
以上是生活随笔為你收集整理的公历转农历、生肖、干支纪年、节气算法研究和C程序实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大富翁游戏
- 下一篇: 古董电脑室:2019日记簿(二)