-- 作者:tgs28
-- 发布时间:2006/9/27 4:35:00
-- [原创]已知公历日期快速估算农历日期
已知公历日期快速估算农历日期 作者:谭笑风 为方便叙述,首先介绍两个函数 高斯函数:y=[x],[x]表示不超过数x的最大整数, 求余数函数:f(x)=xmodt,表示x除以t后所得的余数(即mod表示余数运算) 且被除数x=除数t*商+余数,所以有x=t*[x/t]+xmodt 实际中每个公历回归年比没有闰月的农历年多出约一个朔望月的7/19, 即多出29.5306*7/19≈11(天),即每年春节日期都要提前11天左右, 如遇到前一年有闰月,则春节会比前一年推迟19天左右, 这个规律可以用下式来解析,设公元y年的春节日期约为f(y) f(y)≡19y(mod30),这样y增加1,则f(y)增加19或减少11,不会超过30。 ≡是数论中表示同余的符号,mod30的意思是指在用30作模数(除数), 在19个回归年中加7个闰月后,公历和农历只差0.0892天(2个小时左右), 积累到200年左右才差一天,可见19这个周期非常精确, 即每隔19年的春节日期大致相同,可把年份除以19求余数来简化计算 即公元y年的春节日期约为f(y)≡19*ymod19≡19*(y-19*[y/19])(mod30)。 虽然实际上春节公历日期的范围是在1月21日和2月20日之间, 且一个朔望月是29.5306天,大月小月排列不固定, 但为了找出规律,不妨假设某年(平年)农历正月初一在公历1月1日, 再假设该年农历第一个月30天,第二个月29天,第三个月30天,…… 这样大小月依次间隔排开,平均每个月29.5天,跟29.5306相比近似程度还可以。 由假设知1月1日是正月初一,所以1月几号便是正月几号,31号为二月初一, 继续推知2月1日是二月初二,要算2月几号农历日期,需在公历日期上加1, 除以29之后求余数,所得数即为农历日期,余数为0是农历廿九日, 继续推知3月1日是初一,要算3月几号农历日期,需在公历日期上加0, 除以30之后求余数,所得数即为农历日期,余数为0是农历三十日, 依次下去,要算某月几号农历日期, 分别在日期上加1,2,3,4,5,7,7,9,9,在此称之为“月余数” 然后分别除以29,30,29,30,29,30,29,30,29之后求余数, 所得数即为农历日期。 此假设中按30,29间隔作除数,实际中大月小月排列不固定, 所以实际中每个月用29或30作模(除数)并不固定, 所以假设中按30,29间隔作模用到实际当中就会有误差, 毕竟都是有误差,为了计算方便,还是统一取30为模为好。 由此得到所假设的的这一年估算某日农历日期的方法: 把某月的日期按月分别加上0,1,0,1,2,3,4,5,7,7,9,9。 然后除以30,求得余数即为农历大致日期,余数为0是农历三十日。 这里m月的月余数f(m)可以近似用下面的解析式来表达: f(m)≈(m-3+|m-3|)/2+[m/9],|x|和[x]分别表示绝对值和取整。 先设公历日期为d,农历大致日期为f(y,m,d),容易得出, 如果春节在1月份(月余数为0) f(y,m,d)≡月余数-春节日期+公历日期+1≡f(m)-f(y)+d+1(mod30) 如果春节在2月份(月余数为1) f(y,m,d)≡月余数-春节日期+公历日期≡f(m)-f(y)+d(mod30) 可见,春节在1月份比在2月份估算农历日期时多加了一个1, 实际的情况是有2/3的年份春节在2月份,1/3的年份春节在1月份, 为了使形式简洁便于计算并照顾大多数情况(况且一直是估算),统一取 f(y,m,d)≡f(m)-f(y)+d(mod30),同时也不必考虑闰年多出的一天。 最终结论: 设f(y,m,d)是公元y元m月d日的农历大致日期,f(y,m,d)=0时日期为三十日左右 f(y,m,d)≡f(m)-f(y)+d(mod30) f(y,m,d)≡f(m)-19*ymod19+d(mod30) f(y,m,d)≡11*ymod19+f(m)+d(mod30) f(y,m,d)≈11*(y-19*[y/19])+(m-3+|m-3|)/2+[m/9]+d(mod30) (从另一种角度去考虑,一般公历每年比农历每年多出11天, 所以在f(m)+d的基础上要加上余数乘以年数的积11*ymod19。) 最终算出的结果与实际日期相差一般都不超过一天,农历月份一般为公历月份减去一。 把以上结论说得通俗一点就是: 估算公元某年某月某日的农历日期,先把把公历年份y除以19后求得余数, 把这个余数乘以11后用30除求得余数称之为“年余数”; 再把每个月对应的一个数字,这个数字称之为“月余数”, 1至12月份所对应的数字分别是0,1,0,1,2,3,4,5,7,7,9,9; 最后把所求这一日的“日期数”加上月份对应的“月余数”再加上“年余数”, 求得这三个数字的和,用30除求余数,所得余数便是这一天农历的大致日期, 余数为0时则是农历三十左右。 举个例子,估算1949年10月1日的农历日期,年份1949除以19余数为11, 余数11乘以11得121,用30除得年余数为1;10月对应的“月余数”为7; “日期数”+“月余数”+“年余数”=1+7+1=9,除以30之后所得余数为6, 所以1949年10月1日大概是农历初九左右。 算起来很简单吧?查历书知1949年10月1日实际是初十,和算的结果相比就差一天, 查历书知再隔38年的1987年10月1日就是初九,看来这方法还是管点用的!
|