今天讲的日期是公历日期,农历日期由于涉及到朔望月等较为高深的内容,暂时已经超出了本人的能力范围,故先不探讨。
现行的公历随月份及年份天数不同,如何计算两个日期之间相隔多少天?
这里,介绍一种天文上常用的儒略日,并介绍儒略日与公历的相互转换方法,附上相应的R语言程序。
儒略日是天文上常用的一种计时方法,从公元前4713年1月1日格林尼治平太阳间正午12点开始,每增加一天,儒略日增加1,一直向下累加。(以下内容改写自维基百科)
儒略日是法国学者Joseph Justus Scliger(1540-1609)为纪念他的父亲Julius Caesar Scaliger(1484-1558)在1583年提出来的。
儒略日的起点确定考虑了太阳、月亮的运行周期,以及古罗马税收的间隔。
Joseph Scliger定义儒略周期为7980年,是因28、19、15的最小公倍数,28×19×15=7980。
其中:
28年为一太阳周期(solar cycle),经过一太阳周期,则星期的日序与月的日序会重复。
19年为一太阴周期,或称默冬章(Metonic cycle),因235朔望月=19回归年,经过一太阴周期则阴历月年的日序重复。
15年为一小纪(indiction cycle),此为罗马皇帝君士坦丁(Constantine)所颁,每15年评定财产价值以供课税,是古罗马用的一个纪元单位,故以7980年为一儒略周期,而所选的起点公元前4713年,则是这三个循环周期同时开始的最近年份。
在中国科学院紫金山天文台编纂的《中国天文年历》上,有相应年份逐日的儒略日表,可供参考。
还是回到原来的问题,如何计算公历中两个日期相差的天数?办法之一,就是将二者都转换成儒略日,计算其差值。实际上,天文学家也是依靠儒略日来计算天体动态的。
下面是已知日期计算儒略日和已知儒略日计算日期的方法。用R语言写成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
date2jd <- function(y,m,d){ n=0 G=0 if(y*372+m*31+floor(d)>=588829){ G=1 } if(m<=2) { m = m +12 y = y -1 }
if(G) { n=floor(y/100) n=2-n+floor(n/4) }
res <- floor(365.25*(y+4716)) + floor(30.6001*(m+1)) + d + n - 1524.5 return(res) }
jd2date <- function(jd){ jdate2vect <- function(xxx){ year = xxx[[1]] month = xxx[[2]] day <- xxx[[3]] frac <- xxx[[6]]/(60*60*24)+xxx[[5]]/(60*24)+xxx[[4]]/24 day.dec <- day + frac res <- c(year, month, day.dec) names(res) <- c("Year","Month","Day") return(res) }
D = floor(jd+0.5) F= jd+0.5-D if(D>=2299161) { c = floor((D-1867216.25)/36524.25) D = D + 1+c-floor(c/4); }
D = D + 1524; r.Y = floor((D-122.1)/365.25); D = D - floor(365.25*r.Y); r.M = floor(D/30.601); D = D- floor(30.601*r.M); r.D = D;
if(r.M>13){ r.M=r.M - 13 r.Y=r.Y - 4715; }else{ r.M =r.M - 1 r.Y = r.Y- 4716 } F= F*24; r.h=floor(F); F= F -r.h; F = F * 60; r.m=floor(F); F= F - r.m; F = F * 60; r.s=F; res <- list(r.Y, r.M, r.D, r.h, r.m, round(r.s,2)) names(res) <- c("Year","Month","Day","Hour","Minute","Second") return(jdate2vect(res));
}
|
使用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
date2jd(2010,9,21) - date2jd(1980,1,1)
date2jd(2035,9,2) - date2jd(2010,9,21)
date2jd(2010,9,21) - date2jd(1776,7,4)
date2jd(2010,9,21) - date2jd(-841,1,1)
jd2date(2455230.5)
|