moon_phase.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. """ Function for generating arbitrary moon jds based on a given date.
  2. Copyright (c) 2009, Colin Powell
  3. All rights reserved.
  4. Basic key
  5. 0 = 'New Moon'
  6. 1 = 'Waxing Crescent Moon'
  7. 2 = 'Quarter Moon'
  8. 3 = 'Waxing Gibbous Moon'
  9. 4 = 'Full Moon'
  10. 5 = 'Waning Gibbous Moon'
  11. 6 = 'Last Quarter Moon'
  12. 7 = 'Waning Crescent'
  13. Trig key
  14. 0 = New
  15. 4 = Waxing crecent
  16. 8 = Quarter
  17. 15 = Full
  18. 20 = Wanning gibbous
  19. 24 = Last Quarter
  20. 29 = New
  21. """
  22. import math
  23. from datetime import datetime
  24. def moon_phase(date):
  25. """ Returns a percentage representing the state of the moon on a given date
  26. """
  27. date = datetime.strptime(date, "%Y-%m-%d")
  28. if date.month < 3:
  29. year = date.year - 1
  30. month = date.month + 12
  31. else:
  32. year = date.year
  33. month = date.month
  34. month += 1
  35. jd = (365.25 * year) + (30.6 * month) + (date.day - 694039.09)
  36. jd /= 29.53058868
  37. b = int(jd)
  38. jd -= b
  39. # if jd < 4:
  40. # b=4-jd
  41. # else:
  42. # b=8-jd
  43. b = jd * 8 + 0.5
  44. if b == 8:
  45. b = 0
  46. return b
  47. def jdn(date):
  48. a = (14 - date.month) // 12
  49. y = date.year + 4800 - a
  50. m = date.month + (12 * a) - 3
  51. p = date.day + (((153 * m) + 2) // 5) + (365 * y)
  52. q = (y // 4) - (y // 100) + (y // 400) - 32045
  53. return p + q
  54. def moon_phase_accurate_but_broken(date):
  55. n = math.floor(12.37 * (date.year - 1900 + ((1.0 + date.month - 0.5) / 12.0)))
  56. RAD = 3.14159265 / 180.0
  57. t = n / 1236.85
  58. t2 = t * t
  59. ase = 359.2242 + 29.105356 * n
  60. am = 306.0253 + 385.816918 * n + 0.010730 * t2
  61. xtra = 0.75933 + 1.53058868 * n + ((1.178e-4) - (1.55e-7) * t) * t2
  62. xtra += (0.1734 - 3.93e-4 * t) * math.sin(RAD * ase) - 0.4068 * math.sin(RAD * am)
  63. if xtra > 0.0:
  64. i = math.floor(xtra)
  65. else:
  66. i = math.ceil(xtra - 1.0)
  67. j1 = jdn(date)
  68. jd = (2415020 + 28 * n) + i
  69. p = (j1 - jd + 30) % 30
  70. if p < 14.5:
  71. p = 14.5 - p
  72. else:
  73. p = 29 - p
  74. return p / 14.5