Hello. I calculated the conversion between the Gregorian calendar date $ (year, month, day) $ and the modified Julian day (MJD) or Julian day number (JDN). The flow of conversion calculation is as follows. For the calculation formula, see [Julian Day #Conversion from the Christian era] on Wikipedia (https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%AA%E3%82%A6%E3%] 82% B9% E9% 80% 9A% E6% 97% A5 # .E8.A5.BF.E6.9A.A6.E3.81.8B.E3.82.89.E3.81.AE.E6.8F.9B. E7.AE.97) (Julian day #Calculation) As it is [^ 1] [^ 2] [^ 3].
[^ 1]: Also, the difference between Gregorian and Julian calendars of this DELTA_N_MJD
is that the matching period of both calendars is 100 years from March 1, 200 AD. Coming (not the first year of the Christian era), this comes from the Nikea Religious Council in 325 AD, which set the vernal equinox day on March 21st.
[^ 2]: This value is because Masako UT ( `jd = 2400000.5```) on November 17, 1858 is the epoch of MJD (
`1858.680356 * 365.25 = 678883.000```).
[^ 3]: In addition, although it appears in the calculation part of $ (y, m, d) \ leftrightarrow n $, the average number of days per month is 30.6 (= 153/5) days, and the number of days for 4 years is 1461 days. , The number of days for 400 years of the Gregorian calendar is 146097 days.
(year, month, day) \leftrightarrow (y, m, d) \leftrightarrow n \leftrightarrow mjd \leftrightarrow jdn
$ ./date.py --test
True: ymd2n(0,0,0) == 0
True: date2ymd(0,3,1) == (0,0,0)
True: date2mjd(1858, 11, 17) == 0
date.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
# n: the continuous count of days since March first in 1 B.C. proleptic Gregorian
# date = (year, month, day) in the proleptic Gregorian calendar
# ymd = (y, m, d); modified date in the proleptic Gregorian calendar (see date2ymd() below)
DELTA_N_MJD = {"Julian": 678883, "Gregorian": 678881} # calendars
def mjd2jdn(mjd):
return mjd + 2400001
def jdn2jd(jdn):
return jdn - 0.5 # 00:00:00
def n2mjd(n):
return n - DELTA_N_MJD["Gregorian"]
def mjd2n(mjd):
return mjd + DELTA_N_MJD["Gregorian"]
def date2mjd(year, month, day):
return n2mjd(date2n(year, month, day))
def mjd2date(mjd):
return ymd2date(*n2ymd(mjd2n(mjd)))
def diffdate(date1, date2):
return date2n(*date1) - date2n(*date2)
def adddate(date, d):
n = date2n(*date) + d
return ymd2date(n2ymd(n))
def date2n(year, month, day):
return ymd2n(*date2ymd(year, month, day))
def date2ymd(year, month, day):
y, m, d = year, month-3, day-1
if m < 0:
y, m = y-1, m%12
return y, m, d
def ymd2date(y,m,d):
year, month, day = y, m+3, d+1
if month > 12:
year, month = year+1, month%12
return year, month, day
def ymd2n(y,m,d):
n = d + (153*m+2)//5 + 365*y + y//4 # d + (306*m+4)//10 + (1461*y)//4
n += -(y//100) + y//400 # (-3*(y//100))//4 [Gregorian]
return n
def n2ymd(n):
a = 4*n + 3
a += 4*((3*((4*(n+1))//146097+1))//4) # [Gregorian]
y, b = a//1461, 5*((a%1461)//4) + 2
m, d = b//153, (b%153)//5
return y, m, d
def n2dayofweek(n):
dow = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
return dow[(n+3)%7] # [Gregorian]
#===== test =====
def test_eval(str):
print(eval(str), str)
return 0
def test_epoch():
test_eval('ymd2n(0,0,0) == 0')
test_eval('date2ymd(0,3,1) == (0,0,0)')
test_eval('date2mjd(1858, 11, 17) == 0')
return 0
def test_ymd2n():
for n in range(-146097,146097):
y,m,d = n2ymd(n)
if n != ymd2n(y,m,d):
year, month, day = ymd2date(y,m,d)
print(n,'', year, month, day, 'error')
break
return 0
def test_n2ymd():
m, d = 0, 0
for y in range(-401,400):
n = ymd2n(y,m,d)
if (y,m,d) != n2ymd(n):
year, month, day = ymd2date(y,m,d)
print(n,'', year, month, day, 'error')
break
return 0
def main():
"""
{f}: Conversion between modified Julian day number and Gregorian calendar date.
usage: {f} [-h] [--test]
options:
-h, --help show this help message and exit
--test test
"""
import docopt, textwrap
args = docopt.docopt(textwrap.dedent(main.__doc__.format(f=__file__)))
if args.get("--test", 0):
test_epoch()
test_ymd2n()
test_n2ymd()
return 0
if __name__ == '__main__':
main()
Recommended Posts