|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 mmxx2015 于 2024-10-22 18:10 编辑
搜索公历转农历方法时,多数结果使用的是查表法,即预置N年的农历特征数据,然后根据这些特征数据把N年内其中任意一天的公历转换为农历。
其中,找到的这篇文章的程序比较容易看懂:
公农历转换和获取二十四节气算法
https://blog.csdn.net/qq_46041930/article/details/108653836
文章中还有转换农历二十四节气和星期日,以下程序没有包含这两段,需要的可以查看原文。
实际测试也发现一些问题:
(1)农历特征表格有6年的数据错误。
- 1960年 闰六月
- 错误数据:{0x7A, 0xD5, 0x3C}, /* 060-1960 */
- 正确数据:{0x6A, 0xD5, 0x3C}, /* 060-1960 */
- 1989年 六月大,七月小
- 错误数据:{0x09, 0x37, 0x46}, /* 089-1989 */
- 正确数据:{0x09, 0x57, 0x46}, /* 089-1989 */
- 0x937=1001,0011,0111
- 0x957=1001,0101,0111
- 2025年 闰六月 三月大,四月小
- 错误数据:{0x69, 0x57, 0x3D}, /* 125-2025 */
- 正确数据:{0x6A, 0x57, 0x3D}, /* 125-2025 */
- 0x957=1001,0101,0111
- 0x95A=1010,0101,0111
- 2057年 八月小,九月大
- 错误数据:{0x06, 0xB2, 0x44}, /* 157-2057 */
- 正确数据:{0x06, 0xAA, 0x44}, /* 157-2057 */
- 0x6B2=0110,1011,0010
- 0x6AA=0110,1010,1010
- 2089年 七月小,八月大
- 错误数据:{0x0D, 0x26, 0x4A}, /* 189-2089 */
- 正确数据:{0x0D, 0x16, 0x4A}, /* 189-2089 */
- 0xD26=1101,0010,0110
- 0xD16=1101,0001,0110
- 2097年 六月小,七月大
- 错误数据:{0x0A, 0x4D, 0x4C}, /* 197-2097 */
- 正确数据:{0x0A, 0x2D, 0x4C}, /* 197-2097 */
- 0xA4D=1010,0100,1101
- 0xA2D=1010,0010,1101
复制代码 (2)表格少1900年,无法转换1901年春节前的农历(需要上一年的农历数据)。
(3)有农历闰月的年份,常规月和闰月均记为闰月,比如2025年六月和闰六月均记为闰月。
一下程序修正了上述问题,添加更详细的注释,部分数据使用结构体使之更容易理解。
经过把公历1901.1.1~2099.12.31转成农历串口输出与从农历查询网http://cn.nongli.info/提取的数据对比,数据一致(顺便说一下,我从网上下载的一份“公历农历对照表 ExcelHome”表格中1960年闰七月是错误的,1960年是闰六月,这份文件可能来着 ExcelHome,可能新版已修正,但因为要注册才能下载,所以未验证)。
程序组成(可按需放在一个或多个文件中):
- //******************************************************************
- // 结构体/联合体声明
- //******************************************************************
- //农历特征数据结构体
- typedef struct
- {
- union
- {
- unsigned char V8;
- struct
- {
- unsigned char Month_1_4_Long_Short:4; //字节0 bit[3:0],农历第1-4月的大小
- unsigned char Leap_Month:4; //字节0 bit[7:4],闰月月份,0表示无闰月
- }Bits;
- }Byte_0;
- unsigned char Month_5_12_Long_Short; //字节1,农历第5-12月大小
- union
- {
- unsigned char V8;
- struct
- {
- unsigned char Spring_Festival_Date:5; //字节2 bit[4:0],春节的公历日期
- unsigned char Spring_Festival_Month:2; //字节2 bit[6:5],春节的公历月份
- unsigned char Month_13_Long_Short:1; //字节2 bit7,农历第13个月大小
- }Bits;
- }Byte_2;
- }Lunar_Year_Code_Typedef;
- //公历转农历返回数据结构体
- typedef struct
- {
- unsigned char Month:5; //月
- unsigned char IS_Leap_Month:1; //闰月标志
- unsigned char Reserved_Bits:2;
- unsigned char Date:8; //日
- }Solar2Lunar_Typedef;
复制代码- //位值
- #define BIT0 0x01
- #define BIT1 0x02
- #define BIT2 0x04
- #define BIT3 0x08
- #define BIT4 0x10
- #define BIT5 0x20
- #define BIT6 0x40
- #define BIT7 0x80
- #define BIT8 0x0100
- #define BIT9 0x0200
- #define BIT10 0x0400
- #define BIT11 0x0800
- #define BIT12 0x1000
- #define BIT13 0x2000
- #define BIT14 0x4000
- #define BIT15 0x8000
复制代码- //******************************************************************
- //* 公历与农历转换年份数据存储数组
- //* 公历年对应的农历数据,每年三字节,
- //* 格式第一字节BIT7-4 位表示闰月月份,值为0为无闰月,BIT3-0对应农历第1-4月的大小
- //* 第二字节BIT7-0对应农历第5-12月大小,第三字节BIT7表示农历第13个月大小
- //* 月份对应的位为1表示本农历月大(30天),为0表示小(29天).
- //* 第三字节BIT6-5表示春节的公历月份,BIT4-0表示春节的公历日期
- //******************************************************************
- //农历特征数据表格(1900年~2099年)
- Lunar_Year_Code_Typedef code Lunar_Year_Code[200] =
- {
- {0x84, 0xB6, 0xBF}, /* 000-1900 */
- {0x04, 0xAE, 0x53}, /* 001-1901 */
- {0x0A, 0x57, 0x48}, /* 002-1902 */
- {0x55, 0x26, 0xBD}, /* 003-1903 */
- {0x0D, 0x26, 0x50}, /* 004-1904 */
- {0x0D, 0x95, 0x44}, /* 005-1905 */
- {0x46, 0xAA, 0xB9}, /* 006-1906 */
- {0x05, 0x6A, 0x4D}, /* 007-1907 */
- {0x09, 0xAD, 0x42}, /* 008-1908 */
- {0x24, 0xAE, 0xB6}, /* 009-1909 */
- {0x04, 0xAE, 0x4A}, /* 010-1910 */
- {0x6A, 0x4D, 0xBE}, /* 011-1911 */
- {0x0A, 0x4D, 0x52}, /* 012-1912 */
- {0x0D, 0x25, 0x46}, /* 013-1913 */
- {0x5D, 0x52, 0xBA}, /* 014-1914 */
- {0x0B, 0x54, 0x4E}, /* 015-1915 */
- {0x0D, 0x6A, 0x43}, /* 016-1916 */
- {0x29, 0x6D, 0x37}, /* 017-1917 */
- {0x09, 0x5B, 0x4B}, /* 018-1918 */
- {0x74, 0x9B, 0xC1}, /* 019-1919 */
- {0x04, 0x97, 0x54}, /* 020-1920 */
- {0x0A, 0x4B, 0x48}, /* 021-1921 */
- {0x5B, 0x25, 0xBC}, /* 022-1922 */
- {0x06, 0xA5, 0x50}, /* 023-1923 */
- {0x06, 0xD4, 0x45}, /* 024-1924 */
- {0x4A, 0xDA, 0xB8}, /* 025-1925 */
- {0x02, 0xB6, 0x4D}, /* 026-1926 */
- {0x09, 0x57, 0x42}, /* 027-1927 */
- {0x24, 0x97, 0xB7}, /* 028-1928 */
- {0x04, 0x97, 0x4A}, /* 029-1929 */
- {0x66, 0x4B, 0x3E}, /* 030-1930 */
- {0x0D, 0x4A, 0x51}, /* 031-1931 */
- {0x0E, 0xA5, 0x46}, /* 032-1932 */
- {0x56, 0xD4, 0xBA}, /* 033-1933 */
- {0x05, 0xAD, 0x4E}, /* 034-1934 */
- {0x02, 0xB6, 0x44}, /* 035-1935 */
- {0x39, 0x37, 0x38}, /* 036-1936 */
- {0x09, 0x2E, 0x4B}, /* 037-1937 */
- {0x7C, 0x96, 0xBF}, /* 038-1938 */
- {0x0C, 0x95, 0x53}, /* 039-1939 */
- {0x0D, 0x4A, 0x48}, /* 040-1940 */
- {0x6D, 0xA5, 0x3B}, /* 041-1941 */
- {0x0B, 0x55, 0x4F}, /* 042-1942 */
- {0x05, 0x6A, 0x45}, /* 043-1943 */
- {0x4A, 0xAD, 0xB9}, /* 044-1944 */
- {0x02, 0x5D, 0x4D}, /* 045-1945 */
- {0x09, 0x2D, 0x42}, /* 046-1946 */
- {0x2C, 0x95, 0xB6}, /* 047-1947 */
- {0x0A, 0x95, 0x4A}, /* 048-1948 */
- {0x7B, 0x4A, 0xBD}, /* 049-1949 */
- {0x06, 0xCA, 0x51}, /* 050-1950 */
- {0x0B, 0x55, 0x46}, /* 051-1951 */
- {0x55, 0x5A, 0xBB}, /* 052-1952 */
- {0x04, 0xDA, 0x4E}, /* 053-1953 */
- {0x0A, 0x5B, 0x43}, /* 054-1954 */
- {0x35, 0x2B, 0xB8}, /* 055-1955 */
- {0x05, 0x2B, 0x4C}, /* 056-1956 */
- {0x8A, 0x95, 0x3F}, /* 057-1957 */
- {0x0E, 0x95, 0x52}, /* 058-1958 */
- {0x06, 0xAA, 0x48}, /* 059-1959 */
- {0x6A, 0xD5, 0x3C}, /* 060-1960 */
- {0x0A, 0xB5, 0x4F}, /* 061-1961 */
- {0x04, 0xB6, 0x45}, /* 062-1962 */
- {0x4A, 0x57, 0x39}, /* 063-1963 */
- {0x0A, 0x57, 0x4D}, /* 064-1964 */
- {0x05, 0x26, 0x42}, /* 065-1965 */
- {0x3E, 0x93, 0x35}, /* 066-1966 */
- {0x0D, 0x95, 0x49}, /* 067-1967 */
- {0x75, 0xAA, 0xBE}, /* 068-1968 */
- {0x05, 0x6A, 0x51}, /* 069-1969 */
- {0x09, 0x6D, 0x46}, /* 070-1970 */
- {0x54, 0xAE, 0xBB}, /* 071-1971 */
- {0x04, 0xAD, 0x4F}, /* 072-1972 */
- {0x0A, 0x4D, 0x43}, /* 073-1973 */
- {0x4D, 0x26, 0xB7}, /* 074-1974 */
- {0x0D, 0x25, 0x4B}, /* 075-1975 */
- {0x8D, 0x52, 0xBF}, /* 076-1976 */
- {0x0B, 0x54, 0x52}, /* 077-1977 */
- {0x0B, 0x6A, 0x47}, /* 078-1978 */
- {0x69, 0x6D, 0x3C}, /* 079-1979 */
- {0x09, 0x5B, 0x50}, /* 080-1980 */
- {0x04, 0x9B, 0x45}, /* 081-1981 */
- {0x4A, 0x4B, 0xB9}, /* 082-1982 */
- {0x0A, 0x4B, 0x4D}, /* 083-1983 */
- {0xAB, 0x25, 0xC2}, /* 084-1984 */
- {0x06, 0xA5, 0x54}, /* 085-1985 */
- {0x06, 0xD4, 0x49}, /* 086-1986 */
- {0x6A, 0xDA, 0x3D}, /* 087-1987 */
- {0x0A, 0xB6, 0x51}, /* 088-1988 */
- {0x09, 0x57, 0x46}, /* 089-1989 */
- {0x54, 0x97, 0xBB}, /* 090-1990 */
- {0x04, 0x97, 0x4F}, /* 091-1991 */
- {0x06, 0x4B, 0x44}, /* 092-1992 */
- {0x36, 0xA5, 0x37}, /* 093-1993 */
- {0x0E, 0xA5, 0x4A}, /* 094-1994 */
- {0x86, 0xB2, 0xBF}, /* 095-1995 */
- {0x05, 0xAC, 0x53}, /* 096-1996 */
- {0x0A, 0xB6, 0x47}, /* 097-1997 */
- {0x59, 0x36, 0xBC}, /* 098-1998 */
- {0x09, 0x2E, 0x50}, /* 099-1999 */
- {0x0C, 0x96, 0x45}, /* 100-2000 */
- {0x4D, 0x4A, 0xB8}, /* 101-2001 */
- {0x0D, 0x4A, 0x4C}, /* 102-2002 */
- {0x0D, 0xA5, 0x41}, /* 103-2003 */
- {0x25, 0xAA, 0xB6}, /* 104-2004 */
- {0x05, 0x6A, 0x49}, /* 105-2005 */
- {0x7A, 0xAD, 0xBD}, /* 106-2006 */
- {0x02, 0x5D, 0x52}, /* 107-2007 */
- {0x09, 0x2D, 0x47}, /* 108-2008 */
- {0x5C, 0x95, 0xBA}, /* 109-2009 */
- {0x0A, 0x95, 0x4E}, /* 110-2010 */
- {0x0B, 0x4A, 0x43}, /* 111-2011 */
- {0x4B, 0x55, 0x37}, /* 112-2012 */
- {0x0A, 0xD5, 0x4A}, /* 113-2013 */
- {0x95, 0x5A, 0xBF}, /* 114-2014 */
- {0x04, 0xBA, 0x53}, /* 115-2015 */
- {0x0A, 0x5B, 0x48}, /* 116-2016 */
- {0x65, 0x2B, 0xBC}, /* 117-2017 */
- {0x05, 0x2B, 0x50}, /* 118-2018 */
- {0x0A, 0x93, 0x45}, /* 119-2019 */
- {0x47, 0x4A, 0xB9}, /* 120-2020 */
- {0x06, 0xAA, 0x4C}, /* 121-2021 */
- {0x0A, 0xD5, 0x41}, /* 122-2022 */
- {0x24, 0xDA, 0xB6}, /* 123-2023 */
- {0x04, 0xB6, 0x4A}, /* 124-2024 */
- {0x6A, 0x57, 0x3D}, /* 125-2025 */
- {0x0A, 0x4E, 0x51}, /* 126-2026 */
- {0x0D, 0x26, 0x46}, /* 127-2027 */
- {0x5E, 0x93, 0x3A}, /* 128-2028 */
- {0x0D, 0x53, 0x4D}, /* 129-2029 */
- {0x05, 0xAA, 0x43}, /* 130-2030 */
- {0x36, 0xB5, 0x37}, /* 131-2031 */
- {0x09, 0x6D, 0x4B}, /* 132-2032 */
- {0xB4, 0xAE, 0xBF}, /* 133-2033 */
- {0x04, 0xAD, 0x53}, /* 134-2034 */
- {0x0A, 0x4D, 0x48}, /* 135-2035 */
- {0x6D, 0x25, 0xBC}, /* 136-2036 */
- {0x0D, 0x25, 0x4F}, /* 137-2037 */
- {0x0D, 0x52, 0x44}, /* 138-2038 */
- {0x5D, 0xAA, 0x38}, /* 139-2039 */
- {0x0B, 0x5A, 0x4C}, /* 140-2040 */
- {0x05, 0x6D, 0x41}, /* 141-2041 */
- {0x24, 0xAD, 0xB6}, /* 142-2042 */
- {0x04, 0x9B, 0x4A}, /* 143-2043 */
- {0x7A, 0x4B, 0xBE}, /* 144-2044 */
- {0x0A, 0x4B, 0x51}, /* 145-2045 */
- {0x0A, 0xA5, 0x46}, /* 146-2046 */
- {0x5B, 0x52, 0xBA}, /* 147-2047 */
- {0x06, 0xD2, 0x4E}, /* 148-2048 */
- {0x0A, 0xDA, 0x42}, /* 149-2049 */
- {0x35, 0x5B, 0x37}, /* 150-2050 */
- {0x09, 0x37, 0x4B}, /* 151-2051 */
- {0x84, 0x97, 0xC1}, /* 152-2052 */
- {0x04, 0x97, 0x53}, /* 153-2053 */
- {0x06, 0x4B, 0x48}, /* 154-2054 */
- {0x66, 0xA5, 0x3C}, /* 155-2055 */
- {0x0E, 0xA5, 0x4F}, /* 156-2056 */
- {0x06, 0xAA, 0x44}, /* 157-2057 */
- {0x4A, 0xB6, 0x38}, /* 158-2058 */
- {0x0A, 0xAE, 0x4C}, /* 159-2059 */
- {0x09, 0x2E, 0x42}, /* 160-2060 */
- {0x3C, 0x97, 0x35}, /* 161-2061 */
- {0x0C, 0x96, 0x49}, /* 162-2062 */
- {0x7D, 0x4A, 0xBD}, /* 163-2063 */
- {0x0D, 0x4A, 0x51}, /* 164-2064 */
- {0x0D, 0xA5, 0x45}, /* 165-2065 */
- {0x55, 0xAA, 0xBA}, /* 166-2066 */
- {0x05, 0x6A, 0x4E}, /* 167-2067 */
- {0x0A, 0x6D, 0x43}, /* 168-2068 */
- {0x45, 0x2E, 0xB7}, /* 169-2069 */
- {0x05, 0x2D, 0x4B}, /* 170-2070 */
- {0x8A, 0x95, 0xBF}, /* 171-2071 */
- {0x0A, 0x95, 0x53}, /* 172-2072 */
- {0x0B, 0x4A, 0x47}, /* 173-2073 */
- {0x6B, 0x55, 0x3B}, /* 174-2074 */
- {0x0A, 0xD5, 0x4F}, /* 175-2075 */
- {0x05, 0x5A, 0x45}, /* 176-2076 */
- {0x4A, 0x5D, 0x38}, /* 177-2077 */
- {0x0A, 0x5B, 0x4C}, /* 178-2078 */
- {0x05, 0x2B, 0x42}, /* 179-2079 */
- {0x3A, 0x93, 0xB6}, /* 180-2080 */
- {0x06, 0x93, 0x49}, /* 181-2081 */
- {0x77, 0x29, 0xBD}, /* 182-2082 */
- {0x06, 0xAA, 0x51}, /* 183-2083 */
- {0x0A, 0xD5, 0x46}, /* 184-2084 */
- {0x54, 0xDA, 0xBA}, /* 185-2085 */
- {0x04, 0xB6, 0x4E}, /* 186-2086 */
- {0x0A, 0x57, 0x43}, /* 187-2087 */
- {0x45, 0x27, 0x38}, /* 188-2088 */
- {0x0D, 0x16, 0x4A}, /* 189-2089 */
- {0x8E, 0x93, 0x3E}, /* 190-2090 */
- {0x0D, 0x52, 0x52}, /* 191-2091 */
- {0x0D, 0xAA, 0x47}, /* 192-2092 */
- {0x66, 0xB5, 0x3B}, /* 193-2093 */
- {0x05, 0x6D, 0x4F}, /* 194-2094 */
- {0x04, 0xAE, 0x45}, /* 195-2095 */
- {0x4A, 0x4E, 0xB9}, /* 196-2096 */
- {0x0A, 0x2D, 0x4C}, /* 197-2097 */
- {0x0D, 0x15, 0x41}, /* 198-2098 */
- {0x2D, 0x92, 0xB5}, /* 199-2099 */
- };
- //公历前n月总天数
- unsigned int code Days_Code[13] =
- {
- 0, //0
- 0, //1,1月:当月
- 31, //2,1月:31
- 59, //3,1~2月:31+28=59
- 90, //4,1~3月:31+28+31=90
- 120, //5,1~4月:31+28+31+30=120
- 151, //6,1~5月:31+28+31+30+31=151
- 181, //7,1~6月:31+28+31+30+31+30=181
- 212, //8,1~7月:31+28+31+30+31+30+31=212
- 243, //9,1~8月:31+28+31+30+31+30+31+31=243
- 273, //10,1~9月:31+28+31+30+31+30+31+31+30=273
- 304, //11,1~10月:31+28+31+30+31+30+31+31+30+31=304
- 334, //12,1~11月:31+28+31+30+31+30+31+31+30+31+30=334
- };
- //农历大小月特征位编码
- unsigned char code Month_Long_Short_Bit_Table[14] =
- {
- 0x00, //0
- BIT3, //1,1月
- BIT2, //2,2月
- BIT1, //3,3月
- BIT0, //4,4月
- BIT7, //5,5月
- BIT6, //6,6月
- BIT5, //7,7月
- BIT4, //8,8月
- BIT3, //9,9月
- BIT2, //10,10月
- BIT1, //11,11月
- BIT0, //12,12月
- BIT7, //13,13月
- };
复制代码- //******************************************************************
- //函数名称:unsigned char Get_Lunar_Month_Days(unsigned char Lunar_Month, unsigned int Offset)
- //函数功能:用于读取数据表中农历月的大月或小月
- //输入参数:Lunar_Month,Offset
- //返回值: 0/1(1:大月;0:小月)
- //******************************************************************
- unsigned char Get_Lunar_Month_Days(unsigned char Lunar_Month, unsigned int Offset)
- {
- unsigned char Month_Long_Short; //大小月
- Month_Long_Short = 0; //无效数据返回小月
- if(Lunar_Month <= Ubound(Month_Long_Short_Bit_Table))
- {
- if(Lunar_Month <= 4) //农历参数表格第0字节bit[3:0]表示农历第1-4月的大小
- {
- Month_Long_Short = (Lunar_Year_Code[Offset].Byte_0.Bits.Month_1_4_Long_Short & Month_Long_Short_Bit_Table[Lunar_Month]);
- }
- else if(Lunar_Month <= 12) //农历参数表格第1字节bit[7:0]表示农历第5-12月的大小
- {
- Month_Long_Short = (Lunar_Year_Code[Offset].Month_5_12_Long_Short & Month_Long_Short_Bit_Table[Lunar_Month]);
- }
- else //农历第13个月大小
- {
- Month_Long_Short = Lunar_Year_Code[Offset].Byte_2.Bits.Month_13_Long_Short;
- }
- }
- if(Month_Long_Short)
- {
- Month_Long_Short = 1;
- }
- return Month_Long_Short;
- }
复制代码- //******************************************************************
- //函数名称:Solar2Lunar_Typedef Get_China_Calendar(unsigned int Year,unsigned char Month,unsigned char Day)
- //函数功能:公农历转换
- //输入参数:Year:公历年(只允许1901-2099年) Month:公历月 Day:公历日
- //返回值: 0/1 1对应转换成功,0对应转换失败
- //******************************************************************
- #define C_SOLAR_YEAR_MIN 1901 //公历年最小值
- #define C_SOLAR_YEAR_MAX 2099 //公历年最大值
- Solar2Lunar_Typedef Get_China_Calendar(unsigned int Year,unsigned char Month,unsigned char Day)
- {
- unsigned char Spring_Festival_Month; //当年春节所在的公历月份
- unsigned char Spring_Festival_Date; //当年春节所在的公历日
- unsigned char Leap_Month_Flag; //闰月,农历月不+1
- unsigned char Lunar_Month; //农历月
- unsigned char Lunar_Month_Temp; //农历月(尝试判断月份)
- unsigned char Lunar_Month_Save; //农历月保存(用于判断是不是闰月)
- unsigned char Lunar_Date; //农历日
- unsigned char Lunar_Leap_Month; //闰月
- unsigned char Lunar_Month_Days; //农历月天数
- unsigned char Spring_Festival_Days; //当年春年离当年元旦的天数
- unsigned int Days_After_New_Years_Day; //公历日离当年元旦的天数
- unsigned int Days_Differ; //两个日期天数差
- unsigned int Table_Offset; //农历特征数据表格查表偏移量
- Solar2Lunar_Typedef Return_Value; //返回值
- Return_Value.Month = 0; //月
- Return_Value.IS_Leap_Month = 0; //闰月标志
- Return_Value.Reserved_Bits = 0;
- Return_Value.Date = 0; //日
- if((Year >= C_SOLAR_YEAR_MIN) && (Year <= C_SOLAR_YEAR_MAX)) //1901~2099年之外不处理
- {
- Lunar_Month_Save=0; //农历月保存(用于判断是不是闰月)
-
- /* 定位数据表地址 */
- Table_Offset = (Year - 1900); //农历特征数据从1900年开始,但只能转换1901年之后的数据,转换春节前的数据需要前一年的数据
-
- /* 取当年春节所在的公历月份 */
- Spring_Festival_Month = Lunar_Year_Code[Table_Offset].Byte_2.Bits.Spring_Festival_Month;
-
- /* 取当年春节所在的公历日 */
- Spring_Festival_Date = Lunar_Year_Code[Table_Offset].Byte_2.Bits.Spring_Festival_Date;
-
- /* 计算当年春年离当年元旦的天数,春节只会在公历1月或2月 */
- if ( Spring_Festival_Month == 1 )
- {
- Spring_Festival_Days = Spring_Festival_Date - 1;
- }
- else
- {
- Spring_Festival_Days = Spring_Festival_Date + 31 - 1;
- }
-
- /* 计算公历日离当年元旦的天数 */
- Days_After_New_Years_Day = Days_Code[Month] + Day - 1;
-
- /* 如果公历月大于2月并且该年的2月为闰月,天数加1 */
- if (Month > 2)
- {
- if((Year % 100) == 0) //能被100整除
- {
- if((Year % 400) == 0) //能被400整除--闰年
- {
- Days_After_New_Years_Day ++;
- }
- }
- else if (Year % 4 == 0) //不能被100整除,能被4整除--闰年
- {
- Days_After_New_Years_Day ++;
- }
- }
-
- /* 判断公历日在春节前还是春节后 */
- if(Days_After_New_Years_Day >= Spring_Festival_Days) //当前公历日在春节后
- {
- Days_Differ = (Days_After_New_Years_Day - Spring_Festival_Days); //Days_Differ存放当前公历日距离当前春节公历日天数
-
- Lunar_Month = 1; //农历月
- Lunar_Month_Temp = 1; //农历月,从1月开始判断(第一个月不会是闰月,直接农历正月天数)
- Leap_Month_Flag = 0; //闰月,农历月不+1
-
- if(Get_Lunar_Month_Days(Lunar_Month_Temp, Table_Offset) == 0) //农历月天数
- {
- Lunar_Month_Days = 29; /* 小月29天 */
- }
- else
- {
- Lunar_Month_Days = 30; /* 大月30天 */
- }
-
- /* 从数据表中取该年的闰月月份,如为0则该年无闰月 */
- Lunar_Leap_Month = Lunar_Year_Code[Table_Offset].Byte_0.Bits.Leap_Month;
-
- while(Days_Differ >= Lunar_Month_Days) //天数差>=当前处理农历月天数
- {
- Days_Differ -= Lunar_Month_Days;
-
- if(Lunar_Month == Lunar_Leap_Month) //农历月=当年农历闰月
- {
- Leap_Month_Flag = (~Leap_Month_Flag); //闰月标志
-
- if (Leap_Month_Flag == 0)
- {
- Lunar_Month ++; //闰月之后的下一个月
- }
- else
- {
- Lunar_Month_Save = Lunar_Month; //农历月保存(用于判断是不是闰月)
- }
- }
- else
- {
- Lunar_Month ++; //下一个月
- }
-
- Lunar_Month_Temp ++;
-
- if(Get_Lunar_Month_Days(Lunar_Month_Temp, Table_Offset) == 0)
- {
- Lunar_Month_Days = 29;
- }
- else
- {
- Lunar_Month_Days = 30;
- }
- }
-
- Lunar_Date = (Days_Differ + 1); //农历日
- }
- else /* 公历日在春节前使用下面代码进行运算 */
- {
- Days_Differ = (Spring_Festival_Days - Days_After_New_Years_Day);
-
- Table_Offset -= 1; //未到当年春节,取前一年的农历特征表格
- Lunar_Month = 12; //从前一年农历十二月开始判断
-
- Lunar_Leap_Month = Lunar_Year_Code[Table_Offset].Byte_0.Bits.Leap_Month; //闰月月份
-
- if (Lunar_Leap_Month == 0) //当前年没有闰月
- {
- Lunar_Month_Temp = 12; //农历月,从12月开始判断
- }
- else
- {
- Lunar_Month_Temp = 13; //农历月,当前年有闰月,从13月开始判断
- }
-
- Leap_Month_Flag = 0; //闰月,农历月不-1
-
- if(Get_Lunar_Month_Days(Lunar_Month_Temp, Table_Offset) == 0) //农历月天数
- {
- Lunar_Month_Days = 29; /* 小月29天 */
- }
- else
- {
- Lunar_Month_Days = 30; /* 大月30天 */
- }
-
- while(Days_Differ > Lunar_Month_Days)
- {
- Days_Differ -= Lunar_Month_Days;
-
- Lunar_Month_Temp --;
-
- if(Leap_Month_Flag == 0)
- {
- Lunar_Month --;
- }
-
- if(Lunar_Month == Lunar_Leap_Month)
- {
- Leap_Month_Flag = (~Leap_Month_Flag);
-
- if(Leap_Month_Flag)
- {
- Lunar_Month_Save = Lunar_Month; //农历月保存(用于判断是不是闰月)
- }
- }
-
- if(Get_Lunar_Month_Days(Lunar_Month_Temp, Table_Offset) == 0)
- {
- Lunar_Month_Days = 29;
- }
- else
- {
- Lunar_Month_Days = 30;
- }
- }
-
- Lunar_Date = (Lunar_Month_Days - Days_Differ + 1); //农历日
- }
-
- if(Lunar_Month == Lunar_Month_Save) //当前月=闰月保存月份
- {
- Return_Value.IS_Leap_Month = 1; //闰月标志=1
- }
-
- Return_Value.Month = Lunar_Month; //保存转换农历月、日
- Return_Value.Date = Lunar_Date;
- }
- return Return_Value; //返回值
- }
复制代码
转换实例:
(1)定义一个结构体变量保存转换返回值
- Solar2Lunar_Typedef Lunar_Data; //公历转农历返回值
复制代码 (2)简单判断数据是否有效(待转换日期在预设范围内都会返回有效结果)。
- Lunar_Data=Get_China_Calendar(Year,Month,Date); //公历转农历
-
- if(Lunar_Data.Month != 0) //数据有效
- {
- Lunar_Calendar.Month = Lunar_Data.Month; //保存转换农历月、日
- Lunar_Calendar.Date= Lunar_Data.Date;
-
- Lunar_Calendar.IS_Leap_Month = Lunar_Data.IS_Leap_Month; //闰月标志
- }
复制代码
|
打赏
-
查看全部打赏
|