今天讲的日期是公历日期,农历日期由于涉及到朔望月等较为高深的内容,暂时已经超出了本人的能力范围,故先不探讨。
现行的公历随月份及年份天数不同,如何计算两个日期之间相隔多少天?
这里,介绍一种天文上常用的儒略日,并介绍儒略日与公历的相互转换方法,附上相应的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语言写成。
| 12
 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));
 
 }
 
 | 
使用方法
| 12
 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)
 
 
 
 
 
 
 |