姓名测试 | 心理测试 | 公司名测算 | 车牌号码吉凶 | 周公解梦 | 星座查询 | 手机号码吉凶 | 免费起名 | 姓名配对 | 个性签名 |
更 多▼
网站导航
当前位置:1518首页 - 万年历

公农历转换原理及万年历写法

今天突然想知道我这辈子能不能再经历一次我生日的公里农历重合,也就是公历九月二十五与农历九月初一在同一天。。

刚巧公司有一份比较简单的公农历转换的源码,再加上最近想了解一下Windows下编程,所以就自己写了一个小程序,用来转换公农历,并计算下一次重合是在哪一年。。。

划地为牢的工具盒子.rar

由于公农历转换接口的限制,使程序只能计算到2020年。。。

之后我去网上查了原因,并希望找到公农历转换的公式。结果如下: 

=============================================================

首先,众所周知,公历和农历是跟天文周期息息相关,并以此为计算依据的。如果仅仅是依据天文周期就可以推算出公历和农历各自的计算方法或者说公式的话,那么公历与农历的转换根本就不成问题,因为两个存在关联的既定公式肯定可以汇总结合出另外一个公式。程序员们历来擅长此道。

不过很可惜,公农历的规律不单单与天文周期有关,还有一些其他因素的干预,例如罗马皇帝就曾几次修改2、8等月份长短。另外随着科技的发展,天文数据也会不断更新,例如现在测得的地球公转时间就与公元前测得的地球公转时间不同,起码精度上相差许多。

结论是:试图用一个简单的公式,而不利用许多像万年历一样的数据(尽管可以简化),就达到公农历转换的目的,这是不可能的。

=============================================================

现在网上存在很多类似万年历的程序,无论是程序形式还是网页形式,无一例外全部都是采用对照表的方式。

什么是对照表?

首先要保存公历农历之间的转换信息:以任意一年作为起点,把从这一年起若干年(若干是多少?就看你的需要了)的农历信息保存起来。至于这些数据的格式,那就看你的能力了,当然是越精简越精确的越好,具体算法后面详述。

例如我的代码中,就是先保存“1921年2月8日 正月初一 星期二:”作为一个基本观测点,然后据此再保存一堆相关数据,例如每个月的天数等公历数据,天干地支等农历数据。

最后公农历转换的时候,是根据输入的日期,去比对基本观测点和相关数据,得到对应的农历日期。

由于代码中的对照表(也就是我保存的农历信息)有限,所以只能计算到2020年。



关于公农历转换算法比较详细的文字说明,有兴趣的可以看看:

要保存一年的信息,其实只要两个信息就可以了:

1.农历每个月的大小;2.今年是否有闰月,闰几月以及闰月的大小。

用一个整数来保存这些信息就足够了。

具体的方法是:用一位来表示一个月的大小,大月记为1,小月记为0,这样就用掉12 位(无闰月)或13 位(有闰月),再用高4位来表示闰月的月份,没有闰月记为0。比如说,2000年是110010010110B,表示的含义是指1、2、5、8、10、11月大,其余月小。2001 年的农历信息数据是0x41A95=1101010010101B,其中4表示今年闰4月,月份大小信息就是0x1A95(因为闰月,所以有13 位),具体的就是1、2、4、5、8、10、12月大,其余月份小,4月的后面那一个0表示的是闰4月小,接着的那个1表示5月大。

这样就可以用一个数组来保存这些信息。

公历转换成农历的具体算法:

1.计算出所求时间到起始年正月初一的天数。

2.从起始年份开始,减去每一月的天数,一直到剩余天数没有下一个月多为止。

此时,数组的下标到了多少,就是减去了多少年,用起始年份加上这个下标就可以得到农历年份,然后看减去了几个月。如果本年不闰月或者闰月还在后面,就可以直接得到农历月份,如果在闰月月份数后面一个月,则这个月就是闰月,如果在闰月的后面,则要减去1 才能得到月份数。剩余的天数就是农历日,农历时用(公历时+1)/2 就可以简单地得到了。
关于1518  |  联系我们  |  占卜大师  |  相关资料
Copryright © 2009 1518.com. All rights reserved.