在天文上的算法计算需要用到时间变量时,一般不会使用世界通行的公历。因为现行历法的时间体系包含了三个“变量”-----年,月,日。如果使用这三个量去计算时间则大大增加了算法的复杂性。而解决的办法就如同UNIX时间一样,把时间用一个数去表示,也就是儒略日(Julian Date,JD)。

儒略日的起点订在西元前4713年(天文学上记为 -4712年)1月1日格林威治时间平午(世界时12:00),即JD 0指定为UT时间B.C.4713年1月1日12:00到UC时间B.C.4713年1月2日12:00的24小时。每一天赋予了一个唯一的数字,顺数而下,如:1996年1月1日12:00:00的儒略日是2450084。这个日期是考虑了太阳、月亮的轨道运行周期,以及当时收税的间隔而订出来的。

上述文字是维基百科中对儒略日简单的介绍。通俗的说,就是从-4712年1月1日开始到现在所经历的天数。同时应当注意的是,对于公元1年之前的年份如何计数,天文学家同历史学家并不一致。在天文计算中,“公元前”的年份以天文方法计数。这样,+1年的前一年为0年,再之前才是-1年。所以历史学家所说的公元前585年实际上是-584年。

儒略日的计算

下面的方法对正数年和负数年都是有效的,负的儒略日数除外。

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


注意:格里高利历的启用时间为1582年10月4日,但当时有些国家仍然采用儒略历,更为具体的历史情况请参考维基百科儒略历公历 注意:此算法中,对于INT(),仅表示取数字的整数位,即:INT(5.6)=5 INT(-5.6)=-5 对于某些程序语言的取整函数,应注意负数时返回的应当是其整数部分而不是小于等于这个数的最大整数。 式中取30.6001而不是30.6的原因是为了防止某些计算机出现 5x30.6=152.999 9998 而造成取整错误(int(152.999 9998)=152 而实际应为153)。 PHP代码 ``` php function JDEcalc($year,$month,$day) { if ($month == 1 || $month == 2) { $year --; $month + = 12; } $temp=$year.'-'.$month.'-'.floor($day); if ( $temp<= '1582-10-04') { $B = 0; #ASCII比较 }else{ $A = intval($year / 100); $B = 2 - $A + intval($A / 4); } $result=floor(365.25 * ($year + 4716)) + floor(30.6001 * ($month + 1)) + $day + $B - 1524.5; return $result; } ```

儒略日反推

下面的方法对正数年和负数年都是有效的,负儒略日数除外。 将JD加上0.5,令 Z 为其整数部分,F 为小数部分。 若 Z < 2299161,取A = ZZ>=2299161,计算α=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则为: d = B - D - INT(30.6001*E) + F 月份m为: IF E < 14 THEN m = E – 1; IF E=14 or E=15 THEN m = E – 13 年份为yIF 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日。  
算法来源:《天文算法》 参考资料:  维基百科