Help us understand the problem. What is going on with this article?

ユリウス日とグレゴリウス暦日付との間の換算

こんにちは。
グレゴリウス暦日付 Gregorian calendar date $(year, month, day) $ と、修正ユリウス日(MJD)や Julian day number (JDN) との間の換算を計算してみました。下記のような変換計算の流れです。計算式については Wikipedia のユリウス通日#西暦からの換算 (Julian day#Calculation) そのままです1 2 3

(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()

  1. またこの DELTA_N_MJD の Gregorian and Julian calendars の差 2 は、両暦の一致期間を西暦200年3月1日から100年間とすることから来ていて(西暦元年ではなく)、これは春分の日を3月21日に定めるとした西暦325年のニケーア宗教会議から来ています。 

  2. この値は1858年11月17日正子UT(jd=2400000.5)をMJD元期としていることからです(1858.680356 * 365.25 = 678883.000)。 

  3. なお、$(y, m, d) \leftrightarrow n$ の計算部分に表れていますが、一月平均日数が 30.6 (=153/5) 日、4年分の日数が 1461 日、グレゴリウス暦400年分の日数が 146097 日です。 

kkdd
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした