`
songgz
  • 浏览: 40517 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

农历24节气算法

 
阅读更多
许剑伟

[摘要] 古老而又现代的中国农历,是一种天文学性质的阴阳历。本文采用VSOP87星历算法并结合运动学方法以及牛顿求根法得到24节气的精确时间,揭开农历计算的神秘面纱。
[关键字] 农历算法、星历、节气

[正文] 计算中国农历,首先要计算出二十四节气时刻。在计算机问世之前,二十四节气的许算是非常复杂的。随着计算机及互联网的普及,美国航空航天局、法国巴黎天文台各自在网络上发布了精密星历表的计算方法,这使得民间计算农历成为可能。本文以法国巴黎天文台的VSOP87算法为基础,给出中国农历的二十四节气算法。
在农历中,太阳黄经为0度时,对应春风节气。相邻节气对应的太阳黄经相差15度。一周年内,太阳黄经从0度变化到360度,共有24个节气。
一、时间标尺——儒略日数计算
计算星历之前首先要解决时间尺问题。公历规定平年365日,闰年366日。1582年10月4日以前,公历规定每4年设置一个闰年,平均年长度365.25天,这期间的公历称为儒略历。在1582年10月15日之后实行格里高利历,规定每400年97闰,平均年长度为365.2425天。
由于儒略历存在严重的“多闰”问题,到了1582年,公历跑快了10天左右,当时就人为调整了10天,并从此实行格里历。因此务必注意1582年10月4日(儒略历)的下一日为1582年10月15日(格里历)。就是说1582年10月份少了10天。
在儒略历中,能被4整除的年份为闰年,这一年有366天,其它年份为平年(365天)。 如900年和1236年为闰年,而750年和1429年为平年。
格里高利历法也采用这一规则,但下列年份除外:不能被100整除的年份为平年,如1700年,1800年,1900年和2100年。其余能被400整除的年份则为闰年,如1600年,2000年和2400年。
儒略日数(简称儒略日):
儒略日数是指从公元 -4712 年开始连续计算日数得出的天数及不满一日的小数,通常记为 JD (**)。传统上儒略日的计数是从格林尼治平午,即世界时12点开始的。若以力学时(或历书时)为标尺,这种计数通常表达为“儒略历书日”,即JDE (**),其中E只是一种表征,即按每天86400个标准秒长严格地计日。例如:
1977年4月26.4日 UT = JD 2443259.9
1977年4月26.4日 TD = JDE 2443259.9
儒略日的计算:
设Y为给定年份,M为月份,D为该月日期(可以带小数)。
若M > 2,Y和M不变,若 M =1或2,以Y–1代Y,以M+12代M,换句话说,如果日期在1月或2月,则被看作是在前一年的13月或14月。
对格里高利历有 :A = INT(Y/100) B = 2 - A + INT(A/4)
对儒略历,取 B = 0
儒略日即为:
JD = INT(365.25(Y+4716))+INT(30.6001(M+1))+D+B-1524.5
使用数值30.6取代30.6001才是正确的,但我们仍使用30.6001,以确保总能取得恰当的整数。事实上可用30.601甚至30.61来取代30.6001。例如,5乘30.6精确等于153,然而大多数计算机不能精确表示出30.6,这导致得出一个152.999 9998的结果,它的整数部分为152,如此算出的JD就不正确了。
由儒略日推算历日:
将JD加上0.5,令 Z 为其整数部分,F 为尾数(小数)部分。
若 Z < 2299161,取A = Z
若 Z 大于等于2299 161,计算
α=INT((Z-1867216.25)/36524.25)
A=Z+1+α-INT(α/4)
然后计算
B = A+1524
C = INT((B-122.1)/365.25)
D = INT(365.25C)
E = INT((B-D)/30.6001)
该月日期(带小数部分)则为:
d = B - D - INT(30.6001E) + F
月份m为:
IF E < 14 THEN m = E – 1
IF E=14 or E=15 THEN m = E – 13
年份为y:
IF m>2 THEN y = C – 4716
IF m =1 or m=2 THEN y = C – 4715
这个公式里求E时用的数30.6001不能代之以30.6,哪怕计算机没有先前所说的问题。否则,你得到的结果会是2月0日而不是1月31日,或者4月0日而不是3月31日。
值得记住的一个常数是:2000年1月1日12:00:00的儒略日数是J2000 = 2451545
二、力学时与世界时的差值(deltat T)计算
一般的,可以把手表时(UTC)近似看作世界时(UT),二者的主要差别在于时区。如北京手表时8点对应世界时0点。世界时与地球自转严格同步,但有趣的是,我们的手表时实际上称为协调世界时,它的秒长是原子钟的秒长,由于地球自转速度不均匀,时快时慢,这就注定手表时与地球自转不完全同步。现在,地球自转速度正在变慢,我们不得不在某些年份的年末把手表拨慢1秒,使得手表时更好的与地球自转同步,并美言为“跳秒”。力学时是根据太阳系的动力学原理导出的,是一种均匀的时间系统,其秒长与原子钟的秒长相同。因此,协调世界时(UTC)与世界时(记为UT)其本同步,但力学时(记作TD)与世界时不太同步,二者的差值记作deltat T或记作△T。利用直接的天文观测可以得知每年的△T,利用古代的日月食观测资料可以反推古代的△T。所有年份的△T计算出来后,可以拟合出以下多项式表达,使得△T的计算更快捷,计算结果的单位是秒。
我们利用下表可以严格计算△T(即△T =TD - UT)
年份     a        b      c      d
-4000,108371.7,-13036.80,392.000, 0.0000
-500, 17201.0,  -627.82, 16.170,-0.3413
-150, 12200.6,  -346.41,  5.403,-0.1593
  150,  9113.8,  -328.13, -1.647, 0.0377
  500,  5707.5,  -391.41,  0.915, 0.3145
  900,  2203.4,  -283.45, 13.034,-0.1778
1300,   490.1,   -57.35,  2.085,-0.0072
1600,   120.0,    -9.81, -1.532, 0.1403
1700,    10.2,    -0.91,  0.510,-0.0370
1800,    13.4,    -0.72,  0.202,-0.0193
1830,     7.8,    -1.81,  0.416,-0.0247
1860,     8.3,    -0.13, -0.406, 0.0292
1880,    -5.4,     0.32, -0.183, 0.0173
1900,    -2.3,     2.06,  0.169,-0.0135
1920,    21.2,     1.69, -0.304, 0.0167
1940,    24.2,     1.22, -0.064, 0.0031
1960,    33.2,     0.51,  0.231,-0.0109
1980,    51.0,     1.29, -0.026, 0.0032
2000,    63.87,    0.1,   0,     0,
2005
表中每一行适用一定的年代范围,如第1行适用于公元-4000年到-500年,第2行适用于公元-500到-1500年,其它类推。每行的起始年份记作Y1,终止年份记作Y2,如果年份y在Y1到Y2之间,那么该年的deltat T表达为:
△T = a + b*t1 + c*t2 + d*t3,单位是秒
其中t1 = (y-Y1)/(Y2-Y1)*10, t2 = t1*t1, t3 = t1*t1*t1
对于2005年以后的deltat T是未知的,要做外推计算:
2005至2014年建议使用1995到2005年期间△T的平均增速计算,即:
△T = F(y) = 64.7 + (y-2005) * b, 其中速度 b = 0.4
2114年以后可以使用二次曲线外推
△T = f(y) = -20+ a * [(y-1820)/100]^2 ,其中加速度a = 31
2114年到2014年之间的外推,可以在上面两个外推算式的基础上做一次的曲线连接,使之连续即可。比如可以这么计算:
△T  = f(y) + (y-2114) * [f(2014) – F(2014)] /100
以下数值可供程序验证参考
2008年△T = 66.0秒
1950年△T = 29秒
500年 △T = 5710秒
三、太阳视黄经(真分点视坐标)
算法基于VSOP87半解析法。
力学时t为J2000起算的儒略世纪数,t2 = t*t,t3 = t2*t,t4 = t3*t
A、低精度算法
L0(t) = 48950621.66 + 6283319653.318*t 弧度
B、中精度算法
  L1(t) =  [ 48950621.66 + 6283319653.318*t + 53*t*t
+ 334116*cos( 4.67+628.307585*t)
+ 2061*cos( 2.678+628.3076*t)*t ] / 10000000 弧度
C、高精度算法
L2(t) = [ 48950621.66 + 6283319653.318*t
+ 52.9674*t2 + 0.00432*t3 - 0.001124*t4
+334166 * cos( 4.669257+  628.307585*t)
   +3489 * cos( 4.6261  + 1256.61517*t )
   + 350 * cos( 2.744   +  575.3385*t)
   + 342 * cos( 2.829   +    0.3523*t)
   + 314 * cos( 3.628   + 7771.3771*t)
   + 268 * cos( 4.418   +  786.0419*t)
   + 234 * cos( 6.135   +  393.021*t )
   + 132 * cos( 0.742   + 1150.677*t )
   + 127 * cos( 2.037   +   52.9691*t)
   + 120 * cos( 1.11    +  157.7344*t)
   +  99 * cos( 5.23    +  588.493*t )
   +  90 * cos( 2.05    +    2.63*t  )
   +  86 * cos( 3.51    +   39.815*t )
   +  78 * cos( 1.18    +  522.369*t )
   +  75 * cos( 2.53    +  550.755*t )
   +  51 * cos( 4.58    + 1884.923*t )
   +  49 * cos( 4.21    +   77.552*t )
   +  36 * cos( 2.92    +    0.07*t  )
   +  32 * cos( 5.85    + 1179.063*t )
   +  28 * cos( 1.9     +   79.63*t  )
   +  27 * cos( 0.31    + 1097.71*t  )
+2060.6 * cos( 2.67823 +  628.307585*t ) * t
   +43.0 * cos( 2.635   + 1256.6152*t   ) * t
   +8.72 * cos( 1.072   +  628.3076*t   ) * t2
   -994 – 834 * sin(2.1824-33.75705*t)
- 64 * sin(3.5069+1256.66393*t) ] / 10000000 弧度
  最后两行分别为光行差和章动
四、太阳黄经速度
平速度:  v0 = 628.3319653318
即时速度:v1 = 628.332 +21 * sin(1.527+628.307585*t)
速度的单位是“弧度/儒略世纪”即“弧度/36525天”
注意,平速度比即时速度的精度要高得多,务必保留足够的有效数字,否则将带来严重的计算误差。
五、节气时刻计算
以上天体黄经时间的函数,即L = f(t),所谓的求节气时刻就是已知L求t,显然这是在求解一个关于t的方程。伟大的英国天文学家物理学家牛顿给出了一种非常有效的迭代算法:牛顿求根法。用这种方法,求t所花费的时间仅是求f(t)花费时间的1.2——1.3倍。设某个节气对应的黄经为W,那么算法如下。
牛顿迭代算法设计:
第1步迭代:t = 0
第2步迭代:t = t + ( W – L0(t) ) / v0
第3步迭代:t = t + ( W – L1(t) ) / v1(t)
第4步迭代:t = t + ( W – L2(t) ) / v1(t)
误差:算法误差2分钟以内,实际找到的误差一般在30秒以内,平均15秒
注意:W指的是太阳黄经。1999年春分对应W=0,以后每W每增加15度对应下一个节气。迭代的的结果是力学时,单位是儒略世纪数。最后结果还应转换为北京时间,即:JD = J2000 + t*36525 - △T/86400 + 8/24
最后使用“儒略日数转公历”所述方法得到节气的日期和时间。
六、计算结果比较
为了进行误差比较,下文列出2007年的24节气,并与《寿星天文历》比对。《寿星天文历》是笔者制作的一款精度优于1秒的农历工具,已发布于互联网上,其算法与本文类似。

节气           本文算法  寿星天年历
春分 2007-03-21 08:06:59  08:07:26
清明 2007-04-05 12:04:21  12:04:39
谷雨 2007-04-20 19:06:40  19:07:04
立夏 2007-05-06 05:20:10  05:20:23
小满 2007-05-21 18:11:45  18:11:56
芒种 2007-06-06 09:27:02  09:27:04
夏至 2007-06-22 02:06:22  02:06:25
小暑 2007-07-07 19:41:48  19:41:42
大暑 2007-07-23 13:00:13  13:00:10
立秋 2007-08-08 05:31:31  05:31:14
处暑 2007-08-23 20:08:07  20:07:58
白露 2007-09-08 08:29:56  08:29:29
节气           本文算法  寿星天年历
秋分 2007-09-23 17:51:31  17:51:14
寒露 2007-10-09 00:12:00  00:11:31
霜降 2007-10-24 03:15:43  03:15:24
立冬 2007-11-08 03:24:24  03:24:00
小雪 2007-11-23 00:50:03  00:49:52
大雪 2007-12-07 20:14:11  20:14:04
冬至 2007-12-22 14:07:48  14:07:47
小寒 2008-01-06 07:24:43  07:24:49
大寒 2008-01-21 00:43:28  00:43:30
立春 2008-02-04 19:00:09  19:00:22
雨水 2008-02-19 14:49:27  14:49:32
惊蛰 2008-03-05 12:58:26  12:58:47

[参考文献]
1、Pierre Bretagnon与Gerard Francou 《VSOP87行星运动理论》
2、Jean Meeus《Astronomical.Algorithms》
3、NASA下属JPL实验室的《DE405/406星历表》
分享到:
评论

相关推荐

    编程开发用中国农历24节气数据

    在编程开发过程中,有时我们需要集成特定的文化或传统元素,例如中国的农历和24节气。这些数据对于创建具有中国特色的日历应用或者与日期相关的软件至关重要。以下是对标题和描述中涉及知识点的详细解释: 1. **...

    js获取年月日农历24气节

    在JavaScript编程语言中,获取农历日期以及24节气是一项常见的需求,特别是在开发与中华文化相关的应用时。在给定的标题“js获取年月日农历24气节”和描述“js获取年月日农历、24气节、星期、出行描述”中,我们可以...

    精确计算农历二十四节气

    这个“精确计算农历二十四节气”的demo为我们提供了一种算法,能够根据公历日期准确地推算出对应的农历节气。 在编程中,实现农历与节气的计算通常涉及以下几个关键点: 1. **农历转换**:首先,我们需要理解农历...

    java计算24节气

    2. **节气算法**:计算24节气的算法基于太阳黄经度,每年大致固定,但具体到每一天需要精确计算。24节气包括立春、雨水、惊蛰、春分、清明、谷雨、立夏、小满、芒种、夏至、小暑、大暑、立秋、处暑、白露、秋分、...

    【原创】一种农历、节气极限压缩算法(带数据提取工具)

    (2016) 原创的农历、节气数据极限压缩算法,不仅节省空间(农历月份信息、节气信息、梅雨信息,数九信息,伏日信息,总共仅需11字节/年),效率也高,更有强大的数据提取工具,再也不用手工从万年历上提取了,年份...

    24节气时刻计算.rar

    此外,24节气的计算还涉及到中国古代的天文学知识,如干支纪年法、二十四节气歌等,这些都是中华文化瑰宝的一部分。对于研究古代科技史和民俗文化,24节气的计算方法具有极高的学术价值。 总的来说,24节气是中国...

    万年历算法——阳历阴历24节气

    阳历算法主要依赖于对年份、月份和星期几的计算,而阴历算法则更侧重于对农历日期和24节气的确定。这两种算法的结合使得万年历能够在不同历法之间进行准确转换,为日常生活和农业生产提供了极大的便利。

    c# 日期类,提供农历、24节气、天干地支等

    3:提供24节气信息及计算方法。理论上计算几百几千年的节气还是没什么问题的,甚至可以精确到分/秒。 但对于普通人来说,无非是查查最近几年几十年的节气,并且只需要精确到日,最多精确到时罢了。

    JS完美农历、二十四节气的、可查询的万年历万年历

    在给定的标题“JS完美农历、二十四节气的、可查询的万年历万年历”中,我们可以理解这是一个利用JavaScript实现的功能完善的万年历程序,它特别强调了包含农历和二十四节气的功能。这个程序允许用户查询任何年份的...

    Android 精确计算农历二十四节气-IT计算机-毕业设计.zip

    6. **二十四节气计算**:根据农历算法,计算出每年的二十四节气的具体日期。节气是根据地球在黄道上的位置来划分的,这涉及到天文知识和数学计算。 7. **事件触发与提醒**:当节气到来时,应用可以发送通知提醒用户...

    VB计算24节气.zip

    《VB计算24节气——深入理解VB源码与节气算法》 在信息技术领域,编程语言是构建软件和应用程序的基础。Visual Basic 6.0(简称VB6)是一款经典的面向对象的编程语言,它以其易学易用的特性深受初学者和专业开发者...

    java公历转农历及计算节气的工具类

    输入公历可获取当日农历(包括属相)和节气

    Proteus单片机仿真 万年历支持温度农历24节气显示+源程序

    4. 农历与24节气:农历是中国传统的日历系统,它与阳历(公历)有所不同,需要特定的算法来计算。24节气是中国传统农耕文化的一部分,根据太阳在黄道上的位置划分,与农历相结合。在单片机项目中实现这两项功能,...

    delphi 带有24节气的日历、农历、节日

    在本文中,我们将深入探讨如何在Delphi编程环境中创建一个集成24节气、日历以及农历功能的应用程序。Delphi是一种强大的Object Pascal编程工具,它提供了丰富的组件库和强大的功能,使得开发这类应用程序变得相对...

    万年历及24节气c语言代码

    在24节气的计算上,开发者可能采用了中国传统的节气算法,如“定气法”或者“平气法”。定气法根据太阳在黄道上的位置来确定节气,而平气法则将一年分为24等份。C语言程序中,可能涉及了天文学中的黄经、赤经等概念...

    Proteus单片机仿真 万年历支持温度农历24节气显示+源程序 硬件开发 - 单片机.zip

    农历和24节气的计算则需要特定的算法,这通常需要程序员根据中国古代天文历法进行编程。 硬件开发部分,除了单片机之外,可能还包括LCD显示屏用于显示日期、时间、温度等信息,以及必要的电源管理、时钟振荡器、...

    Python万年历(含农历、节气等)

    在实际项目中,开发者还需要具备一定的算法思维和问题解决能力,例如,如何高效地计算节气,如何优雅地处理农历和公历之间的转换等。通过这个项目,开发者不仅可以提升Python编程技能,还能深入理解日期时间处理和...

    Android代码-精确计算农历二十四节气.zip

    在Android开发中,有时我们需要实现一些特色功能,例如精确计算农历二十四节气。这个压缩包“Android代码-精确计算农历二十四节气.zip”提供了一种解决方案。它包含了一个名为SolarTerm.java的Java类,用于计算农历...

    纯JS万年历,带阴历、节假日、星座、24节气

    《纯JS实现的万年历:融合阴历、节日、星座与24节气》 在Web开发中,实现一个功能全面的日历组件是常见的需求,尤其是一个支持阴历、节假日、星座和24节气的万年历,能够极大地提升用户体验。本项目通过纯...

    mysql农历数据库1970-2100,含有闰月,24节气,法定假日,星期,班休区分

    由于之前搜索了多种语言算法,得到的结果都不怎么理想。 后面搜索到一个数据库存储的,信息不怎么全,就自己新加了(闰月标识、法定假日、星期、班休,和自定义法定假日班休数据表)内容,满足业务需求, 有2个表,...

Global site tag (gtag.js) - Google Analytics