阳历到阴历的转换

    技术2022-05-11  105

    在上见到不少有人问关于阴历的问题,我查了一下,文档中心还没有相关的文章,碰巧手头有一份资料,哪来的忘了,现在将全文贴出来,希望对大家有帮助。 - 90.电脑语言, C (90:90/1237) ------------------------------------------- 90-C - Msg  : #404 [407]                                                              From : Sunshine Lin                        90:2010/633    Thu 29 Aug 96 22:05 To  : Steven Shui                                        Sun 01 Sep 96 05:03 Subj : 国历转农历                                                              -------------------------------------------------------------------------------- .MSGID: 90:2010/633.0 32264c56 .PID: BWRA 3.02 [Eval] .TID: GE 1.11+ 回复如下... SS> 请问有谁知道 "国历转农历" 的演算法? SS> 望知道的前辈不佞赐教.     农历的演算法相当复杂, 多半都是由查表方式完成,     以下程式是在 Internet 找到的。     另外我还找到另一支程式是大陆人写的, 可以反堆,     还可算八字。有兴趣的话写信给我, 我再 post 出来好了!! -------------------------------------------------------------------- 发信人: smhwang@phoenix (全自动之狼), 信区: programming 标  题: --- 西历与农历转换函式 --- 发信站: 交大资工凤凰城资讯站 (Wed Jul 26 01:51:17 1995) 转信站: phoenix Origin: kscg-ts5.kscg.gov.tw 本函式欢迎各站各版转载, 无须经本人同意. 若对历法有兴趣, 欢迎讨论. /*   西历农历转换程式    黄晓鸣  1995,7,25   prototype:  int CalConv( struct ConvDate * );   struct ConvDate   {     int Source;      ==0 则输入日期为西历, !=0 则输入为农历     int SolarYear;    输出或输入之西历年份     int SolarMonth;  西历月     int SolarDate;    西历日     int LunarYear;    输出或输入之农历年份     int LunarMonth;  农历月     int LunarDate;    农历日     int Weekday;      该日为星期几 ( 0==星期日, 1==星期一, ... )     int Kan;          该日天干    ( 0==甲, 1==乙, ..., 9==癸 )     int Chih;        该日地支    ( 0==子, 1==丑, ..., 11==亥 )   };   呼叫时须设定 Souce 的值, 若为 0 则为西历转农历, 否则为农历转西历. 然後视   输入为西历或农历来设定西历或农历的年月日. 转换後的年月日会填入结构中( 农   历或西历 ), 以及该日为星期几, 天干地支.   若函式的返回值为 0 表示没有错误, 1 为输入之年份错误, 2 为输入之月份错误,   3 为输入之日期错误.   输入之西历年须在 1937 - 2031 间   输入之农历年须在 1936 - 2030 间   若须扩充, 则增加 LunarCal[] */ #define FIRSTYEAR 1936  /* The first year in LunarCal[] */ struct ConvDate {   int Source;   int SolarYear;   int SolarMonth;   int SolarDate;   int LunarYear;   int LunarMonth;   int LunarDate;   int Weekday;   int Kan;   int Chih; }; struct tagLunarCal {   int BaseDays;        /* 到西历 1 月 1 日到农历正月初一的累积日数 */   int Intercalation;    /* 闰月月份. 0==此年没有闰月 */   int BaseWeekday;      /* 此年西历 1 月 1 日为星期几再减 1 */   int BaseKanChih;      /* 此年西历 1 月 1 日之干支序号减 1 */   int MonthDays[13];    /* 此农历年每月之大小, 0==小月(29日), 1==大月(30日) */ }; struct tagLunarCal LunarCal[] = { { 23,  3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 },  /* 1936 */ { 41,  0, 4, 23, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 }, { 30,  7, 5, 28, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 }, { 49,  0, 6, 33, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 38,  0, 0, 38, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },  /* 1940 */ { 26,  6, 2, 44, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 45,  0, 3, 49, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 35,  0, 4, 54, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 24,  4, 5, 59, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },  /* 1944 */ { 43,  0, 0,  5, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 }, { 32,  0, 1, 10, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 }, { 21,  2, 2, 15, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 40,  0, 3, 20, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 },  /* 1948 */ { 28,  7, 5, 26, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 47,  0, 6, 31, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 }, { 36,  0, 0, 36, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 26,  5, 1, 41, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },  /* 1952 */ { 44,  0, 3, 47, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 }, { 33,  0, 4, 52, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, { 23,  3, 5, 57, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, { 42,  0, 6,  2, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },  /* 1956 */ { 30,  8, 1,  8, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 48,  0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 38,  0, 3, 18, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, { 27,  6, 4, 23, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 },  /* 1960 */ { 45,  0, 6, 29, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 }, { 35,  0, 0, 34, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, { 24,  4, 1, 39, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, { 43,  0, 2, 44, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 },  /* 1964 */ { 32,  0, 4, 50, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 }, { 20,  3, 5, 55, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, { 39,  0, 6,  0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 29,  7, 0,  5, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 },  /* 1968 */ { 47,  0, 2, 11, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 36,  0, 3, 16, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 }, { 26,  5, 4, 21, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 }, { 45,  0, 5, 26, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 },  /* 1972 */ { 33,  0, 0, 32, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 }, { 22,  4, 1, 37, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 }, { 41,  0, 2, 42, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 }, { 30,  8, 3, 47, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 },  /* 1976 */ { 48,  0, 5, 53, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 }, { 37,  0, 6, 58, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 27,  6, 0,  3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 }, { 46,  0, 1,  8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 },  /* 1980 */ { 35,  0, 3, 14, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, { 24,  4, 4, 19, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 }, { 43,  0, 5, 24, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 }, { 32, 10, 6, 29, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 },  /* 1984 */ { 50,  0, 1, 35, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 39,  0, 2, 40, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1 }, { 28,  6, 3, 45, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 }, { 47,  0, 4, 50, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },  /* 1988 */ { 36,  0, 6, 56, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, { 26,  5, 0,  1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 }, { 45,  0, 1,  6, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0 }, { 34,  0, 2, 11, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 },  /* 1992 */ { 22,  3, 4, 17, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 40,  0, 5, 22, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 30,  8, 6, 27, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 }, { 49,  0, 0, 32, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1 },  /* 1996 */ { 37,  0, 2, 38, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, { 27,  5, 3, 43, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 }, { 46,  0, 4, 48, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 }, { 35,  0, 5, 53, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 },  /* 2000 */ { 23,  4, 0, 59, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 42,  0, 1,  4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 31,  0, 2,  9, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 21,  2, 3, 14, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 },  /* 2004 */ { 39,  0, 5, 20, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 28,  7, 6, 25, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, { 48,  0, 0, 30, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 }, { 37,  0, 1, 35, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 },  /* 2008 */ { 25,  5, 3, 41, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 44,  0, 4, 46, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 33,  0, 5, 51, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 22,  4, 6, 56, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 },  /* 2012 */ { 40,  0, 1,  2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 30,  9, 2,  7, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, { 49,  0, 3, 12, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 }, { 38,  0, 4, 17, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },  /* 2016 */ { 27,  6, 6, 23, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, { 46,  0, 0, 28, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 }, { 35,  0, 1, 33, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, { 24,  4, 2, 38, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },  /* 2020 */ { 42,  0, 4, 44, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, { 31,  0, 5, 49, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, { 21,  2, 6, 54, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, { 40,  0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 },  /* 2024 */ { 28,  6, 2,  5, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, { 47,  0, 3, 10, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 }, { 36,  0, 4, 15, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 }, { 25,  5, 5, 20, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 },  /* 2028 */ { 43,  0, 0, 26, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, { 32,  0, 1, 31, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0 }, { 22,  3, 2, 36, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 } }; #define LASTYEAR (FIRSTYEAR+sizeof(LunarCal)/sizeof(struct tagLunarCal)-1) /* 西历年每月之日数 */ int SolarCal[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /* 西历年每月之累积日数, 平年与闰年 */ int SolarDays[2][14] = { { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 }, { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 397 } }; /* 求此西历年是否为闰年, 返回 0 为平年, 1 为闰年 */ int GetLeap( int year ) {   if ( year % 400 == 0 )     return 1;   else if ( year % 100 == 0 )     return 0;   else if ( year % 4 == 0 )     return 1;   else     return 0; } /* 西历农历转换 */ int CalConv( struct ConvDate *cd ) {   int leap, d, sm, y, im, l1, l2, acc, i, lm, kc;   if ( cd->Source == 0 )  /* Solar */   {     if ( cd->SolarYear <= FIRSTYEAR ¦¦ cd->SolarYear > LASTYEAR )       return 1;     sm = cd->SolarMonth - 1;     if ( sm < 0 ¦¦ sm > 11 )       return 2;     leap = GetLeap( cd->SolarYear );     if ( sm == 1 )       d = leap + 28;     else       d = SolarCal[sm];     if ( cd->SolarDate < 1 ¦¦ cd->SolarDate > d )       return 3;     y = cd->SolarYear - FIRSTYEAR;     acc = SolarDays[leap][sm] + cd->SolarDate;     cd->Weekday = ( acc + LunarCal[y].BaseWeekday ) % 7;     kc = acc + LunarCal[y].BaseKanChih;     cd->Kan = kc % 10;     cd->Chih = kc % 12;     if ( acc <= LunarCal[y].BaseDays )     {       y--;       cd->LunarYear = cd->SolarYear - 1;       leap = GetLeap( cd->LunarYear );       sm += 12;       acc = SolarDays[leap][sm] + cd->SolarDate;     }     else       cd->LunarYear = cd->SolarYear;     l1 = LunarCal[y].BaseDays;     for ( i=0; i<13; i++ )     {       l2 = l1 + LunarCal[y].MonthDays[i] + 29;       if ( acc <= l2 )         break;       l1 = l2;     }     cd->LunarMonth = i + 1;     cd->LunarDate = acc - l1;     im = LunarCal[y].Intercalation;     if ( im != 0 && cd->LunarMonth > im )     {       cd->LunarMonth--;       if ( cd->LunarMonth == im )         cd->LunarMonth = -im;     }     if ( cd->LunarMonth > 12 )       cd->LunarMonth -= 12;   }   else  /* Lunar */   {     if ( cd->LunarYear < FIRSTYEAR ¦¦ cd->LunarYear >= LASTYEAR )       return 1;     y = cd->LunarYear - FIRSTYEAR;     im = LunarCal[y].Intercalation;     lm = cd->LunarMonth;     if ( lm < 0 )     {       if ( lm != -im )         return 2;     }     else if ( lm < 1 ¦¦ lm > 12 )       return 2;     if ( im != 0 )     {       if ( lm > im )         lm++;       else if ( lm == -im )         lm = im + 1;     }     lm--;     if ( cd->LunarDate > LunarCal[y].MonthDays[lm] + 29 )       return 3;     acc = LunarCal[y].BaseDays;     for ( i=0; i<lm; i++ )       acc += LunarCal[y].MonthDays[i] + 29;     acc += cd->LunarDate;     leap = GetLeap( cd->LunarYear );     for ( i=13; i>=0; i-- )       if ( acc > SolarDays[leap][i] )         break;     cd->SolarDate = acc - SolarDays[leap][i];     if ( i <= 11 )     {       cd->SolarYear = cd->LunarYear;       cd->SolarMonth = i + 1;     }     else     {       cd->SolarYear = cd->LunarYear + 1;       cd->SolarMonth = i - 11;     }     leap = GetLeap( cd->SolarYear );     y = cd->SolarYear - FIRSTYEAR;     acc = SolarDays[leap][cd->SolarMonth-1] + cd->SolarDate;     cd->Weekday = ( acc + LunarCal[y].BaseWeekday ) % 7;     kc = acc + LunarCal[y].BaseKanChih;     cd->Kan = kc % 10;     cd->Chih = kc % 12;   }   return 0; }

    最新回复(0)