72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
# Copyright (c) 2011-2022, Manfred Moitzi
|
|
# License: MIT License
|
|
from __future__ import annotations
|
|
from math import floor
|
|
from datetime import datetime
|
|
|
|
|
|
def frac(number: float) -> float:
|
|
return number - floor(number)
|
|
|
|
|
|
class JulianDate:
|
|
def __init__(self, date: datetime):
|
|
self.date = date
|
|
self.result: float = self.julian_date() + self.fractional_day()
|
|
|
|
def fractional_day(self) -> float:
|
|
seconds = (
|
|
self.date.hour * 3600.0 + self.date.minute * 60.0 + self.date.second
|
|
)
|
|
return seconds / 86400.0
|
|
|
|
def julian_date(self) -> float:
|
|
y = self.date.year + (float(self.date.month) - 2.85) / 12.0
|
|
A = floor(367.0 * y) - 1.75 * floor(y) + self.date.day
|
|
B = floor(A) - 0.75 * floor(y / 100.0)
|
|
return floor(B) + 1721115.0
|
|
|
|
|
|
class CalendarDate:
|
|
def __init__(self, juliandate: float):
|
|
self.jdate = juliandate
|
|
year, month, day = self.get_date()
|
|
hour, minute, second = frac2time(self.jdate)
|
|
self.result = datetime(year, month, day, hour, minute, second)
|
|
|
|
def get_date(self) -> tuple[int, int, int]:
|
|
Z = floor(self.jdate)
|
|
|
|
if Z < 2299161:
|
|
A = Z # julian calendar
|
|
else:
|
|
g = floor((Z - 1867216.25) / 36524.25) # gregorian calendar
|
|
A = Z + 1 + g - floor(g / 4.0)
|
|
|
|
B = A + 1524.
|
|
C = floor((B - 122.1) / 365.25)
|
|
D = floor(365.25 * C)
|
|
E = floor((B - D) / 30.6001)
|
|
|
|
day = B - D - floor(30.6001 * E)
|
|
month = E - 1 if E < 14 else E - 13
|
|
year = C - 4716 if month > 2 else C - 4715
|
|
return int(year), int(month), int(day)
|
|
|
|
|
|
def frac2time(jdate) -> tuple[int, int, int]:
|
|
seconds = int(frac(jdate) * 86400.0)
|
|
hour = int(seconds / 3600)
|
|
seconds = seconds % 3600
|
|
minute = int(seconds / 60)
|
|
second = seconds % 60
|
|
return hour, minute, second
|
|
|
|
|
|
def juliandate(date: datetime) -> float:
|
|
return JulianDate(date).result
|
|
|
|
|
|
def calendardate(juliandate: float) -> datetime:
|
|
return CalendarDate(juliandate).result
|