公历和儒略日
儒略日的计算

儒略⽇的计算儒略⽇的计算现在的公历起源于埃及历,由古罗马的恺撒在公元前46年制定的,365⽇作为⼀年,单⽉为⼤⽉31天,双⽉为⼩⽉30天,4年⼀闰,称为"儒略历"或"恺撒历"。
1582年罗马教皇格⾥⾼利⼗三世(Gregorius XⅢ)对"儒略历"⼜进⾏修改,规定被4整除的年为闰年,但逢百之年只有能被400除尽才能是闰年。
这就是使⽤⾄今的"格⾥历"。
教皇于1582年10⽉ 4⽇还下令将次⽇(即原10⽉5⽇)定为10⽉15⽇,把春分⽇⼜恢复为3⽉21⽇。
儒略⽇(Julian day,JD)是由法国学者 Joseph Justus Scaliger(1540-1609)发明的,是天⽂学上不⽤⼀种不⽤年、⽉的长期纪⽇法,⽤它可以很⽅便地计算到两时? 涞慵湟蕴焓 屏康氖奔浼涓簟H迓匀找怨 ?713年儒略历1⽉1⽇格林威治平午为起算⽇期,以7980年为⼀个周期,每天顺数⽽下,流⽔计⽇。
儒略⽇的这种计算⽅法相当⽅便,获得了天⽂? 缒诘囊恢虏捎茫 翘煳募扑阒凶钗 匾 募扑慊 肌?例如:JD=245 191 9.34230,它意味着距儒略周期的开始已经逝去了2451919天。
⽽⼩数点后的".34230"代表这天的时间("15:12:54 EST"),在天体位置计算中是最具信息量的数据。
再⽐如世界时公元2009年3⽉1号的儒略⽇是2454891.8333333335天。
注意,"儒略⽇(julian Day)" 与"儒略历(Julian Calendar)"指的不是同⼀概念。
由于儒略⽇的表达数值太长,需要7位数字表⽰天数,因此,后来⼜出现了⼀种约化儒略⽇(Modified Julian Day,MJD)的记法,MJD = JD - 2,400,000.5,即约化儒略⽇的起算点在1858年11⽉16⽇平午。
儒略日与公历转换公式

儒略日与公历转换公式儒略日是一种表示日期的方法,它最初由儒略历制定者所使用,后来被广泛应用于科学和天文学领域。
儒略日是指自公元前4713年1月1日中午12点(格林威治时间)至今所经历的天数。
儒略日的计算涉及到公历和儒略历的转换,下面介绍一下常用的儒略日与公历转换公式。
儒略日转公历日期公式:首先,儒略日数J的整数部分代表的是距离公元前4713年1月1日中午12点的天数,而小数部分代表的是当天已经过去的时间(例如,0.5代表中午12点半)。
为了将儒略日转换成公历日期,我们需要使用以下公式:L = J + 68569N = (4L / 146097)L = L - (146097N + 3) / 4I = (4000(L+1))/1461001L = L - (1461I/4) + 31J = 80L/2447D = L - (2447J/80)L = J / 11M = J + 2 - 12LY = 100(I - 49) + L + M其中,L是一个中间变量,N是每400年有多少个闰年的修正项,I是每100年有多少个闰年的修正项,J是一个中间变量,D是日期,M是月份,Y是年份。
公历日期转儒略日公式:如果我们已知公历日期,想要将其转换成儒略日,则可以使用以下公式:J = (1461(Y+4800+(M-14)/12))/4+(367(M-2-12((M-14)/12)))/12 - (3((Y+4900+(M-14)/12)/100))/4 +D-32075其中,Y是年份,M是月份,D是日期,J是儒略日数。
以上就是儒略日与公历转换的公式,它们在天文学、地球科学和计算机科学等领域都有广泛应用。
儒略日 纪日体系

儒略日纪日体系第一节儒略日纪日体系《儒略历》是现行《公历》的前身,是古罗马执政官儒略凯撒于公元前46年颁布实行的,故以"儒略"命名。
儒略日则与《儒略历》不同,儒略日是一种连续递增的纪日体系。
儒略日取《儒略历》公元前4713年1月1日12时为起点顺数而下,每过1日加1,连续不断。
儒略日由十六世纪意大利学者斯卡里杰(1540年-1609年)于1582年创制。
目的是用来确定不同历法、纪元或纪年法所记录的各种历史事件之间所经过的时间。
目前已为世界各国普遍采用,认为用其记事、考证、历算等都有极高的准确性。
斯卡里杰是意大利语言学家兼历史学家、医师斯卡里杰的儿子。
他比较各文明古国创造的计时方法,研究校正各种历法的时间,于1582年提出了连续递增的计日体系,并以其父儒略的名字命名,称"儒略日"。
斯卡里杰取儒略日这种长期计数的周期为7980年。
算式为:7980=28×19×15。
其中数字"28"是儒略历所谓太阳周的年数。
经过一太阳周期,星期的日期便又回到了同一天。
数字"19"是太阳周的年数,即月相在太阳年中的某一日重复出现的周期。
数字"15"是一种指示周期,它起源于古罗马定期课程或政府征用的日程表。
斯卡里杰选择公元前4713年作为儒略日的纪元,是因为它在过去年代中是上述三个周期一同开始的最近一年。
取12时为一天的起点是1925年以前国际的通例。
从那年起才改为由子夜作为一天之始。
儒略日的纪日体系,虽号称从公元前4713年1月1日12时为起点顺数而下,每过1日加1,实际上于1582年前并没有做到。
虽称只计数自然天,不受年、月、季节的影响,但由上可知,儒略日的纪日体系仍与《儒略历》有着内在联系,这就是年的岁实是相同的。
《儒略历》历年长度为365.25日,大于回归年365.2422日,大约每128年多出一天。
儒略日与公历转换公式

儒略日与公历转换公式儒略日和公历是两种不同的时间计量方式,它们在历史上都曾被广泛使用。
儒略日是一种连续计数的时间系统,起始日为公元前4713年1月1日,而公历是一种以天、月和年为单位的时间系统。
在进行日期转换时,我们可以使用一些公式来帮助我们准确地将儒略日转换为公历或将公历转换为儒略日。
1. 儒略日转换为公历要将儒略日转换为公历日期,我们可以使用以下公式:L = JD + 68569N = 4 * L / 146097L = L - (146097 * N + 3) / 4I = 4000 * (L + 1) / 1461001L = L - 1461 * I / 4 + 31J = 80 * L / 2447D = L - 2447 * J / 80L = J / 11M = J + 2 - 12 * LY = 100 * (N - 49) + I + L其中,JD表示儒略日,Y表示公历的年份,M表示月份,D表示日期。
2. 公历转换为儒略日要将公历日期转换为儒略日,我们可以使用以下公式:Y = 公历年份M = 公历月份D = 公历日期如果M为1或2月,Y需要减去1,M需要加上12。
A = Y / 100B = A / 4C = 2 - A + BE = 365.25 * (Y + 4716)F = 30.6001 * (M + 1)JD = C + D + E + F - 1524.5其中,JD表示儒略日。
通过使用上述公式,我们可以将儒略日和公历之间进行精确的转换。
这些公式基于历史上对时间的精确测量和计算。
儒略日和公历的转换对于天文学家、历史学家和其他需要处理日期的人们来说都非常重要。
它们可以帮助我们在不同的时间系统之间进行准确的转换,以满足不同领域的需求。
总结起来,儒略日与公历转换公式是一种重要的工具,可以帮助我们在儒略日和公历之间进行准确的日期转换。
通过这些公式,我们可以方便地将儒略日转换为公历日期,或者将公历日期转换为儒略日,满足不同领域对时间计量的需求。
儒略日、公历年月日之间的转换以及儒略日的应用电子教案

一、作业要求编写程序实现以下任务:1.1由公历年月日化为儒略日1.2由儒略日转化为公历年月日1.3儒略日的应用1.3.1 计算两个日期间的间隔天数1.3.2 计算星期几1.3.3 计算年积日(DOY)1.3.4 由年积日计算年月日二、程序设计2.1 窗体设计2.2 代码实现2.2.1由公历年月日化为儒略日//由公历年月日转化为儒略日的函数public double GLToJD(double Y, double M, double D){double JDtime;JDtime = 367 * Y - Math.Truncate(7 * (Y + Math.Truncate((M + 9) / 12)) / 4) + Math.Truncate(275 * M / 9) + D + 1721013.5;return JDtime;}2.2.2由儒略日转化为公历年月日//由儒略日转化为公历年月日的函数public void JDToGL(double JDtime,out double Y,out double M,out double D){double a, b, c, d, e;a = Math.Truncate(JDtime + 0.5);b = a + 1537;c = Math.Truncate((b - 122.1) / 365.25);d = Math.Truncate(365.25 * c);e = Math.Truncate((b-d)/30.6001);D=b-d-Math.Truncate (30.6001*e)+JDtime+0.5- Convert.ToInt32(JDtime+0.5);M = e - 1 - Math.Truncate(e / 14) * 12;Y = c - 4715 - Math.Truncate((7 + M) / 10);}2.2.3 计算两个日期间的间隔天数private void JGTSbutton_Click(object sender, EventArgs e){double JDtime1, JDtime2,Y1,M1,D1,Y2,M2,D2,JGTS;if (Year31.Text == "" || Month31.Text == "" || Day31.Text == "" || Year31.Text == "" || Month31.Text == "" || Day31.Text == ""){MessageBox.Show("输入的日期不能为空!");}else{Y1 = double.Parse(Year31.Text);M1 = double.Parse(Month31.Text);D1 = double.Parse(Day31.Text);JDtime1 = GLToJD(Y1, M1, D1);Y2 = double.Parse(Year32.Text);M2 = double.Parse(Month32.Text);D2 = double.Parse(Day32.Text);JDtime2 = GLToJD(Y2, M2, D2);JGTS = Math.Abs(JDtime2 - JDtime1);JG.Text = JGTS.ToString();}}2.2.4 计算星期几private void XQbutton_Click(object sender, EventArgs e){double JDtime,Y,M,D, XQ;if (Year4.Text == "" || Month4.Text == "" || Day4.Text == "") {MessageBox.Show("输入的日期不能为空!");}else{Y = double.Parse(Year4.Text);M = double.Parse(Month4.Text);D = double.Parse(Day4.Text);JDtime = GLToJD(Y, M, D);XQ = (JDtime + 1.5) % 7;if (XQ == 0){weekDay.Text = "星期日";}if (XQ == 1){weekDay.Text = "星期一";}if (XQ == 2){weekDay.Text = "星期二";}if (XQ == 3){weekDay.Text = "星期三";}if (XQ == 4){weekDay.Text = "星期四";}if (XQ == 5){weekDay.Text = "星期五";}if (XQ == 6){weekDay.Text = "星期六";}}}2.2.5 计算年积日private void NJRbutton_Click(object sender, EventArgs e){double Y,M,D,JDtime1,JDtime2;if (Year5.Text == "" || Month5.Text == "" || Day5.Text == "") {MessageBox.Show("输入的日期不能为空!");}else{Y = double.Parse(Year5.Text);M = double.Parse(Month5.Text);D = double.Parse(Day5.Text);JDtime1 = GLToJD(Y,M-1,D);JDtime2 = GLToJD(Y,0,0 );NJR1.Text = (JDtime1-JDtime2).ToString();}}2.2.6 由年积日计算年月日private void NJRTONYRbutton_Click(object sender, EventArgs e){double JDtime, Y1, Y, M, D,NJR;if (Year6.Text == "" || NJR2.Text == "" ){MessageBox.Show("输入的日期不能为空!");}else{NJR = double.Parse(NJR2.Text);Y1 = double.Parse(Year6.Text);JDtime = GLToJD(Y1, 0, 0) + NJR+30;JDToGL(JDtime ,out Y,out M,out D);textBox1.Text = JDtime.ToString ();GLNYR.Text = Y.ToString() + "年" + M.ToString() + "月" + D.ToString() + "日"; }}2.3 运行结果。
时间转换--年积日-儒略日-GPS周

%start from Julian March 1, 4801 B.C. if( J < 2299160.5 ) % before 1582.10.4. 24:00 is Julian calender j0=floor(J+0.5); dd=J+0.5-j0; else % after 1582.10.15. 00:00 is Gregorian calender %number of certury years that are not leap year n1=floor((J-2342031.5)/36524.25/4)+1; %1700.3.1.0 n2=floor((J-2378555.5)/36524.25/4)+1; %1800.3.1.0 n3=floor((J-2415079.5)/36524.25/4)+1; %1900.3.1.0 j0=n1+n2+n3+J+10; dd=j0+0.5-floor(j0+0.5); j0=floor(j0+0.5); end
三、程序实现成果(具体代码见附件) 1. gps2cal 将 GPS 周和周内秒转换到公历时间
function cal=gps2cal(gpst) % gps2cal 将 GPS 周和周内的秒转换到公历 GPS 时间 % cal=gps2cal(week,sec) 返回的公历是 1x6 矩阵,6 列分别为年月日时分秒 % gpst:1x2 矩阵,2 列分别为 GPS 周和周内的秒 % GPS 从 MJD44244 开始 mjd=44244+(gpst(1)*86400*7+gpst(2))/86400; cal=mjd2cal(mjd);
阳历、阴历、农历、夏历很多人都搞错弄混,到底有什么区别?

阳历、阴历、农历、夏历很多人都搞错弄混,到底有什么区别?阳历、阴历、农历、夏历,可以说很多人对这几个词的理解,都是模糊而片面的。
至今,还有很多人对阳历、阴历、夏历、农历等词的理解,还傻傻分不清,以至于闹出不少的笑话。
关于这几点内容,读书君查阅了不少的资料,下面,给大家具体来说说这其中几个词的具体所指和差别。
01 阳历阳历(也就是公历、西历、太阳历),这是全球多数国家通用的一种历法,由儒略历修订而成。
儒略历阳历最早的源头,可以追溯到古埃及的太阳历。
众所周知,尼罗河就像中国的黄河一样,它是埃及人的命根子,河流给埃及人带来了希望,同时也带来了灾难。
尼罗河每年都有泛滥周期,为此计算尼罗河泛滥周期,更好地安排农业生产,古埃及人根据尼罗河水的潮落和天狼星的位置变化,制定了太阳历,这是人类历史上第一部太阳历。
当时的古埃及人,将每一年一度的尼罗河泛滥的日子(大概是在6月15日前后),定为一年的开始,这一天,在古埃及恰好天狼星和太阳刚好出现在同一地平线上。
天狼星位置与体积当时,人们根据尼罗河水的潮落以及农作物的生长规律,将一年分为了泛滥、播种和收割三个季,每个季为4个月,一年共12个月,每个月30天,年末剩下的5天,叫“闰日”,如此下来,一年共有365天(这和如今我们以三个月为一季,四个季为一年的划分,多少有些区别)。
这种算法,比如今的阳历少了6个小时,所以大概间隔120年左右,就会多出大概一个月的时间。
如此推下去,大概是400多年后,就会周而复始。
具体来说,阳历这是一种以地球绕太阳运动作为根据的历法,以地球绕太阳一周(一回归年)为一年。
一回归年的长度是365.2422日,也就是365天5小时48分46秒,积累4年共有23小时15分4秒,大约等于一天,所以每4年增加1天,加在2月的末尾,得366天,就是闰年。
但是,4年加一天的话,实际回归年就多了44分56秒,积满128年左右,那么就会又多加了一天,也就是在400年中大概会多算了三天的时间。
儒略历和公历对照表

儒略历和公历对照表
儒略历和公历是两种历法,二者之间的差异主要在于历法计算的方式不同。
在本文中,我们将会详细了解这两种历法,并提供一份儒略历和公历对照表。
1. 儒略历
儒略历源于古罗马时期,是由朱利叶斯·凯撒于公元前45年颁布的。
此历法主要采用了太阳年的观点,并将一年分为三百六十五天,再加一个闰日。
2. 公历
公历源于16世纪的欧洲,由教皇格里高利十三世改进而来,于公元1582年正式使用。
此历法主要采用了太阳年、月相和潮汐的观点,并将一年分为三百六十五天,再加上一些闰日和闰秒。
3. 对照表
下面是儒略历和公历的对照表,其中包括了两种日期的对照:
儒略历日期公历日期
1月1日 1月1日
1月25日 2月14日
2月29日 3月1日
3月25日 4月4日
4月19日 5月1日
5月1日 5月13日
6月24日 7月4日
7月4日 7月15日
7月15日 7月26日
8月1日 8月13日
8月15日 8月27日
9月1日 9月13日
9月21日 10月3日
10月1日 10月13日
10月28日 11月9日
11月1日 11月13日
12月25日 12月25日
总之,在这个对照表的帮助下,我们可以轻松地将儒略历和公历之间的日期转换,并避免因为历法差异导致的不必要麻烦。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第 1 讲 公历和儒略日1. 时间的计量时间计量是天文计算的第一个基础.时间概念的发生,源于人类生活生产的需要.白 昼和黑夜交替,月圆和月缺轮换,炎夏和寒冬往复,自然界中这些周期发生的现象与人类的 生存息息相关,很自然地成为计时的依据,抽象出日,月和年的概念.把这些基本元素组织 成一个协调实用的计时系统,就产生了历法. 南京东郊风景如画的紫金山第三峰上,座 落着著名的紫金山天文台.台区内陈列着一组 堪称国宝级文物的古代天文仪器.其中一台高 3.56 米的仪器,由一具平卧的圭和一具竖立的 表组成,叫做圭表(图 1) .这是一种起源可以 追溯到远古时代的计时仪器.它依南北子午线 方向水平安置,根据正午时刻落在圭尺上的表 的影子的长度测定时间.表影所反映的太阳在 天球上每天一次经过南北子午圈的视运动,是 "太阳日"概念的来源.地球上每个人时时都 最直接地感受着这个天象.实际上它并不象我 们直观看到的那样单纯,而是稍许有点复杂, 它是地球绕轴自转和绕太阳公转两个运动合成 的反映.以太阳日为基本单位的计时系统,叫图 1 圭表,造于明代(1439 年)做世界时,简记为 UT1.天空中太阳相对于地面上南北子午圈的位置依赖于当地的地理经 度,时间的度量因而也与地理经度有关,不同地理经度的观测地有不同的时间,这就是地方 时.为了统一,规定世界时为本初子午线或零经度线上的地方时,这条经线经过英国伦敦的 格林尼治天文台,因此也叫做格林尼治时间. 比太阳的视运动简单一点的是遥远恒星每 天一次经过南北子午圈的视运动,它只是地球绕 轴自转一种运动的反映,与之相联系的概念是 "恒星日" .恒星日虽然单纯,却远离生活,因 而没有成为计时的基础.随着观测技术的发展和 观测精度的提高,到了 20 世纪,人们终于发现, 无论是地球的自转还是公转,都是不均匀的,都 不宜用作精密计时的尺度.从 1967 年开始,改 用原子振动的周期作为计时的尺度,规定铯原子 基态的两个超精细能级在零磁场下跃迁辐射振 荡 9,192,631,770 周所持续的时间为一个国际制 秒.时间计量从此与地球的运动脱钩,这样的时 间尺度叫做原子时,简记为 TAI.根据爱因斯坦 的广义相对论,时间的快慢与局部引力场有关. 在太阳系内,有两个处所是紧要的:一个是太阳 系质心,所有太阳系天体的运动都与它相联系; 一个是地球质心,包括地面观测者在内所有地球图 2 被天极周围恒星的周日运动1物体的运动都与它相联系. 这样就从原子时派生出两个时间系统: 以太阳系质心为参照的质 心力学时,简记为 TDB;以地球质心为参照的地球力学时,简记为 TT.这两个时间尺度差 别的主要部分的振幅为 1.7 毫秒,周期为一年,对于本书所讨论的问题,可以忽略不计.而 地球力学时与地面原子时的尺度是完全一样的,仅仅因为历史的原因两者的起点有 32.184 秒的差.两者间的转换公式是: TT = TAI + 32 .184 .s以更加稳定的原子时作为基准,世界时的不均匀性就显现了出来,经过积累会盈余或 短缺 1 秒,而且还有长期变慢的趋势.但世界时以地球的自转和公转运动为基础,既反映地 球在空间中的指向和方位,又符合人们千百年来的生活习惯,具有实际应用价值.为了协调 原子时和世界时两种不同的时间尺度,就产生了协调世界时 UTC,并且从 1979 年起成为世 界各国使用的正式时间标准.协调世界时的单位为国际制秒,但时刻保持与 UT1 一致.当 UTC 领先 UT1 0.8 秒时,增加一个闰秒;当 UTC 落后 UT1 0.8 秒时,减少一个闰秒.实施 闰秒的日期为 3 月 31 日,6 月 30 日,9 月 30 日和 12 月 31 日的最后一秒.这样,一日所含 的国际制秒数不再是常数 86400.闰秒的设置是由国际时间局(BIH)根据天文观测资料决 定和发布.2. 儒略历和格里历现在通用的公历是意大利医生兼哲学家里利乌斯(Aloysius Lilius,1510-1576)主持制 定,罗马教皇格里高利十三世(Gregory XIII)在 1582 年二月颁布实行的格里历.在此之前 通用的是儒略历, 这个历法是由埃及亚历山大的希腊数学家兼天文学家索西琴尼 (Sosigenes, 公元前一世纪)主持制定,罗马统治者盖厄斯·儒略·恺撒(Gaius Julius Caesar the Great, 约公元前 100—44 年)颁布,从公元前 46 年 1 月 1 日起实行的.这两种历法都是太阳历, 只考虑了太阳的周年视运动,不考虑月亮的视运动. 为了对太阳的视运动有个明确 的概念,我们先复习一下天球上有 关的点与线.当我们站在地球上某 处观测天象时,看到的只是日月星 辰在天空中的方位,它们似乎距离 我们同样遥远,镶嵌在那个叫做天 球的球面上,它们离开我们的远近 差别是无法直觉感受的.由于地球 的自转,整个天球都在自动向西地 转动,只有如图 2 所示的两个点是 不动的,他们就是天球的南北两 极.连接两极的直线就是叫做天轴 的转轴,垂直于天轴中分天球的大 圆是天球赤道,与赤道平行的圆周 是赤纬线.周日运动之外,恒星在 天球上没有容易察觉的其他运动,图 3. 春分点在天球上的位置似乎牢固地镶嵌在天球上.日月行星则不然,短期观测就能断定它们没有固定在天球上,而 是游走于恒星之间.如果用圭表逐日测量正午时刻表影的长度,就能发现它是变化的,这意2味着太阳每天正午在天空中的高度, 因而它的赤纬是变化的. 如果比较太阳和恒星从东方地 平升起或从西方地平落下的先后,就能发现太阳的赤经也是变化的.长期观测就可以确定, 太阳以一年为周期,沿着一个与赤道成 23.5 度倾角的大圆从西向东移动,这叫做太阳的周 年运动,而这个倾斜的大圆就是黄道.由于哥白尼(Nicolas Copernics,(1473-1543))的卓 越贡献,现在我们知道它们是地球绕太阳周年运动的反映.哥白尼之前人们的认识,却与我 们上面的直观大致相同. 黄道和赤道有两个交点, 太阳由天球南半球穿越赤道进入北半球的 那个交点叫做春分点; 另一个相反的交点就是秋分点. 太阳经过春分点的日子, 叫做春分日, 适逢北半球春耕生产的农忙季节, 自古就受到特别的重视, 春分点还被确定为天球上赤经起 算的原点.太阳周年视运动的周期,也就是太阳两次经过春分点的时间间隔叫做回归年,是 制定公历和农历历法的基本参数.现在采用的回归年长度的精确值是 365.24218968 日,即 365 日 5 小时 48 分钟 45.188 秒.此值每年缩短约 5.3 毫秒,换句话说,每一千年缩短约 5.3 秒.儒略历采用的回归年长度为 365.25 日,每世纪含 36525 日.取平年长为 365 日,闰年 长为 366 日.由于每 4 年含 1461 日,故需设一闰年.每世纪 25 个闰年,以公元年序数能被 4 整除的年份为闰年.但要注意公元前年序数的算法:公元前 1 年的年序数为 0,公元前 2 年的年序数为-1,等等.按照规则,公元前 5 年的年序数为-4,可被 4 整除,故为闰年. 儒略历的年长与精确值之差为0.00781日或11分钟14.8秒,因此太阳回到春分点的时刻每 年要提前11分钟14.8秒.公元前46年儒略历开始实行时,春分日在当年的3月23日(世界时, 下同) .公元325年召开第一次基督教主教尼塞(Nicée)会议时,春分日已经提前到了3月20 日.到1582年改历之时,这个差值已经积累到12.6996日,春分日提前到了3月10日.为了消 除这个差数,格里历颁布时规定1582年10月4日之后的那天为1582年10月15日,于是1583年 的春分日就回到了3月21日.按照这个规定,我们今天所说的公历系统,在1582年10月5之前 指的是儒略历,1582年10月14日之后,指的是格里历,而1582年10月5日至10月14日之间的 日期是不存在的.公元前46年之前,尽管儒略历还没有颁布, 格里历的年长为 365.2425 日,与精确值之差为 0.00031032 日或 26.8 秒,2700 年才会 积累起 1 日的误差.400 年含 146097 日,需要设 97 个闰年,比儒略历少 3 个.因此规定凡 年序数能被 100 整除而不能被 400 整除的年份仍为平年. 由于置闰的调节, 按格里历和世界 时计算的春分日,总在 3 月 20 日前后,有时会提前到 3 月 19 日,有时又会落后到 3 月 21 日. 进一步的说明: 下面一段的内容是为感兴趣的读者准备的,没有兴趣的读者可以跳过.回归年的长度 (中国天文年历) 365.24218968 - 0.0000000616(t - 2000) 日,t 为公元年序数.经简单 变 换 , 可 得 365.24231288 - 0.0000000616t , 格 里 历 年 长 与 回 归 年 长 之 差 为 0.00018712 - 0.0000000616t 日 . 积 分 这 个 式 子 , 即 可 得 到 格 里 历 的 平 均 误 差 :0.00018712t - 0.0000000308t 2 + C ,假定 1582 年时此差为零,求出常数 C = 0.37311 ,遂得差数为: 0.00018712t - 0.0000000308t 0.37311 日,不考虑日长本身的变化,到24298 年时,才会积累达到 1 日误差. 格里历月的设置继承了儒略历的规则.儒略历创立之时,将全年分为 12 个月,单数月 为大月,长 31 日,双数月为小月,长 30 日.只有 2 月的日数可变以调节平年和闰年,平 年长 29 日,闰年长 30 日.公元前 8 年,儒略·恺撒的继承人奥古斯都又从 2 月减去一日 加到 8 月使之成为大月,又把 9 月,11 月改为小月,10 月,12 月改为大月.这样 2 月的3日数成为平年 28 日,闰年 29 日.3. 儒略日从天文计算的角度,只要以日为单位连续计时就可以了,这就是儒略日.年月的设置更 多地是为了生活生产的需要,对于天文计算并不是必须的. 现在广泛使用的是法国学者史伽利日 (Joseph Justus Scaliger,1540-1609)提出的儒 略日系统.之所以叫做儒略日,与上面讲过的 儒略历并不相干,而是因为史伽利日的父亲, 意大利学者 Julius Caesar Scaliger (1484-1558) 与颁布实施儒略历的罗马统治者儒略·恺撒同 名. 系统以公元前 4713 年 1 月 1 日正午为起点, 向后连续计日,简记为 JD.积累到现在,已经 是一个很大的数字. 例如 2000 年 1 月 1 日地球 力学时 12 时的儒略日记法就是 JD 2451545.0, 这是一个很重要的时刻,特别记为 J2000.0.由 于儒略日数字位数太多,国际天文学联合会于 1973 年采用简化儒略日(MJD) ,其定义为 MJD = JD - 2400000.5. MJD 相应的起点是 1858 年 11 月 17 日世界时 0 时.图 4. 史伽利日读者要问,儒略日系统的历元为何选在公元前 4713 年 1 月 1 日正午?原来史伽利日构 造这个系统时考虑了三种周期:阳历日期与星期会合的 28 年(365.25×4×7 日)周期,阳 历与阴历会合的 19 年(29.53×(12×19+7)≈365.25×19=6939.75 日,这个数字等到我 们后面讲农历的时候再来解释)周期,以及罗马政府为征税登记财产的 15 年周期.取 3 者 的最小公倍数 7,980 年为儒略周期,然后向上推算,得到公元前 4713 年 1 月 1 日为这三个 周期同时开始的历元.换句话说,这一天既是公历元旦,又是农历初一和星期日,还是罗马 政府(假如有的话)登记财产的日子.这就是儒略日起算历元的由来. 儒略日的引入提出了两个需要解决的问题,就是怎样在公历年月日序数和儒略日序数之 间进行互换.下面先讨论如何由公历年月日序数 y, m, d 推算当天的儒略日序数 J ( y, m, d ) . 这个问题稍许有些难度,我们不妨后退一步,先把需要考虑的时间范围限制在一年之内,考 虑如何由月日序数 m, d 推算当天的积日 S ( m, d ) ,从中或许可以找到解决问题的思路.3.1.积日的计算一年里某日积日概念的引入,想法与儒略日的设立是一致的.即忽略月的存在,从年初 第一天起连续计日,直至年末的最后一天.只不过它的作用范围只限于一年之内,到了下一 年再重新开始计算,不像儒略周期那样长达 7,980 年.这样,年,特别是闰年的因素就不必 考虑了.1 月 1 日的积日为 1,12 月 31 日的积日平年时为 365,闰年时为 366. 积日的计算原本并无难处, 却由于 2 月的特殊情形而变得复杂了. 凯撒把闰月设在 2 月, 奥古斯都从 2 月减去一日,都缘于 2 月是古罗马处决死囚的凶月,颇具人道意味.但由于闰4月设在 2 月,2 月的日数变得不唯一,必须按平年和闰年加以调节,这就影响到以后十个月 份的积日也不唯一.设想一下,如果把闰月设在年末的最后一天,那么除了这一天之外,一 年中所有其他日子的积日数都是唯一不变的,包括每月 0 日的积日,问题就变得简单了. 但是,闰月在二月的设置尽管有不便之处,却不是随便可以更改的.我们最好换一个思 路考虑,能否在计算的过程中,把 3 月当作当年的第一个月,而把次年的 2 月当作当年的最 后一个月?只要把次年的 1 月和 2 月称为当年的 13 月和 14 月, 每年由 3—14 共十二个月组 成, 这样一来, 闰月落在了一年的最后一个月, 只要计算完毕后再恢复原来年月的归属关系, 困难就迎刃而解了. 这样安排之下,对于月序数为 m ,日序数为 d 的一天,对应的积日可以表示成:S (m, d ) = S 0 (m) + d(3 ≤ m ≤ 14, d ≤ 31)(1)式中 S 0 ( m) 是这个月 0 日的积日,叫做月首积日.日序数为 0 的日子原本是不存在的,引 入它只是为了计算的方便.由 4 月 1 日前推 1 天,就是 3 月 31 日,也就是 4 月 0 日,3 月 0 日应是上年 14 月的最后一天, 依上年是否闰年而分别是 14 月 29 日和 28 日, 其余依此类推. 月首积日的计算有下面的公式可用:S 0 (m) = Floor (30.6 * (m + 1)) 122(3 ≤ m ≤ 14)(2)公式中的符号 Floor 是实数向下取整运算, Floor (x) 代表不大于括号中实数 x 的最大整数, 数学书中常用 [ x] 表示. 我们这里由于接着要讲编程, 故直接借用了程序语言的表达式. (2) 式的正确性,读者可以自行验证.结合(1)(2)两式,就得到了计算积日的公式: ,S (m, d ) = Floor (30.6 * (m + 1)) + d 122(3 ≤ m ≤ 14, d ≤ 31)(3)以上的思考过程带给我们如下的启发:类似于求取积日的做法,如果我们能求出当年 3 月 0 日的儒略日 J 0 ( y ) ,那么当天的儒略日 J ( y, m, d ) 就可以表示成J ( y, m, d ) = J 0 ( y ) + S (m, d )问题归结为如何求取年首儒略日.(4)3. 2. 儒略日的计算从公元 1582 年 10 月 4 日往前,都按儒略历计算,从闰年后一年开始,到下一个闰年为 止,每 4 年一个周期,总日数是 1461.儒略日历元原本是公元前 4713 年 1 月 1 日正午,按 我们在上一小节中对于年月序数的约定,应改为公元前 4714 年 13 月 1 日世界时 12 时,但 这年是周期的第 4 年,这个周期应开始于公元前 4717(或-4716)年 3 月 1 日,这天 1.0 日 的儒略日是-1401.5.因此年首儒略日为 J 0 ( y ) = Floor (365.25 * ( y + 4716.0)) 1402.5 , 稍作简化得到:J 0 ( y ) = Floor (365.25 * y ) + 1721116.5( y ≤ 1582)(5)5此式中 Floor 函数的自变量可能是负值,因此不能用另一个类似的函数 Int 代替. Floor 是 向下取整, Int 是向零取整,两者对正实数的作用相同,对负实数的作用不同. 从公元 1582 年 10 月 15 日往后,要按格里历计算,这天的儒略日是 2299160.5.假定从 公元元年 3 月 1 日起都按格里历的规则置闰,则到公元 y 年时要比儒略历少置Floor ( y / 100.0) Floor ( y / 400.0) 个闰.但这个规则直到 1600 年才被实行,此前的 12个闰并没有设置,不应该减去;而实行格里历时跳过的 10 天又应该减去,由此得到格里历 年首儒略日:J 0 ( y ) = Floor (365.25 * y ) Floor ( y / 100.0) + Floor ( y / 400.0) + 1721118.5( y ≥ 1582)(5)(6)两式可以统一写成如下形式: ,(6)J 0 ( y ) = Floor (365.25 * y ) + w + 1721116.5其中(7)0 w= Floor ( y / 100.0) + Floor ( y / 400.0) + 2( y ≤ 1582) ( y ≥ 1582)(8)当 y = 1582 时, w 的具体取值尚需根据月日序数判断.以(3)(7)两式代入(4)式,得: ,J ( y, m, d ) = Floor (365.25 * y ) + Floor (30.6 * (m + 1)) + d + w + 1720994.5由给定的年月日序数求对应儒略日的问题至此完全解决.(9)3.3.儒略日计算的计算机语言实现上述算法可以用一个 Pascal 语言写成的函数实现. 为了便于今后应用, 我们把表示一个 特定时刻的年月日及日小数的数据组织成如下记录类型: type TYmd=record year,month,day:integer; fday:extended; end; 分量 year,month 和 day 是整型变量,表示年月日序数,fday 为十字节浮点数,表 示日的小数部分,通过适当的换算可以得到时分秒数据. 程序文本如下,为便于阅读增加了适当的注释. function DateToJd(t:TYmd):extended; var u, w:extended; begin// with 语句表明语句括号 begin…end 之间的 year,month,day 和 fday 等分量的 // 公共变量名为 t6with t do begin// u 为表示日期的变量,整数部分为年序数,十分位和百分位为月序数,千分位及以后各位 // 日数u:=year+(month+day/100.0)/100.0;// 变换年月序数,见 3.1 节if month<2.5then begin month:=month+12; year:=year-1; end; w:=0; if u>1582.1014 then begin// 按格里历计算 ww:=year/100.0; w:=-int(w)+int(w/4.0)+2;// 检查并处理不存在的日期end else if u>1582.1004 then showmessage('Error Date');// 计算儒略日u:=floor(365.25*year) +floor(30.6*(month+1)) + day +w +1720994.5;// 返回儒略日,包括日的小数Result:=u+fday; end; end; 函数带有一个刚刚说明的 TYmd 类型的入口参数 t,其分量就是待转换的年月日及日小 数.函数内使用了两个局部工作变量:w 用于存放(8)式定义的同名参数;u 在开始时存 放一个以实数表示的年月日量,用于判别使用那种历法,以及入口的日期是否存在.当入口 日期不存在时,弹出一个消息框发出警告,并且按儒略历计算.然后用于存放儒略日的主要 部分,计算完毕后返回儒略日.注意日小数分量 fday 不参加儒略日的计算,直到最后才加 上去.4. 由儒略日求年月日现在来解决 3.1 节问题的逆问题,由儒略日求年月序数和日数.仿照前面的做法,先退 一步, 解决较简单的问题: 如何由积日求月序数和日数?这个问题可以归结为: 已知方程 (3) 左边的量 S ,求变量 m 和 d 的解.把未知量移到左边,已知量移到右边,方程整理成:Floor (30.6 * (m + 1)) + d = S + 122(3 ≤ m ≤ 14, d ≤ 31)(10)在数学上可以证明,方程(10)有如下形式的解:S + 122 ) 1 m = Floor ( 30.6 d = S + 122 Floor (30.6 * (m + 1)) (11)解得的 d 有可能为零,这时该日是上月的最后一日,将 m 的值减 1,代入第二式重新计算 d7即可. 现在回到由儒略日求年月序数和日数的问题.它是方程(9)问题的逆问题.这个方程 可以写成:Flooar (365.25 * y ) + S = J w 1721116.5(1 ≤ S ≤ 365)(12)问题归结为:已知方程(12)右边各量,求未知变量 y 和 S .按照求解方程(10)的同样 方法可得:J w 1721116.5 ) y = Flooar ( 365.25 S = J w + 1721116.5 Floor (365.25 * y ) (13)与方程(10)的情况相同,解得的 S 有可能为零,这时该日是上年的最后一日,将 y 的值 减 1,代入第二式重新计算 S 即可. 需要由儒略日 J 预先算出. 最后剩下的一个问题是, 方程 (12) 右边的 w 现在还不知道, 由于 w 通过(8)式与 y 联系,而 y 通过(13)式与 w 联系,因此 w 可以和 y 一道迭代解出. 用迭代方法求解方程是算法设计的重要技巧,我们将一再使用.请读者给予足够的关注.算 法如下面的 Wannier 图所示:s := J 1721116.5; w := 0; y := 1500; 迭代计算 y和w y1 := y; 迭代计算 y := Floor (( s w) / 365.25); (1, N ) until y = y1 {w:=-Floor(year/ 100 )+Floor(year/ 400 )+2; (重新计算w5 0,1) if J ≥ 2299160. 先取 w = 0 , y = 1500 作为初值,然后开始迭代计算,这是一个循环结构,表示为:迭代计算 {循环体(1, N ) until y = y1记号 (1, N ) 表示循环, until y = y1 是结束循环的条件.循环体的内容见上图,先保存 y 的 当前值到 y1 以备后用,再计算 y .如果在格里历的适用范围内,就要按 y 的新值重新计算w ,然后重新计算 y ,如此反复,直到 y 的值不再改变. "重新计算 w "是一个选择结构,表示为:( 0 ,1) if J ≥ 2299160.5可选操作 重新计算w {记号 (0,1) 表示选择, if J ≥ 2299160.5 是选择条件,儒略日 2299160.5 对应于 1582 年 10 月 15 日,这个条件给出了格里历的适用范围.8至此可以把儒略日求年月日的算法表示如图 5:分离日的小数部分送入分量fday 迭代计算年序数y和参数w 计算积日数S { S := S w; y := y 1; 重新计算y和S ( 0 ,1) if S = 0 按y的新值计算S 按(11)式计算月序数m和日数d m := m 1; 重新计算m和d ( 0 ,1) if d = 0 按m的新值计算d 图 5. 由儒略日求年月日算法的 Wanier 图 第一个操作是分离日的小数部分.目的是先分离出日小数送入分量 fday ,而把待处理 的儒略日规格化为小数部分是 0.5 的格式,这样它对应的日期就是世界时零时,而 fday 则 是一个小于 1 的正数.随后的两个选择结构,分别对应于积日 S = 0 和日期 d = 0 的情形, 也就是年首和月首的情形,这时需分别修改年序数和月序数,并重新计算积日和日期. 下面是用 Pascal 语言写成的实现由儒略日求年月日算法的函数: function JdToDate(jd:extended):TYmd; var w,s,d:extended; y1:integer; t:TYmd; begin with t do begin// 分离出日的小数部分,儒略日的小数部分为 0.5w:=Floor(jd)+0.5;// 调整日小数非负fday:=jd-w; if fday<0.0 then begin fday:=fday+1.0; w:=w-1.0; end;// 迭代计算 y 和 ws:=w-1721116.5; w:=0; year:=Floor(s/365.25); repeat y1:=year;9if jd>=2299160.5 then w:=-Floor(year/100)+Floor(year/400)+2; year:=Floor((s-w)/365.25); until year=y1; s:=s-w;// 暂时保存 sw:=s;// 积日s:=s-Floor(365.25*year); if s=0 then begin year:=year-1; s:=w-Floor(365.25*year); end; s:=s+122; month:=Floor(s/30.6)-1; d:=s-Floor(30.6*(month+1)); if d=0 then begin month:=month-1; d:=s-Floor(30.6*(month+1)); end;// 分离日和日的小数部分w:=d+fday; day:=Floor(w); fday:=w-day;// 化为自然年月序数if month>12 then begin month:=month-12;year:=year+1; end; end; Result:=t;end; 进一步的说明: 我们在第 4 小节中未加证明地给出了方程(10)的解(11) ,对数学有兴趣的读者可能 会有不足之感.为免此缺憾,特以引理的形式给出简短证明.对数学推导没有兴趣的读者尽 可跳过不看. 引理:如果Floor ( pN ) + M = K方程中 N , M , K 是整数, p 是实数,且满足 p > M ≥ 1 ,则有:(14)N = Floor ( K / p )(15)证明:根据 Floor 函数的定义,由(14)式,存在实数 0 ≤ δ < 1 使pN = K M + δ ,10即 p M p K N δ−−=, 另一方面,由所给条件有:110<≤<≤p M p p δ,即10<−<pM δ,引理由此得证。