📄 sm1.htm
字号:
<html><head><title>帮助</title></head>
<body>
<center>
<table width=780 border=0 cellpadding=3 cellspacing=0>
<tr><td style='line-height:150%;font-size:16px;text-indent: 20'>
<p><a href="readme.htm">返回</a></p>
<p align=center><b>第一章 关于寿星万年历</b></p>
<p><b>一、《寿星万年历》概述</b></p>
<p>欢迎使用寿星万年历。寿星万年历是一款采用现代天文算法制作的农历历算程序,含有公历与回历信息,可以很方便的进行公、农、回三历之间的转换。提供公元-4712年到公元9999年的日期查询功能。其中-721年到1960年的农历数据已经与陈垣的《二十史朔闰表》、张培瑜的《三千五百年历日天象》、方诗铭的《中国史历日和中西历日对照表》核对;含有从公元前2000多年以前到今的基本年号。在过去几百年中,寿星万年历的误差是非常小的,节气时刻计算及日月合朔时刻的平均误差小于1秒。当使用力学时作为时间基础时,与现今最精密星历表比较,太阳坐标的最大可能误差为0.2角秒,月亮坐标的最大可能误差为3角秒,平均误差为最大可能误差的1/6。万年历中含有二千多个国内城市的经纬度,并且用户可根据自已的需要扩展经纬度数据。此外,本万年历还提供了历谱数据导出功能。</p>
<p><font color=red><b>本软件是一款真正精准的年代跨度大的日历工具,可作为一般的实用日历工具,也可供历史学家放心地使用(但最好读完此文,以免误解);软件中的算法及数据对历算工作者、天文爱好者均有较大的参考价值。</b></font></p>
<p>在寿星万年历中,还可以查询日出日没、月出月没时间等,与国内外著名的天文软件或天文年历比较,结果完全一致。此外,万年历中还即时显示了“月亮被照亮部分比例”、太阳和月亮的地心黄道坐标、地心赤道坐标、站心地平坐标等。其中日月的地心黄道、赤道则采用高精度算法;“月亮被照亮部分比例”的计算采用低精度的算法,但可以满足一般需求;地平坐标的计算已适当考虑了大气折射,由于大气的气压及气温变化具有许多不确定的因素,所以只考虑平均情况下的大气折射修正,在本软件中,地平坐标被描述为方位角与高度角,它是以观测点为中心的坐标,所以已经考虑了周日视差修正。<i><b>屏幕显示的方位角从正南向西测量</i>。</b>方位角与高度角已转换到是站心地平坐标,并且做了视差修正,同时在地平真纬度大于0时进行大气折射修正。</p>
<p>受到各地的地形地貌、大气状态、海拔高度等的影响,日出日没、月出月没时间无法计算得很准确,通常只能精确到1分钟,因此,软件中时间显示精确到到了秒数量级,但这并不表明日出日没时间的计算达到了这个精度。日月中天时刻受大气等因素的影响要小得多,所以可以精确到秒。日月的“出、中天、没”的计算不需要高精度日月位置坐标(因为一天中,日月在视野中的位置主要由地球自转决定),程序中使用非常低精度的方法计算日月坐标仍可以把中天时刻精确到秒。</p>
<p><b>[天文算法]:</b>寿星万年历在进行月历推算时采用了先进的现代天文算法,它是基于2002年巴黎天文台西尔特处Jean CHAPRONT 和 Gerard FRANCOU发表的ELP/MPP02月球运动理论,在几百年范围内,该理论与当今世界上公认的最精密的DE405/406系列星历表仅相差3毫角秒,在几千年范围相差不超过4角秒。由于农历的计算不需要这么高的精度,我们做了一些截断处理及实质性的简化处理,但仍可以满足高精度历算的要求。程序中采用了1988年法国巴黎天文台Pierre Bretagnon与Gerard Francou发表的VSOP87行星运动理论计算太阳坐标。由于该理论与DE405/406星历表存在少量差异,我们对VSOP87进行少量修正,提高了计算精度。节气及合朔时刻问题在天文学层面看来,就是已知天体的坐标反求时间的问题。在VSOP87或ELP中,天体的坐标是时间的函数z = f(t),所谓的求节气时刻或月相时刻就是已知z求t,显然这是在求解一个关于t的方程。伟大的英国天文学家物理学家牛顿给出了一种非常有效的迭代算法:牛顿求根法。用这种方法,求t所花费的时间仅是求f(t)花费时间的1.2——1.3倍,并且迭代引起的额外时间误差只零点零几秒。牛顿求根法在一般的《数值方法》书籍中均有介绍。</p>
<p><b>[古历处理]:</b>总体上说农历是天文历(天象日历),理想情况下古人计算的农历与今人计算的农历是相同的,但是由于种种原因(当时的天体运行理论局限、计算工具落后、观测精度有限、时间系统不同、动力学理论不完善等原因),古人计算的农历与今人计算的农历有点出入。通常,古人的日历是皇家日历,不能随便更改。所以,我们以古代的农历为标准,重新历算,具体方法详见以下的“古代农历与寿星万年历”章节。有些气朔数据,使用古算法的结果与其相应的颁行历法有冲突,本万年历仍使用颁行历为准,极个别使用古算法的结果(不多,只有公元320年以前几个),当然还存在一些无法考证的数据。</p>
<p><b>[地标数据]:</b>城市经纬度数据库做了压缩处理。要扩展经纬数据库,可使用附件中的【城市经纬压缩器】生成代码并替换程序中的JWv数组。程序中现有的经纬度数据本来只有几百个,后来网友郑彬给我一份2600多个城市的数据,比较全面,因此本版使用他的数据。</p>
<p><b>[时区数据]:</b>各地时区数据库做了小量压缩处理。如要扩展,可使用附件中的【时区合成器】生成代码并替换程序中的SQv数组。时区数据库是“中华农历网”netghos先生提供。</p>
<p><b>[年号纪年]:</b>万年历中的纪年数据参考万国鼎《中国历史纪年表》,有些朝代存在多组帝王,程序中不一定全部纳入。年号纪年问题比较罗嗦,本人史学功底肤浅,无法严格的解决此问题,仅在程序中加入南北朝(约公元420年)至今的年号数据,未能保证其完全正确。在V2.04版本以后,补上了由“中华农历论坛”ldlcau(亦是“国学数典”论坛的ldlcau)先生提供的公元420年以前的年号数据。从V2.04版开始,程序中提供了年号数据管理工具,详见附件中的【纪年管理器】。</p>
<p><b>[命理八字]:</b>鼠标经过日历表,显示普通的八字信息。屏幕下方的八字是严格的,以立春时刻界定年,以节气时刻界定月,以本地真太阳时23点界定日(这里的真太阳时使用低精度算法,误差可能达到1秒),以真太阳时23点、1点、3点……界定时辰。注意,这时屏幕上方输入的时间为当地时间(电脑时间,UTC)。</p>
<p><b>[日数标尺]:</b>本万年历中使用两种日数标尺。其一是公历,其二是儒略日数。为了简化历算过程,本万年历的历算代码全部使用“儒略日数”作为日数标尺。日历数据的显示则使用公历,它也叫格里历。严格的说,格里历始于1582年10月15日,1582年10月4日及以前的公历是4年1闰的儒略历。公历是在最近一百两年受到西方政治、经济优势的影响才逐渐广范使用,显然本万年历把“公历”外延到千年以前只是为了建立一个相对统一的连惯的日数标尺,而不是说很久以前全世界就在使用这种历法。再者,“公历”中的儒略历也不完全是古罗马颁行“儒略历”,因为古罗马儒略历曾有过置闰失误。</p>
<p><b>[开源软件]:</b>寿星万年历是开放源代码的,我并不打算作任何加密处理。月历生成部分涉及多种历法,而且还要处理纪年、节日信息、古历算等,所以相应的程序比较长。天文算法部分的程序比较短,只要算法已知,编写起来是比较容易的,困难的是如何设计出我们所需高精度、高速的算法。要设计算良好的天文算法,需参考较多资料并作认真的推导、验证等,工作量比较大,所以最好不要更改这部分代码,以免发生错误。</p>
<p><b>二、古代农历与寿星万年历</b></p>
<p>平气平朔日推算:只要知道当时采用的平朔望月(或相邻平气)长度k及历算起始参点b,就可推算出古历的气朔数据,当然,不同的历法所采用的k和b是不同的。例如:假设公元100年1月1日为朔日,相应的平朔时刻定为这天的12点(100年1月1.5日),平朔的k=29.53。那么下一个平朔时刻 = 100年1月1.5日 + 29.53 = 100年2月1.03日,则相应的朔日发生在2月1日。</p>
<p>显然,推算平气平朔的代数表达是:D = [ k*n + b ],式中D是气朔的日期(日数),k为气朔长度,n为气朔积累计数值,b为初始值,中括号表示取整。为了得到各个颁行历所使用的k和b,寿星万年历选择了一种快捷方法,即在现有的历谱数据中提取各历法的k、b采用值。在数十万的历谱数据中找k和b,简值是大海捞针。因此本人借助计算机强大的数据处理能力,反向推算古历算诸参数。本程序附带的反向推算的算法是通用的,不仅适用已知的连惯历谱,也适用于不连续的片段历谱。</p>
<p>反向推算的结果可能与古代历算的实际采用值存在少量差异。比如,对“四分历”历谱(公元85年以后1百多年的历谱数据)反推得到平朔望月长度值是 29.53085097。历书记载的值是 29+499/940 = 29.53085106。但本万年历使用的是前者,而不是后者。因为历算时全部采用浮点数,存在计算机固有的截断误差,直接使用499/940是危险的。如,对于分数499/940乘940得正确值499,而计算机得到的可能是489.9999999999,取整数日以后变为489,误差1天。相反,k值取前者是安全的,因为k和b的值在反推过程中已在历法适用范围内得到完全验证。<font color=red><b>关于反向推算的算法详见主目录下的《离散序列的直线拟合》章节。</b></font></p>
<p><b>反向推算过程1:</b>(-103年至1960年)</p>
<p>2008年9月5日,我在中华农历网发贴“求:中国古代农历算法”,许多热心的网友给我回复,并提供了大量资料或思想方法。在此感谢各位的同好,正是这些热心朋友的帮助才使本万年历得以进一步可靠的前推。郑先生(网名zb9003)发合我一本“古代历法计算”pdf书,主要讲三统历、四分历、乾象历,使我对古历计算有了信心。粗略看了以后,发现平气朔法的历理非常简单,只是古人把它算得很复杂,多半在处理分数及公倍数、公约数等初等数论相关的东西。我不主张使用古方法计算,在本万年历中,所有古代平气平朔法均使用线性方程来解决问题。记得尤先生(网名“易子”)曾说过“大约在唐代”开始使用平气定朔,围绕这一个要点,准确得知平朔使用的所代范围。</p>
<p>(1)先从徐先生(网名“春光”)发给我的《古代历法摘要(上)》获得“中国历法表”,在这个表中得知中国曾经版发的历法名称及适用范围。春光的一句话给我很大的帮助:“主要参考律历志”。</p>
<p>(2)在网上下载《三千五百年历日天象》pdf书,把古代日历部分传换为bmp格式。通用ocr软件无法准确的将bmp日历转换为文本格式日历数据表,所以利用C++Builder编写一个图片转文字的专用程序,将这本书扫描成文本格式的日历表。在扫描过程中,遇到识别困难的,在识别后的文字前加一个问号。这项工作整整历时5天。误码率为1%,误码的部分通常会有个问号,所以真正误码的不到千分一。当初转化时,只从-100年开始,所以其中的-103年到-101的这3年的日历采用手工输入。</p>
<p>(3)编写javascript程序,对扫描后的数据进行校验,以消除误码并找出原书的错误。校验方法:a.大小月与朔日的日期进行校验;b.1645年以后的一些关键数据还与寿星万年历早期版本比对;c.节气的日期与节气干支比对;d.节气干支与朔日干支校验;e.相邻节气长度粗大误差校验。所有校验不通过的给出报告并进行人工校对,直到不发生错误报告为止。校验过程中,发现原书也有不少错误。</p>
<p>(4)最强有力的校验:分段线性拟合校检!1645年以前的日历采用平气法,也就是说在某一个历法实行期间,相邻节气交接时刻之差(或朔时刻之差)为常数,各交接时刻可以连成直线。由于原书没有给出交接时刻,所以采用了一些变换方法。</p>
<p>设拟合公式为 D=k*n+b,n=0,1,2,...,用D(n)的整数部份与历表比对,如果不能通过则调整k和b并重新比对(k和b的反复调整方法需要算法支持,如果算法适当,只需调整1至4次就可得到最佳的k和b),直到通过,如果不能通过,则说明书中的的数据有问题或古代历算家的计算结果有问题或是扫描出错,那么就减小拟合的日历范围,找出拟合能够通过与不能通过的临界节气,然后人工查看一下原书中该日期到底错在哪里,为什么错。当然找出为什么出错是需要一些技巧,为此我花了好多时间。</p>
<p>分段拟合所用的时间分段范围使用第(1)所述的“中国历法表”。并不是“中国历法表”中所有的历法颁发时段完全与《三千五百年历日天象》吻合,其中的律历志、新唐书等相关的是吻合的,出现这些问题的原因是,国家分裂时期可能有多部历法同时颁行。</p>
<p>(5)古代定气的算法:本万年历使用开普勒椭圆轨道定气,同时考虑了岁差、章动、轨道要素的长期变化。但必竞使用了现代数据,与古代历算参数有点差异,所以程序中对定气朔进行了订正,使之与古历相符。</p>
<p>也许有人会问,为什么不考虑使用古代原来的算法?实际上,为了提高历算精度,清代的《历象考成》已经使用了第谷的宇宙体系,在乾隆七年(公元1742年)以后的《历象考成后编》,开始应用了开普勒行星运动第一、第二定律(但椭圆焦点上的是地球而不是太阳)。因此大约在1734年以后,古代定气与现代计算结果的已经相差无几。这就造成简单的加减乘除根本不能解决问题,所以宁愿采用“现代算法+订正”思路来解决问题。</p>
<p>(6)古代定朔的算法:从公元619年开始,我国就已经使用定朔法,不同年代的定朔算法差异很大。早期使用一些修正表并插值来推算朔日,晚期已经使用牛顿运动定律求解,本人没有时间也没有能力逐一追朔古人的算法,翻阅历代文献,对我来说简直是天书。于是,利用现代推算的月球轨道要素(已考虑了长期变化),把月球运动近似为椭圆进而算出朔日,再与古历比对,生成朔日订正表。接下来,在正式的程序中使用“椭圆运动+朔日订正表”得到精准的古代定朔日历。</p>
<p><b>反向推算过程2:</b>(-721年至-104年)</p>
<p>(1)根据《三千五百年历日天象》手工输入秦汉气日朔日表、战国朔日表、春秋朔日表。花费了一个下午的时间。</p>
<p>(2)对气朔表做线性拟合。对闰年表做线性拟合。拟合的过程中同时校验查错。</p>
<p>(3)拟合以后发现,该书中的春秋、战国分别使用一个平朔线性算式。实际上,原数据个别数据错误造成一个线性算式无法拟合通过,我已对其改正。从原理上分析,上元取值不同造成的的“错误”不会是个别的,所以《三千五百年历日天象》中的这些错误多半是原作者算错或笔误了或颁行历法的错误。不过,颁行历法发生错误的可能性要小很多。</p>
<p><b>反向推算的结果:</b></p>
<p>在没用足够的古代历书的帮助下,直接使用历谱数据,通过以上方法就可重现古代不同历法平气平朔的历算参数及定气朔的修正表。所有参数确定后,还特别校对了一下1645年以后定气定朔颁行历与现代算法计算结果的差异。经过以上拟合校验,最后得到古代历谱计算所需的数据只有4k,并使得本万年历计算结果的准确性超过了《三千五百年历日天象》本身,可利用它辅助校验历书数据。</p>
<p>上述平气、平朔的计算公式表达为:D = k*n + b , 式中n=0,1,2,3,...,N-1;下面给出各朝代颁发历法的k与b的参数,每行第1个参数为b,第2参数为k,结果D表达为儒略日数;h表示k不变b允许的误差,如果b不变则k许可误差为h/N;N是历法颁行期间朔或气的总个数。</p>
<pre>
//“朔”直线拟合参数
1457698.231017,29.53067166, // -721-12-17 h=0.00032 古历·春秋
1546082.512234,29.53085106, // -479-12-11 h=0.00053 古历·战国
1640640.735300,29.53060000, // -221-10-31 h=0.01010 古历·秦汉
1642472.151543,29.53085439, // -216-11-04 h=0.00040 古历·秦汉
1683430.509300,29.53086148, // -104-12-25 h=0.00313 汉书·律历志(太初历)平气平朔
1752148.041079,29.53085097, // 85-02-13 h=0.00049 后汉书·律历志(四分历)
1807665.420323,29.53059851, // 237-02-12 h=0.00033 晋书·律历志(景初历)
1883618.114100,29.53060000, // 445-01-24 h=0.00030 宋书·律历志(何承天元嘉历)
1907360.704700,29.53060000, // 510-01-26 h=0.00030 宋书·律历志(祖冲之大明历)
1936596.224900,29.53060000, // 590-02-10 h=0.01010 随书·律历志(开皇历)
1939135.675300,29.53060000, // 597-01-24 h=0.00890 随书·律历志(大业历)
1947168.00// 619-01-21
//“气”直线拟合参数
1640650.479938,15.21842500, // -221-11-09 h=0.01709 古历·秦汉
1642476.703182,15.21874996, // -216-11-09 h=0.01557 古历·秦汉
1683430.515601,15.218750011,// -104-12-25 h=0.01560 汉书·律历志(太初历) 回归年=365.25000
1752157.640664,15.218749978,// 85-02-23 h=0.01559 后汉书·律历志(四分历) y=365.25000
1807675.003759,15.218620279,// 237-02-22 h=0.00010 晋书·律历志(景初历) y=365.24689
1883627.765182,15.218612292,// 445-02-03 h=0.00026 宋书·律历志(何承天元嘉历) y=365.24670
1907369.128100,15.218449176,// 510-02-03 h=0.00027 宋书·律历志(祖冲之大明历) y=365.24278
1936603.140413,15.218425000,// 590-02-17 h=0.00149 随书·律历志(开皇历) y=365.24220
1939145.524180,15.218466998,// 597-02-03 h=0.00121 随书·律历志(大业历) y=365.24321
1947180.798300,15.218524844,// 619-02-03 h=0.00052 新唐书·历志(戊寅元历) y=365.24460
1964362.041824,15.218533526,// 666-02-17 h=0.00059 新唐书·历志(麟德历) y=365.24480
1987372.340971,15.218513908,// 729-02-16 h=0.00096 新唐书·历志(大衍历,至德历)y=365.24433
1999653.819126,15.218530782,// 762-10-03 h=0.00093 新唐书·历志(五纪历) y=365.24474
2007445.469786,15.218535181,// 784-02-01 h=0.00059 新唐书·历志(正元历,观象历)y=365.24484
2021324.917146,15.218526248,// 822-02-01 h=0.00022 新唐书·历志(宣明历) y=365.24463
2047257.232342,15.218519654,// 893-01-31 h=0.00015 新唐书·历志(崇玄历) y=365.24447
2070282.898213,15.218425000,// 956-02-16 h=0.00149 旧五代·历志(钦天历) y=365.24220
2073204.872850,15.218515221,// 964-02-16 h=0.00166 宋史·律历志(应天历) y=365.24437
2080144.500926,15.218530782,// 983-02-16 h=0.00093 宋史·律历志(乾元历) y=365.24474
2086703.688963,15.218523776,// 1001-01-31 h=0.00067 宋史·律历志(仪天历,崇天历) y=365.24457
2110033.182763,15.218425000,// 1064-12-15 h=0.00669 宋史·律历志(明天历) y=365.24220
2111190.300888,15.218425000,// 1068-02-15 h=0.00149 宋史·律历志(崇天历) y=365.24220
2113731.271005,15.218515671,// 1075-01-30 h=0.00038 李锐补修(奉元历) y=365.24438
2120670.840263,15.218425000,// 1094-01-30 h=0.00149 宋史·律历志 y=365.24220
2123973.309063,15.218425000,// 1103-02-14 h=0.00669 李锐补修(占天历) y=365.24220
2125068.997336,15.218477932,// 1106-02-14 h=0.00056 宋史·律历志(纪元历) y=365.24347
2136026.312633,15.218472436,// 1136-02-14 h=0.00088 宋史·律历志(统元历,乾道历,淳熙历)365.24334
2156099.495538,15.218425000,// 1191-01-29 h=0.00149 宋史·律历志(会元历) y=365.24220
2159021.324663,15.218425000,// 1199-01-29 h=0.00149 宋史·律历志(统天历) y=365.24220
2162308.575254,15.218461742,// 1208-01-30 h=0.00146 宋史·律历志(开禧历) y=365.24308
2178485.706538,15.218425000,// 1252-05-15 h=0.04606 淳祐历 y=365.24220
2178759.662849,15.218445786,// 1253-02-13 h=0.00231 会天历 y=365.24270
2185334.020800,15.218425000,// 1271-02-13 h=0.00520 宋史·律历志(成天历) y=365.24220
2187525.481425,15.218425000,// 1277-02-12 h=0.00520 本天历 y=365.24220
2188621.191481,15.218437484,// 1280-02-13 h=0.00013 元史·历志(郭守敬授时历) y=365.24250
2321919.49// 1645-02-04
</pre>
<p>直得注意的是:儒略日数的小数部分为0.5才对应晚上0点;新唐书·历志(戊寅元历)公元619年开始使用平气定朔,之前使用平气平朔,1645年及以后使用定气定朔。</p>
<p><font color=red><b>举例说明:</b></font>求公元88年2月15(儒略日数为1753245)附近的朔日的具体公历日期。</p>
<p>88年的颁行历为后汉书·律历志的四分历,它的平朔参数 b = 1752148.041079,k = 29.53085097。先把朔日D估计为88年2月15日。又因 D = k*n+b,所以 n = (D-b)/k = 37.15,四舍五入取整得 n = 37。易得准确日期为 D = k*n+b = 1753240.68,转为公历得公元88年2月11号4时,朔日在11日。</p>
<p><b>1501至1940颁行历的朔日与今算得天象不相符的数据:</b></p>
<p>以下古历部分数据来自《二十史朔闰表》</p>
<table border="1" width="100%" style='font-size:16px'>
<tr align=center><td><b>天象日期 =》 古历日期</b></td> <td><b>天象日期 =》 古历日期</b></td></tr>
<tr align=center><td>1501-06-16 六月 =》06-15</td> <td>1508-01-02 十二 =》01-03</td></tr>
<tr align=center><td>1513-10-29 十月 =》10-28</td> <td>1516-10-25 十月 =》10-26</td></tr>
<tr align=center><td>1521-10-01 九月 =》09-30</td> <td>1526-07-10 六月 =》07-09</td></tr>
<tr align=center><td>1527-06-29 六月 =》06-28</td> <td>1534-06-12 五月 =》06-11</td></tr>
<tr align=center><td>1535-08-29 八月 =》08-28</td> <td>1535-10-26 十月 =》10-27</td></tr>
<tr align=center><td>1544-05-22 五月 =》05-21</td> <td>1546-01-02 十二 =》01-03</td></tr>
<tr align=center><td>1546-07-28 七月 =》07-27</td> <td>1571-08-21 八月 =》08-20</td></tr>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -