从百度上面考下来的一个农历日起算法。。。。。。。。
Python实现150年公历农历换算
烤鱼片
cleverysm@gmail.com
前段时间玩twitter,跟风做了一个自动报时的机器人。一来练习python,而来玩玩gae,看看twitter的api是什么样子的。单是报公历太普通不好玩,于是想来做个报农历时间的,于是研究了一下农历的换算问题,并用python做了个小程序实现从1901年到2050年的换算。
要实现这个功能首先是要搞明白农历历法的规律。以前没查过这方面材料,以为是有什么公式可以直接从公历时间换算一下就可以,其实不然,中国农历的推算那可是相当复杂的,精确计算是得用上天体力学的。
首先要纠正一个不准确的说法,就是阴历。我们用的农历历法民间也俗称阴历,对应公元纪年的叫做阳历。顾名思义,阳历就是根据太阳与地球的相对运动关系计算的立法,阴历则是根据月亮周期计算的。乍看我们的农历好似是阴历,一个月恰是一个月亮的周期,但实际上农历还要根据太阳周期对一年的日期进行矫正,否则要是简单按照月亮周期计算的话一年就不是365天,会跟阳历有固定的误差,时间久了误差就会越来越大。为了避免这种误差,保证阴历一年和阳历一年基本对应,就引入了矫正机制,也就是闰月。而24节气虽是农历节气,但其时间则是根据地球相对太阳公转的相对位置确定的,而不是固定在某个阴历日期。因此我们所说的阴历其实应该算是一种阴阳混合历,真正典型的阴历代表则是伊斯兰历。
农历的计算就要涉及到每年是否闰月,闰几月,每个月有多少天,也就是大小月问题,二十四节气日期的确定这几个关键数据,这些都要用到太阳月亮地球三者之间的运行状况的计算,非专业人士很难搞的明白,而作为一般应用,也只有一种比较好的办法,那就是查表,找到一些关键时间数据存下来,计算的时候根据这些数据进行计算。
那么,公历到农历的转化需要最终得到哪些信息呢?首先第一个是农历的年份,也就是每年哪一天是大年初一,这个日子的确定取决于每年的闰月情况和各个月的大小月分布;然后是农历的月份和日期,也就是要算出今天是农历的几月几号;所计算日期是否属于24节气,是哪个节气;以及年干支、月干支、日干支乃至某时刻的干支是什么都要算出来。
我们先从简单的开始算起。
1.时刻干支
时刻干支简单的将就是在古装剧上常听到“子时”“午时”来表示一天的时刻,12个地支一天,也就是一个地支是两个小时,子时就是从23点到第二天的1点间俩小时,其他的类推下去。如果再精确点还可以在地支前加一个天干,也就是每个时刻可以表示成“甲子”“乙丑”这样的。地支时刻很简单,就是一天对应12个,直接对应就行。天干是10个,和地支组合起来则是60一循环,不能跟一天的12个时辰直接对应,所以就要取一个基准时刻,知道那个时刻的天干地支就可以根据60一循环的规律进行推算了。在这里我以1901年的1月1日凌成1点为基准点,此刻是乙丑时的开始,函数只做了向后计算,向前推算也很简单,稍改一下就可以。这里为最终返回干支结果,定义了几个常量,对应干支的汉字。
TIAN_GAN=("甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸")
DI_ZHI=("子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥")
HOUR_GANZHI={0:"子时", 1:"丑时", 2:"丑时", 3:"寅时", 4:"寅时", 5:"卯时", 6:"卯时", 7:"辰时", 8:"辰时", 9:"巳时", 10:"巳时", 11:"午时"\
, 12:"午时", 13:"未时", 14:"未时", 15:"申时", 16:"申时", 1