juliandate.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # Purpose: julian date
  2. # Created: 21.03.2011
  3. # Copyright (c) 2011-2018, Manfred Moitzi
  4. # License: MIT License
  5. from typing import Tuple
  6. from math import floor
  7. from datetime import datetime
  8. def frac(number: float) -> float:
  9. return number - floor(number)
  10. class JulianDate:
  11. def __init__(self, date: datetime):
  12. self.date = date
  13. self.result = self.julian_date() + self.fractional_day() # type: float
  14. def fractional_day(self) -> float:
  15. seconds = self.date.hour * 3600. + self.date.minute * 60. + self.date.second
  16. return seconds / 86400.
  17. def julian_date(self) -> float:
  18. y = self.date.year + (float(self.date.month) - 2.85) / 12.
  19. A = floor(367. * y) - 1.75 * floor(y) + self.date.day
  20. B = floor(A) - 0.75 * floor(y / 100.)
  21. return floor(B) + 1721115.
  22. class CalendarDate:
  23. def __init__(self, juliandate: float):
  24. self.jdate = juliandate
  25. year, month, day = self.get_date()
  26. hour, minute, second = frac2time(self.jdate)
  27. self.result = datetime(year, month, day, hour, minute, second)
  28. def get_date(self) -> Tuple[int, int, int]:
  29. Z = floor(self.jdate)
  30. if Z < 2299161:
  31. A = Z # julian calendar
  32. else:
  33. g = floor((Z - 1867216.25) / 36524.25) # gregorian calendar
  34. A = Z + 1. + g - floor(g / 4.)
  35. B = A + 1524.
  36. C = floor((B - 122.1) / 365.25)
  37. D = floor(365.25 * C)
  38. E = floor((B - D) / 30.6001)
  39. day = B - D - floor(30.6001 * E)
  40. month = E - 1 if E < 14 else E - 13
  41. year = C - 4716 if month > 2 else C - 4715
  42. return int(year), int(month), int(day)
  43. def frac2time(jdate) -> Tuple[int, int, int]:
  44. seconds = int(frac(jdate) * 86400.)
  45. hour = int(seconds / 3600)
  46. seconds = seconds % 3600
  47. minute = int(seconds / 60)
  48. second = seconds % 60
  49. return hour, minute, second
  50. def juliandate(date: datetime) -> float:
  51. return JulianDate(date).result
  52. def calendardate(juliandate: float) -> datetime:
  53. return CalendarDate(juliandate).result