算法系列之二十:计算中国农历(二)

图(1)没有闰月情况下朔日与冬至节气关系图

图中上排数字是公历月的编号,黑色圆点代表朔日,黑色三角形代表冬至节气。图(2)显示了2012年有闰月的情况下朔日和冬至的关系:

图(2)有闰月情况下朔日与冬至节气关系图

朔日编号

对应公历日期

月长

月名

1

01:35:39.90

2010-12-06

29

冬月

2

17:02:34.26

2011-01-04

30

腊月

3

10:30:42.67

2011-02-03

正月

4

04:45:59.44

2011-03-05

二月

5

22:32:15.13

2011-04-03

三月

6

14:50:31.79

2011-05-03

四月

7

05:02:32.51

2011-06-02

五月

8

16:53:54.10

2011-07-01

六月

9

02:39:45.06

2011-07-31

七月

10

11:04:06.43

2011-08-29

八月

11

19:08:50.09

2011-09-27

九月

12

03:55:54.64

2011-10-27

十月

13

14:09:40.97

2011-11-25

14

02:06:27.05

2011-12-25

15

15:39:23.99

2012-01-23

表(2)2011年朔望月与公历日期关系表

编号为1和2的两个朔日之间的朔望月是十一月,因为冬至节气落在这个朔望月,其它月的月名依次类推,正月的朔日就是春节。输出公历和农历双历时,以月(公历)为单位,从每月第一天开始,依次判断每一天属于哪个朔望月,确定这一天的农历月名,然后比较这一天和这个朔望月的朔日之间相差几天,记为农历日期。以2011年1月1日为例,这一天在2010年12月6日(2010年农历十一月的朔日)和2011年1月4日之间(2010年农历十二月的朔日),查表(1)可知对应的农历月是十一月,这一天和2010年12月6日相差26天,因此这一天的农历日期就是“廿七”。再以2011年2月3日(春节)这一天为例,查朔望月表得知2月3日属于从2月3日开始的朔望月,这个朔望月的月名是正月,而2月3日就是月首,农历日期是初一,正月初一就是春节。

5doubleCalculateSolarTerms(intyear,intangle);

8doubleCalculateMoonShuoJD(doubletdJD);

生成指定公历年份的公历和农历的双历年历的流程如下:

图(3)计算公农历双历年历的流程

139voidCChineseCalendar::GetAllSolarTermsJD(intyear,intstart,double*SolarTerms)

140{

141inti=0;

142intst=start;

143while(i<25)

144{

145doublejd=CalculateSolarTerms(year,st*15);

147if(st==WINTER_SOLSTICE)

148{

149year++;

150}

151st=(st+1)%SOLAR_TERMS_COUNT;

152}

153}

start参数是节气的索引,定义二十四节气的索引如下:

38constintVERNAL_EQUINOX=0;//春分

39constintCLEAR_AND_BRIGHT=1;//清明

40constintGRAIN_RAIN=2;//谷雨

41constintSUMMER_BEGINS=3;//立夏

42constintGRAIN_BUDS=4;//小满

43constintGRAIN_IN_EAR=5;//芒种

44constintSUMMER_SOLSTICE=6;//夏至

45constintSLIGHT_HEAT=7;//小暑

46constintGREAT_HEAT=8;//大暑

47constintAUTUMN_BEGINS=9;//立秋

48constintSTOPPING_THE_HEAT=10;//处暑

49constintWHITE_DEWS=11;//白露

50constintAUTUMN_EQUINOX=12;//秋分

51constintCOLD_DEWS=13;//寒露

52constintHOAR_FROST_FALLS=14;//霜降

53constintWINTER_BEGINS=15;//立冬

54constintLIGHT_SNOW=16;//小雪

55constintHEAVY_SNOW=17;//大雪

56constintWINTER_SOLSTICE=18;//冬至

57constintSLIGHT_COLD=19;//小寒

58constintGREAT_COLD=20;//大寒

59constintSPRING_BEGINS=21;//立春

60constintTHE_RAINS=22;//雨水

61constintINSECTS_AWAKEN=23;//惊蛰

137voidCChineseCalendar::GetNewMoonJDs(doublejd,double*NewMoon)

138{

139for(inti=0;i

141doubleshuoJD=CalculateMoonShuoJD(jd);

142NewMoon[i]=shuoJD;

143

145}

146}

170boolCChineseCalendar::BuildAllChnMonthInfo()

171{

172CHN_MONTH_INFOinfo;//一年最多可13个农历月

173inti;

174intyuejian=11;//采用夏历建寅,冬至所在月份为农历11月

175for(i=0;i<(NEW_MOON_CALC_COUNT-1);i++)

176{

177info.mmonth=i;

178info.mname=(yuejian<=12)yuejian:yuejian-12;

179info.shuoJD=m_NewMoonJD[i];

180info.nextJD=m_NewMoonJD[i+1];

181info.mdays=int(info.nextJD+0.5)-int(info.shuoJD+0.5);

182info.leap=0;

183

184CChnMonthInfocm(&info);

185m_ChnMonthInfo.push_back(cm);

186

187yuejian++;

188}

189

190return(m_ChnMonthInfo.size()==(NEW_MOON_CALC_COUNT-1));

191}

194voidCChineseCalendar::CalcLeapChnMonth()

195{

196assert(m_ChnMonthInfo.size()>0);/*阴历月的初始化必须在这个之前*/

197

198inti;

199

200if(int(m_NewMoonJD[13]+0.5)<=int(m_SolarTermsJD[24]+0.5))//第13月的月末没有超过冬至,说明今年需要闰一个月

201{

202//找到第一个没有中气的月

203i=1;

204while(i<(NEW_MOON_CALC_COUNT-1))

205{

206

207/*m_NewMoonJD[i+1]是第i农历月的下一个月的月首,本该属于第i月的中气如果比下一个月

208的月首还晚,或者与下个月的月首是同一天(民间历法),则说明第i月没有中气*/

209if(int(m_NewMoonJD[i+1]+0.5)<=int(m_SolarTermsJD[2*i]+0.5))

210break;

211i++;

212}

213if(i<(NEW_MOON_CALC_COUNT-1))/*找到闰月,对后面的农历月调整月名*/

214{

215m_ChnMonthInfo[i].SetLeapMonth(true);

216while(i<(NEW_MOON_CALC_COUNT-1))

217{

218m_ChnMonthInfo[i++].ReIndexMonthName();

219}

220}

221}

222}

从理论上讲,本文介绍的算法在精度允许的范围内可以计算前后几千年的农历年历,但是对古代的农历计算需要小心。首先是“平朔”和“定朔”的问题,唐代以前使用的是平朔方法定月首,本文介绍的计算方法采用的是“定朔”方法,因此计算出的年历与唐代以前的历史会不一致。另外,即是在唐代以后采用“定朔”的历法,因为古代天文观测和计算受条件限制,可能不够精确,因此与现在用天文算法计算出的结果可能并不一致。所以对历史农历的计算应该以历史事实为主,天文计算为辅,当计算与历史不一致时,要根据历史数据进行校正。Calendar.exe是根据本文介绍的算法编写的日历小程序,没有太多的功能,主要是为了验证算法,因为没有历史数据用于修正结果,因此不支持1601年以前的农历计算(也就是说按照天文算法计算出来的结果可能和实际历史上的历法不符)。

图(5)演示程序的界面

小知识1:民间历法和历理历法

小知识2:通式寿星公式

“通式寿星公式”是前人整理出来的一个用于计算每年立春日期的经验公式:

Date=向下取整(Y*D+C)-L

其中,Y是年份,D的值是0.2422,C是经验值,取决于节气和年份,对于21世纪,立春节气的C值是4.475,春分节气的C值是20.646等等;

L是闰年数,其计算公式为:

L=向下取整(Y/4)-向下取整(Y/100)+向下取整(Y/400)

用“通式寿星公式”确定2011年立春日期的过程如下:

L=int(2011/4)–int(2011/100)+int(2011/400)=502–20+5=487

Date=int(2011×0.2422+4.475)-487=491–487=4

所以,2011年的立春日期是2月4日。

小知识3:计算节气和朔日的经验公式

F=365.242*(y–1900)+6.2+15.22*x-1.9*sin(0.262*x)

其中x是节气的索引,0代表小寒,1代表大寒,其它节气按照顺序类推。

计算从1900年开始第m个朔日的公式是:

M=1.6+29.5306*m+0.4*sin(1-0.45058*m)

小知识4:平朔和定朔

小知识5:正月初一和立春节气

立春是二十四节气之首,所以古代民间都是在“立春”这一天过节,相当于现代的春节(中国古代即是节气也是节日的情况很多,比如清明、冬至等等)。1911年,孙中山领导的辛亥革命建立了中华民国,在从历法上正式把农历正月初一定为“春节”,把公历1月1日定为“元旦”,也就是“新年”。农历年从正月初一开始没有争议,但是农历生肖年从何时开始却一直有争议,目前多数人都认为“立春”节气是农历生肖年的开始。因为在中国古代历法中,十二生肖的计算与天干地支有很大关系,所以在“论天干地支、计算廿四节气”的情况下,“立春”节气应该是新生肖的开始。对于普通老百姓来说,习惯于认为正月初一是生肖年的开始,因此,正月初一和“立春”节气之间出生的小孩,在确定属相的时候就有点麻烦了。属龙还是属蛇?这是个问题。

THE END
1.儒略日数和日干支计算器时间(24小时制)夜半正午其他时间 时分秒 ,执行公历日期→儒略日数和日干支。 儒略日数: ,执行儒略日数→公历日期和日干支。 计算结果 公历日期: 公元2024年11月29日, 时间: 12:00:00 儒略日数:2460644, 星期五 日干支: 丁酉(干支数=34) 说明https://www.chengxua.com/lishi/Julian_simp.html
2.426万年历信息服务万年历查询,阳历农历转换。阳历农历 相隔天数计算器 起始日期: 结束日期: 生日查星座 阳历农历 阴阳历转换 阳历农历 万年历1900~2099年日历表 1900~1909 1900年日历表1901年日历表1902年日历表1903年日历表1904年日历表 1905年日历表1906年日历表1907年日历表1908年日历表1909年日历表 https://www.rili.com.cn/wannianli/
3.中国农历年份,rpa,机器人,自动化至此千百年来,中国传统历——汉历(农历)所采用得干支纪年方法,与皇帝年号纪年一样以新年正月朔(元旦)为开始。 从元明清三代的史书,可见干支纪年在正月初一更替的记录:更多内容请查看https://baike.baidu.com/item/%E5%B9%B2%E6%94%AF%E7%BA%AA%E5%B9%B4/3383226 https://wdlinux.cn/html/zonghe/20241128/20015.html
4.农历阳历转换阴历转公历查询阴历阳历换算农历知识问答:公历是农历还是阳历?解答:公历是阳历。农历是阳历还是阴历?解答:农历是阴历。 您也可以在『万年历』中查询。如何在万年历进行阴历查阳历:一般阴历日期大概落后阳历日期一个月,比如要查2010年农历四月二十的阳历,翻动万年历,可能在2010年5月或6月的界面找到。 https://m.buyiju.com/cha/yyl.php
5.算法系列之二十:计算中国农历(一)农历算法算法系列之二十:计算中国农历(一) 本文介绍了中国农历的历法规则,包括阴阳历的结合、天干地支纪年法、闰月的设置原理以及农历与二十四节气的关系。农历以月相为基础,通过置闰月协调与回归年的差异。天干地支纪年法通过天干(10个)和地支(12个)组合,每60年一个轮回。农历的闰月依据“十九年七闰”或更精确的“中气https://blog.csdn.net/orbit/article/details/9210413
6.公历农历转换公历农历转换 二十四节气查询 汽车油耗计算 电费计算器 日期差计算 未来时间查询 金银走势 交通标志 常用电话号码 交通违章查询 快递查询 机场三字码查询 全球港口查询 2025放假时间安排表 行政区划查询 统计用产品分类目录 经纬度查询 升降旗时间 倒计时 https://gonglinongli.bmcx.com/
7.日期计算器农历/阳历转换 农历/公历转换 在线秒表 节日大全 万年历 24节气查询 2024年放假 北京时间 今天农历几月几日 老黄历 吉时吉日查询 提供快速计算出两日期相差天数,以及提供天数推算日期的服务。 点击我体验(新版)日期计算器 日期推算: 计算日期差: 工具简介 https://www.sojson.com/time/jsq.html
8.农历计算器首页>>时间工具箱>> 农历计算器 计算两个农历日期之间差多少天 农历:年月日 距 农历:年月日 相差:天 推算几天后的农历日期 年月日 (默认今天农历) 往后天 (输入负数向前计算) 结果: →农历转换阳历 →天数计算器https://www.qianask.com/tooltime/nongli.html
9.万年历农历查询农历阳历转换阴历转阳历阴阳历转换2019年日历农历表 2020年日历农历表 2021年日历农历表 2022年日历农历表 2023年日历农历表 2024年日历农历表 2025年日历农历表 国学文化导航 →传统节日24节气民俗文化国学大全四库全书诸子百家文学名著国学语录汉语字典 十二星座 星座运势|星座性格|星座配对|生日配对|个人星盘|星座查询|48星区|生日密码|星座日期|星座https://life.httpcn.com/nongli.asp
10.农历公历转换阴历转阳历 请输入农历(阴历)日期: 年月日 农历是中国传统历法,现在生活中一般俗称阴历(太阴历-按月亮月相周期变化计算的历法)。阳历为太阳历,以地球公转周期计算的历法,公历就是一种太阳历。公历是现今世界通行的历法,即公历纪元、亦称西历,西元、公元等。https://t.aies.cn/shijian/nongli/
11.农历日期本文详细介绍了在Excel中插入农历日期的多种方法,包括使用公式、VBA函数和第三方插件,帮助读者在处理数据时实现农历日期的插入。 开始使用 已被使用33次 深入了解宫表计算器:轻松掌握使用方法 本文详细介绍了宫表计算器的结构和使用方法,帮助读者轻松掌握这一独特的计算工具,以准确计算出农历日期和传统节气。 https://www.zaixianjisuan.com/tag/107407
12.用于儒略历日和农历日期之间转换的计算装置和方法导航: X技术> 最新专利>计算;推算;计数设备的制造及其应用技术专利名称::用于儒略历日和农历日期之间转换的计算装置和方法技术领域::本发明涉及一种在计算装置中进行儒略日#丈(Juliandaynumber)禾口农历日其月(Chinesecalendardate)之间的4争4灸的方';去,还涉及一种用于实施这样的转换的计算装置。背景技术::如本https://www.xjishu.com/zhuanli/55/200580047646.html
13.身份证农历日期计算法生日揭秘农历转换身份证10月12日对应的农历日期,揭秘农历生日计算法身份证10月12号农历多少1、星座是按阳历算的 你去万年历上面可以根据 你出生的阴历时间查到你的阳历生辰。2、阴历是:九月初七 3、你女独自流浪 2024-11-28 没有更多内容 滇ICP备2023010045号-70 本文内容由互联网用户自发贡献,该文观点仅代表作者本人,http://m.emotion123456.com/tags-62138.html
14.jquery如何获取农历js获取农历时间js计算农历日期前段时间仿做了一个win10的日历,其中涉及到阳历转换成农历的问题,当时顺手百度了一个js代码提供这个功能,但是不知道为什么其中有一段代码将2020年之后日期的屏蔽掉了,我将这个代码删除之后发现可以继续计算,当时没有多想,事后发现2020年之后的计算结果全是错误的 原因 农历定义为: 农历取月相的变化周期即朔望月为月https://blog.51cto.com/u_16099263/11744503
15.过生日是按那个日期来算?(生日怎么算的)打开日历 打开手机或电脑的日历功能,翻阅到自己阳历生日的这天,查看这天的农历日期即可。 2. 计算 要计算农历生日,需按照出生时的农历,每年在此农历时间便是生日。 3. 手机查找 可以用手机或电子辞典查,在手机“日历”的“更改日期”里输入出生日期,确定后就能显示出生日期的阳历,同时农历日期 https://www.shiwaiyun.com/article/post/142430.html
16.xktime:xkxk-time 是时间转换,时间计算,时间格式化,时间解析,日历,时间cron表达式和时间NLP等的工具,使用Java8,线程安全,简单易用,多达70几种常用日期格式化模板,支持Java8时间类和Date,轻量级,无第三方依赖。 xk-time is a tool for time conversion, time calculation, time formatting, time parsing, calendar, time cronhttps://gitee.com/xkzhangsan/xk-time
17.技术分析农历日期公式详解:如何准确计算农历日期与节气转换先战胜自己,再战胜庄家。https://www.55188.com/thread-27907839-1-1.html
18.日历天数计算器计算日期相差天数输入日期自动计算天数天天日期为您提供:计算天数在线计算、日期天数计算器、时间计算器、倒计时等功能,帮助您在线自动计算转换公历农历日期的间隔天数、年数、月数、周数,可帮您计算有关恋爱结婚、生日纪念日、考试的等事件的天数日期。https://www.ttriqi.com/
19.全新的Excel公农历转换方法,含节气四柱日期计算和天数计算1、能否在紫色日期标题栏加上年月的农历,举例,公历纪元2018(戊戌)年3(乙卯)月 农历正月(小);或者https://club.excelhome.net/thread-1281548-7-1.html
20.日期计算器资料大全www.riqijisuanqi.com查询结果2020年时间差天数在线日期计算器,使用现在最新时间在线计算,提供日期、几天后日期、两个时间的时间差等时间计算方法,预产期安全期倒计时,农历转换为阳历,2020年最好用的日期计算器,时间管理专家。https://cdn.2898.com/website_250692.htm
21.年龄计算器,在线计算周岁虚岁年龄计算器为您提供在线计算周岁虚岁、周岁虚岁在线计算,周岁在线计算,虚岁在线计算,教你如何计算周岁怎么算、怎么算虚岁,计算实际岁数,周岁计算器,虚岁计算器,生日天数计算,虚岁怎么算,年龄计算器,生肖查询,星座查询,还可以在线计算出你活了多久、多少天等。https://nianling.xiaowazi.com/
22.日期查询网今天是农历几月几日星期几今天是什么日子时间计算器说明 此日期计算器可以帮您算出从出生至今日一共存活了多少天数、距离节日、高考、考研、纪念日等日期还相差多少天数。有向前向后两种计算方式;并有计算几天后的时间和日期差数两种换算模式。 热门地区时间 美国时间农历转换生辰八字时区预产期排卵期倒计时闹钟时间戳时辰对照表世界时间时间万年历行业分类尺子http://www.78994.cn/
23.万年历查询表农历万年历虚岁计算器万年历/虚岁/农历月份 1、计算指定公历日期的虚岁 公历(阳历)生日: 要计算虚岁的特定日期(如受孕日、末次月经首日): 在这天的虚岁: 2、根据公历日期计算农历日期、农历月份 公历(阳历)日期: 农历(阴历)日期: 农历(阴历)月份:(计算受孕/月经/排卵的农历月份)https://www.bozhong.com/tools-yinli.html
24.生日年龄计算器,在线计算周岁虚岁知之生日年龄计算器为您提供在线计算周岁虚岁、周岁虚岁生日在线计算,周岁在线计算,虚岁在线计算,教你如何计算周岁怎么算、怎么算虚岁,计算实际岁数,周岁计算器,虚岁计算器,生日天数计算,虚岁怎么算,年龄计算器,生肖查询,星座查询,还可以在线计算出你活了多久、多少天等。https://nianling.100xgj.com/
25.万年历天干地支查询表天干地支日期计算器万年历表干地支老黄历火光,万年历查询日历查询农历查询农历日历老黄历万年历表,年5月13日星期三农历四月十六日丁卯年乙巳月壬戌日足以每地支的万年历万年历干地支查询带干支的万年历查询。 日柱在命学上顺时针在晚上子开始十二个是一每占两个,其实在古代采用十干与十二地支组成的纪年方式但是对于当时大字不识的平头https://www.16757.com/ysh/huangli/1287.html
26.天数计算器计算助手,多功能计算器合集。 时间日期计算器,轻松计算日期天数,非常好用。时间换算,清爽换算时间,包括,年、月、日、小时、分、秒等等。 更多计算包含: 日期天数计算器 亲戚称呼计算器 星座生肖计算器 农历公历计算器 闰年计算器 成年人BMI计算器 吸烟成本计算器 脂肪百分比计算 随机数生成器 N次方计算器 开根号计https://apps.apple.com/bf/app/%E5%A4%A9%E6%95%B0%E8%AE%A1%E7%AE%97%E5%99%A8-%E6%97%A5%E6%9C%9F%E6%97%B6%E9%97%B4%E8%AE%A1%E7%AE%97%E5%8A%A9%E6%89%8B/id1659343679