以文本方式查看主题 - 中华农历论坛 (http://bbs.nongli.net/index.asp) -- 历法知识 (http://bbs.nongli.net/list.asp?boardid=2) ---- 试编查表法年历/日期计算器农历数据结构 (http://bbs.nongli.net/dispbbs.asp?boardid=2&id=47670) |
-- 作者:txwdx -- 发布时间:2011/8/13 19:02:00 -- 试编查表法年历/日期计算器农历数据结构 一、日期表示法 1、数字符号法 a.公历、回历 第1位:历种。G公历、H回历 第2位:纪元前后。纪元前无标识,纪元后在年份前加\',比如G\'0001年,公元前1年。 第3-6位:年序号。 第7位:“/”,分隔符 第8-9位:月序号,公历、回历1-12 第10位:“/”分隔符 第11-12位:日序号 例如:G2011/8/28、H1432/9/28 农历主体历 第1位:历种。X:黄帝纪元,黄帝元年为0年。 第2-5位:年序号。 第6位:“/”,分隔符 第7-9位:月标识,前两位为流水号,闰月则有第三位\',比如04\'闰4月。 第10位:“/”分隔符 第11-12位:日序号 例如:X4708/7/27 农历干支历 第1位,0-F,纪顺序号(60年为1世,60世为1纪,24纪为1元)。公元前2697年立春,视作是辰正(第8纪)。 第2位,“:”分隔符 第3-4位,世序号,甲子为00,公元前2697年立春,视作是第8纪甲子(第0世) 第5位,“:”分隔符 第6-7位,年序号,甲子为00,公元前2697年立春,视作是第8纪第0世甲子年(第0年) 第8位,“/”分隔符 第9-10位,以24节气为始日,将1年分为24个节气月,1节气月14-16日;冬至为子正,立春为寅初。第9-10位为小月号,立春为0,冬至为21,大寒为23 第11位,“/”分隔符 第12-13位,日序号,节气当日为0。 例如:9:18:27/13/05。巳初纪壬午世甲子年申正小月第五日(处暑后第五日) 二、日期运算符。 “-”:求两个日期之间的天数,结果为日。 比如:G2011/08/29-X4708/08/15=-14。公历2011年8月29比农历4708年8月15早14日。 “>>”、“<<”:后移、前移,一个日期向后、向前推移若干年月日。 比如:G2011/08/29>>25=G2011/09/23;G2011/08/29>>1/25=G2011/10/24;G2011/01/28>>1/1/25=G2012/3/24 <、=、>:日期前后(以箭头指向为准)。G2011/08/29>X4708/08/15=True “@”:系统当前日期。 “->G”,转公历 “->X”,转农历 “->H”,转回历 ,“->N”转节气历 “->R”,求日干支 “->W”求星期 “?”:日期正确与否。比如:G2011/02/29?=False 三、农历常数的数据结构。 以60年为1个包(年世表),使用64个16字节数据表示。 第1-60个16字节为年表。 第61个16字节为公对农换算数据 第62个16字节为回对农换算数据 第63个16字节为儒略日对农换算数据 第64个16字节为世表 年表结构为: 第1-16位为年序号。 第17-28位为当年起始月在本世内的流水号。从1始。(方便对回换算) 第19-32位为闰月序号。无闰为0 第33-48位为当年起始日在本世内的流水号。从1始。(方便对公跨年换算) 第49-52位为始日天干,0:甲、9:癸。 第53-56位为始日地支,0:子,B:亥。 第56-60位为始日星期,0:日,6:六/土 第61位为立春所在月。立春在正月,为1;立春若在年前,前面补一个30天的0月 第62-75位,为大小月标记,0为大月30天,1为小月29天。 第76-80位,立春日期 第81-128位,各节气月的长短,每个节气月2位,11为14天、00为15天、01为16天 比如:2012年的年表为 949C 15B 4 27EA 971 A954A 34 05 14 50 00 30 第61个16字节换算表结构为 第1-16位,序号。 第17-28位,年号。 第19-32位,0 第33-48位,始日流水号。(为方便计算,以2月的日期均+2,以1/30日为首日。) 第49-52位为始日天干,0:甲、9:癸。 第53-56位为始日地支,0:子,B:亥。 第56-60位为始日星期,0:日,6:六/土 第69-128位,年大小标记。大年366天,为1,小年365天,为0,大多是0x1 1111 1111 1111。 本世的换算表为94 9C 15 B4 27 EA 97 12 55 4D 34 05 14 50 00 30 第62个16字节换算表结构为 第1-16位,序号。 第17-28位,年号。 第19-32位,立春所在月月号。 第33-48位,始日流水号。(为方便计算,以最靠近农历的那个月的月号为准,多为2或3) 第49-52位为始日天干,0:甲、9:癸。 第53-56位为始日地支,0:子,B:亥。 第56-60位为始日星期,0:日,6:六/土 第66-128位,年大小标记。小年354天,为1,大年355天,为0。 本世的换算表为94 BD 57 C5 00 02 33 50 2D AD B5 B6 B6 B6 D6 DA 第63个16字节换算表结构为 第1-16位,序号。 第81-128位,首日儒略日号 本世的换算表为94 BE 00 00 00 00 00 00 00 00 00 00 00 25 51 A5 第64个16字节世表结构为 第1-16位为序号。 第17-28位为最后一个月的流水号。从1始。(方便对跨世换算) 第19-32位为0 第33-48位为最后一日的流水号。从1始。(方便对公跨世换算) 第49-52位为末日天干,0:甲、9:癸。 第53-56位为末日地支,0:子,B:亥。 第56-60位为末日星期,0:日,6:六/土 第69-128位,年平闰标记(便于对回换算) 本世世表为94 BF 2E 60 55 98 00 00 04 92 92 92 52 52 4A 49 [此贴子已经被作者于2011-8-30 8:26:56编辑过]
|
-- 作者:txwdx -- 发布时间:2011/8/14 16:58:00 -- 农公转换:X4708/8/15=G? 1、农历年份转换为干支纪年。4708减1,然后对60(0011 1100)求余,得年数27。4708减去28,除以60,然后对60求余,得世数18。除以3600后的整数部分,再加上8,得记数9 2、mod(27,6)=3,3*5=15 3、取换算表,大小年序列为0x111 1111 1111 1111,后27位累加为7 3、15+7=22。 4、取换算表,首日为8002,即-2,22+(-2)=20。 5、取年表,首日为0x2688(9864),mod(9864,30)=24。 6、24-20=4。 7、取年表,大小月序列为,0010 1011 0100 10 8、查8月15,取年表,闰月为0,无闰月,大小月序列后7位累加为3。 9、公历大小月序列,为0011 0101 1010 10,查换算表,从右至左第28位,为0。0和公历大小月序列末位异或,依然为0011 0101 1010 10,后7位累加,为4。 10、5-3-4=-3,15+(-3)=12。 11、取换算表年号为1984,1984+27=2011。 12、X4708/8/15=G2011/9/12 [此贴子已经被作者于2011-8-29 19:54:00编辑过] |
-- 作者:txwdx -- 发布时间:2011/8/14 17:25:00 -- 日期运算 公农转换,G2011/10/1=X?。 一、查预置常数,得2011年属于1984-2043世数据包。 二、取转换表,得首年为1984年,2011-1984=27。 三、取转换表,大小年序列为,0x111 1111 1111,后27位累加为7。 四、mod(27,6)=3,3*5=15,15+7=22。 五、取转换表,得首日为8002,为-2,22+(-2)=20。 六、公历年表为 110101101010,转换表第28位为0,末位与0异或,仍为1101 0110 1010。 七、后八位(公历年表,从2月开始。10月前有8个月)累加,得4。20+4=24。 八、取9:18:27年年表,首日为0x2688(9864),对30求余,为24。24-24=0。 九、取9:18:27年年表,大小月序列为,0010 1011 0100 10。后八位累加为4。,1+4=5 十、G2011/10/1=X4708/9/5 [此贴子已经被作者于2011-8-29 19:13:29编辑过] |
-- 作者:txwdx -- 发布时间:2011/8/14 17:51:00 -- 应用二, 农回转换 X4708/8/15=H? 转干支纪年,X4708=9:18:27, 查年表,首月为335月 查转换表,首月为H1404/5。1404/5后移335-1个月为1432/3。即X4908/1=1432/1 334/2=167。若将12月视为小月的话,这334月,比334*30,少167天。 1404年至1432年,经历1432-14-4=28个年尾。将转换表后28位叠加,得17。有28-17=11个闰月,167-11=156。实际少156天 查年表,首日为9864,(9864-1)-334*30=155 156-155=1,H1432/3的首日在X4708/1的日期,比H1404/5首日在本世首月里的日期多1天 查转换表,H1404/5/1=X4681/1/2。则H1432/3/1=X4708/1/3。 查年表,月序列001001 0110101后7位累加,为4。X4708/8/1-X4708/1/1=7*60-4 回历年表为 010 1010101 01,后3-9位累加,为4。H1432/10/1-H1432/3/1=7*60-4 4-4=0,也就是说H1432/10/1在X4708/10的日期和H1432/3/1在X4708/1的日期一样,为3 15-3=?-1. ?=13 即: X4908/8/15=H1432/10/13。 [此贴子已经被作者于2011-8-29 19:48:00编辑过] |
-- 作者:客人 -- 发布时间:2011/8/15 21:37:00 -- 回历年尺 从低位至高位 32位,置零。 31位,置两年的标记。伊斯兰历每32.5年和公历年相差一年。此年年尺,放二年(视作闰一年)。可将月差控制在12个月以内,回农互转的时候,也就只需要调2年尺。每轮农历正月和伊斯兰历一月第一次大致重合的那一年(比如公元2005、2037年)置1, 27-30位,月差,伊斯兰历一月和阴历正月的月差。 25-26位,为0 1-24位,月数据,每月2位,从2月至1月,高位为0,低位为大小月标记(2月的日期加2。)。大月为1,小月为0。闰一年时,高位放后一年,低位放前一年。 伊斯兰历农历对照时,低位月对上一年,高位月对当年。 伊斯兰历大致有六种(调斋除外)。 0 0**** 00 0000 0100 0100 0100 0100 0100 0 0**** 00 0100 0100 0100 0100 0100 0100 0 1**** 00 0000 1100 1100 1100 1100 1100 0 1**** 00 0000 0000 1100 1100 1100 1100 0 1**** 00 0000 1000 1100 1100 1100 1100 0 1**** 00 0000 0100 1100 1100 1100 1100 |
-- 作者:txwdx -- 发布时间:2011/8/15 21:48:00 -- 应用三 回农转换。 H1432/10/1=X? 查常数,H1432/10/1在农历4681-4740之间。 取94BD转换。 得首年为1404,首月为5。 从H1403/10为第(1432-1404)*12+10-4=342个月。 取94BF世表年序列,4 92 92 92 52 52 4A 49。从右至左,逐位检索,逢1加13,否则加12。直至大于342为止。 int y=0,m=1;long long yearsequence=0x492929252524A49; for(i=0;i<61;i++){if(m>342)break; m+=12;m+=yearsequence & 1;y+=1;yearsequence>>1;} y-=1;m-=12;m=341-m; 算的y=27,m=8 (342-1)/2=170.5,5月、9月均为大月,舍去,为170; 取换算表年序列 2D AD B5 B6 B6 B6 D6 DA,后1432-1404=28位累加为17,28-17=11。170-11=159。 取第27年年表,得首月为335。首日为9864。9864-1-(335-1)*30=-157。 取年序列,后7位累加,为3。157+3=160。 160-159=1,查转换表,首日为2。2+1=3. 4681+25=4708. H1432/10/1=X4708/8/3 [此贴子已经被作者于2011-8-29 20:43:43编辑过]
|
-- 作者:txwdx -- 发布时间:2011/8/29 21:16:00 -- 应用4。某农历某日为节气后的第几天。 比如:X4709/1/1=9:18:2?/?/? 4709转换为干支纪年为9:18:28. 取28号年表,得立春月为1,立春日为13。 取27号年表,得大寒节气月数据为00,15天,15-13=2。 X2709/1/1=9:18:27/23/2。大寒后第二天。 比如:X4708/8/15=9:18:27/?/? 取27号年表,月序列,后7位累加为4。 取27号年表立春月为1,立春日为2。4+(2-1)=5 取27号年表,节气序列,前28位,每2位为1单元,11为-1,01为1,7单元叠加,为6。 6+5=11。9:18:27/14/0(白露)=X4708/8/11 15-11=4。 x4708/8/15=9:18:27/14/04。 |