[PYTHON] Conversion entre le jour Julius et la date du calendrier Gregorius

Bonjour. J'ai calculé la conversion entre la date du calendrier grégorien $ (année, mois, jour) $ et le jour julien modifié (MJD) ou le numéro de jour julien (JDN). Le déroulement du calcul de conversion est le suivant. Pour la formule de calcul, voir [Julius commuting #Conversion from the Western calendar](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) (Jour julien #Calculation) Tel qu'il est [^ 1] [^ 2] [^ 3].

[^ 1]: De plus, la différence entre les calendriers grégorien et julien de ce DELTA_N_MJD``` est que la période de correspondance des deux calendriers est de 100 ans à partir du 1er mars 200 après JC. À venir (pas la première année de l'ère chrétienne), cela vient du Conseil religieux de Nikea en 325 après JC, qui a fixé le jour du printemps le 21 mars. [^ 2]: Cette valeur est due au fait que Masako UT ( jd = 2400000.5 '') le 17 novembre 1858 est la première période MJD ( `` `1858.680356 * 365.25 = 678883.000 ''). [^ 3]: De plus, bien qu'il apparaisse dans la partie calcul de $ (y, m, d) \ leftrightarrow n $, le nombre moyen de jours par mois est de 30,6 (= 153/5) jours et le nombre de jours pour 4 ans est de 1461 jours. , Le nombre de jours pour 400 ans du calendrier Gregorius est de 146097 jours.

(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

Conversion entre le jour Julius et la date du calendrier Gregorius
Date du calendrier Gregorius modifiée par rapport à la date de Julius
Conversion mutuelle entre la date et les jours écoulés depuis le 1er janvier 2000
Conversion entre unixtime et datetime
Conversion entre mots singuliers et pluriels
Conversion mutuelle entre l'article Qiita et le notebook Jupyter
[Python] Mémo de conversion entre les données temporelles et les données numériques
Méthode de conversion entre le calendrier occidental et le calendrier japonais
Conversion en virgule fixe et binaire
Conversion mutuelle entre JSON et YAML / TOML en Python