阳历转阴历算法
概述
毕设要做万年历,但是对阴阳历了解不多,在此总结。
阳历
阳历,就是“太阳历”,是依据太阳的变化(严格来说,应该是地球围绕太阳运动时,人在地球上所观测到的太阳的变化)来修订的历法,以地球绕太阳一圈的时间为一年。
小时候老师教过:“一三五七八十腊,三十一天永不差”。
阳历有很强的规律性,每年12个月,1、3、5、7、8、10、12月都为31天,2月份平年28天,闰年29天,其余月份为30天。是否闰年也好算,能被100整除的年份中能被400整除的是闰年,不能被100整除的年份中能被4整除的是闰年。
阴历
简介
阴历,也就是“月亮历”,是依据月亮的变化来修订的历法。月亮每经历一次从圆到缺的循环,就是一个月。我国古人常把月亮叫做“太阴”,所以也叫“阴历”。
阴历全年12个月的总天数是354.3672天,它同季节变化的周期——阳历1年365.2422天)相差约11天。阴历分大小月:大月30天、小月29天。由于这样算与阳历有差别,会不能正确反映季节,我国就创造了一种带有一定阳历成分的阴历———“阴阳合历”,也就是农历,又叫夏历(夏朝开始的)。
阴历同阳历一年相差11天。因此,农历每3年需要闰(增加)1个月,5年闰2个月,7年闰3个月,19年闰7个月,周而复始,有闰月的那一年就被称为闰年。这种设置闰月的方法叫“19年7闰法”。
因此,阴历平年12个月,闰年13个月。
算法
这根本就没规律嘛!!
所以我们要从观测阴历的天文台处得到阴历数据,网上大多是1900年到2100年的数据(根本不是万年历啊摔(/゚Д゚)/)。那么我们先从数据入手。
数据
网上搜集:
1 | 0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909 |
解析
十六进制的数据要转成二进制解析
二进制形式
xxxx | xxxx | xxxx | xxxx | xxxx |
---|---|---|---|---|
20-17 | 16-13 | 12-9 | 8-5 | 4-1 |
1-4: 表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。
5-16:为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。
注意:从1月到12月对应的是第16位到第5位。
17-20: 表示闰月是大月还是小月,仅当存在闰月的情况下有意义。
例子1
1980年的数据是(十六进制):0x095b0
二进制:0000 1001 0101 1011 0000
0000 | 1001 | 0101 | 1011 | 0000 |
---|---|---|---|---|
20-17 | 16-13 | 12-9 | 8-5 | 4-1 |
无意义 | 1-4月 | 5-8月 | 9-12月 | 非闰年 |
最右边的0000表示1980年没有闰月,所以最左边的0000也没有意义。从1月到12月的天数依次为:30、29、29、30、29、30、29、30、30、29、30、30,共12个月。分别对应16-5位的二进制数,1对30,0对29。
例子2
2017年的数据是:0x15176
二进制:0001 0101 0001 0111 0110
0001 | 0101 | 0001 | 0111 | 0110 |
---|---|---|---|---|
20-17 | 16-13 | 12-9 | 8-5 | 4-1 |
闰大月 | 1-4月 | 5-8月 | 9-12月 | 闰六月 |
从1月到12月的天数依次为:29、30、29、30、29、29(六月)、30(闰六月)、29、30、29、30、30、30,共13个月。
使用
1 | //传回农历 y年的总天数 |
日历重点是公历和阴历的转换,明后弄懂了再撰文。
转换弄懂了的话到时候结婚算八字都不用翻风水书了呢( ̄▽ ̄)
课外扩展:
八字神煞合婚算法,看看自己中了几枪