Moon Phase at a given date (Python)

vegaseat 2 Tallied Votes 6K Views Share

For those who are afraid of lycanthropes and full moons, here is a way to figure out the phase of the moon.

''' moon_phases.py
determine the moon phase at a given date
(mildly off on moon's light intensity)
checked with http://aa.usno.navy.mil/data/docs/RS_OneDay.html

tested with Python274 and Python331  by  vegaseat  02may2013
'''

def moon_phase(month, day, year):
    ages = [18, 0, 11, 22, 3, 14, 25, 6, 17, 28, 9, 20, 1, 12, 23, 4, 15, 26, 7]
    offsets = [-1, 1, 0, 1, 2, 3, 4, 5, 7, 7, 9, 9]
    description = ["new (totally dark)",
      "waxing crescent (increasing to full)",
      "in its first quarter (increasing to full)",
      "waxing gibbous (increasing to full)",
      "full (full light)",
      "waning gibbous (decreasing from full)",
      "in its last quarter (decreasing from full)",
      "waning crescent (decreasing from full)"]
    months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
              "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

    if day == 31:
        day = 1
    days_into_phase = ((ages[(year + 1) % 19] +
                        ((day + offsets[month-1]) % 30) +
                        (year < 1900)) % 30)
    index = int((days_into_phase + 2) * 16/59.0)
    #print(index)  # test
    if index > 7:
        index = 7
    status = description[index]

    # light should be 100% 15 days into phase
    light = int(2 * days_into_phase * 100/29)
    if light > 100:
        light = abs(light - 200);
    date = "%d%s%d" % (day, months[month-1], year)

    return date, status, light


# put in a date you want ...
# 26jan2009 is the start of the Chinese New Year for 2009
# the moon is at its lowest intensity
month = 1
day = 26
year = 2009  # use yyyy format

date, status, light = moon_phase(month, day, year)
print("moon phase on %s is %s, light = %d%s" % (date, status, light, '%'))

''' result ...
moon phase on 26Jan2009 is waning crescent (decreasing from full), light = 0%
'''
zjtpjs4 0 Newbie Poster

Hey, this is pretty cool! I just tested it and it sounds about right, though I'll have to take a look at the sky tonight. Its funny, 'cause I've also googled this, and heaps of websites can not agree on what the phase is. Half of them say waning cresent, the other half say last quater (your program says that)

Sichen 0 Newbie Poster

what an atrocious code this is, you should improve your coding skills and learn to use variables and comment to indicate what you are doing, btw i still cant figure out the days_to_phase+2 part is doing in your index and i am pretty sure your code is only correct for one month out of every two month

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.