儒略日和公历
儒略日及公历的概念
- 儒略日:从公元前4713年1月1日正午12h开始的累计天数
- 公历:在1582年10月4日前使用儒略历(旧历),由于误差改为格力高历(新历),增加10天从1582年10月15日开始计算
修改原因
为了宗教事务上的方便,罗马教皇格雷果里十三世于公元1582年修改了儒略历。改历的内容有修正公元325年宗教会议以来所积累的10日的误差,格雷果里下令:这样,历史上就留下了10天空白。改历的内容有二个方面:一是使当时的春分回到3月21日,二是使以后的春分固定在3月21日。
详见知乎
公历转儒略日
旧历转儒略日
公式
y年m月d日的儒略日为JD=int(365.25*(y+4712))+int(30.61*(m+1))+d-63.5
要求日期在-4712年1月1日到1582年10月4日之间,并且当m=1,2时,要用(y-1,m+12,d)带入公式计算。
下面进行推导:
- 从-4712年1月1日到
y年1月1日前一天累计天数:
- 当
y为闰年,JD1=int(365.25*(y+4712)) - 当
y为平年,JD1=int(365.25*(y+4712))+1
- 从
y年1月1日到y年m月1日前一天累计天数:
注意到(对于平年)
m | 累计天数 | int(30.61*(m+1))-63 |
|---|---|---|
| 3 | 59 | 59 |
| 4 | 90 | 90 |
| 5 | 120 | 120 |
| 6 | 151 | 151 |
| 7 | 181 | 181 |
| 8 | 212 | 212 |
| 9 | 243 | 243 |
| 10 | 273 | 273 |
| 11 | 304 | 304 |
| 12 | 334 | 334 |
| 13(1月) | 365 | 365 |
| 14(2月) | 396 | 396 |
当m=1,2时,先把年份y减1,月份m加12再带入公式。
- 当
y为闰年,JD2=int(30.61*(m+1))-63+1 - 当
y为平年,JD2=int(30.61*(m+1))-63
- 从
y年m月1日到y年m月d日累计天数:JD3=d-1(d为小数,比如d=1.5代表2号12:00) - 综上并考虑到起算点是-4712年1月1日中午12h,要再减去半天:
JD=JD1+JD2+JD3-0.5=int(365.25*(y+4712))+int(30.61*(m+1))+d-63.5
新历转儒略日
公式
y年m月d日的儒略日为JD=int(365.25*(y+4712))+int(30.61*(m+1))+d-63.5+B
B=2-int(y/100)+int(y/400)
要求日期在1582年10月15日之后,并且当m=1,2时,要用(y-1,m+12,d)带入公式计算。
推导:
- 以旧历公式为基础进行修正,由于旧历每四年一闰改为新历的每百年不能被400整除就不闰,按照原公式计算会把1582年以后百年中不需要闰的年份也闰了,这一部分的天数为
B1=-int(y/100)+int(y/400),但是这个公式又把0年到1582年应该闰的部分整百年没有闰,这样又少闰了12年,补上这12天后B1=12-int(y/100)+int(y/400) - 由于从旧历到新历还直接空了10天,故
B2=-10 - 综上,修正项
B=B1+B2=2-int(y/100)+int(y/400)
儒略日转公历
转换代码
jd.py
py
def ymd2jd(y,m,d):
if m in [1,2]:
y = y - 1
m = m + 12
jd = int(365.25*(y+4712))+int(30.61*(m+1))+d-63.5
b = 0
if y > 1582 or (y == 1582 and m > 10) or (y == 1582 and m == 10 and d > 14):
b = 2 - int(y/100) + int(y/400)
return jd + b
def jd2ymd(jd):
re, jd = math.modf(jd + 0.5)
if jd >= 2299161: # 大于1582年10月15日
jd = jd + 10
a = int((jd - 2268993) / 36524.25) # 2268993为1500年3月1日的儒略日+0.5
jd = jd + a - int((a+3) / 4)
y = int(jd / 365.25) - 4712
Y = y
while True:
muYD = jd - int((y + 4712) * 365.25) - 1 # 除去年积日
if muYD >= 59:
m = int((muYD + 1 + 63) / 30.61) - 1
M = m - 12 if m > 12 else m
break
else:
y = y - 1
D = muYD - int(30.61 * (m + 1)) + 63 + 1
return Y, M, D + re1
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
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