Skip to content

Instantly share code, notes, and snippets.

@miklb
Created July 1, 2015 07:12
Show Gist options
  • Save miklb/ed145757971096565723 to your computer and use it in GitHub Desktop.
Save miklb/ed145757971096565723 to your computer and use it in GitHub Desktop.
Calculate Lunar Phase
#!/usr/bin/env python
"""
moonphase.py - Calculate Lunar Phase
Author: Sean B. Palmer, inamidst.com
Cf. http://en.wikipedia.org/wiki/Lunar_phase#Lunar_phase_calculation
"""
import math, decimal, datetime
dec = decimal.Decimal
def position(now=None):
if now is None:
now = datetime.datetime.now()
diff = now - datetime.datetime(2001, 1, 1)
days = dec(diff.days) + (dec(diff.seconds) / dec(86400))
lunations = dec("0.20439731") + (days * dec("0.03386319269"))
return lunations % dec(1)
def phase(pos):
index = (pos * dec(8)) + dec("0.5")
index = math.floor(index)
return {
0: "New Moon",
1: "Waxing Crescent",
2: "First Quarter",
3: "Waxing Gibbous",
4: "Full Moon",
5: "Waning Gibbous",
6: "Last Quarter",
7: "Waning Crescent"
}[int(index) & 7]
def main():
pos = position()
phasename = phase(pos)
roundedpos = round(float(pos), 3)
print "%s (%s)" % (phasename, roundedpos)
if __name__=="__main__":
main()
@miklb
Copy link
Author

miklb commented Sep 9, 2021

Actually I believe roundedpos is your lunation %. I get .09 for today which seems ~.01 accurate

I added print(f"{pos: .2%}" + " illuminated") after the current print

6F986A32-0066-467E-967E-616821A24B22

@cbronner35
Copy link

Perfect!!! Thanks so much that's exactly what I needed! Your amazing! I appreciate it :)

@cbronner35
Copy link

You know actually I'm not super sure its very accurate. I just printed around 12.4 % but according to this site https://www.timeanddate.com/astronomy/@4313572 for our area its 16.1 percent. Any idea why I have such a disconnect between these two?

@miklb
Copy link
Author

miklb commented Sep 10, 2021

My tide app tells me it’s 28% waxing. I believe there are a few different formulas for calculating lunation. All use some fixed time from the past to calculate from. I suppose if you need accuracy to the 1°, a different formula may be required. If you find one I’d be happy to help implement in this script.

@miklb
Copy link
Author

miklb commented Sep 11, 2021

You could always go a different route & make an api call to get the reported lunation. That could also get you visibility for closest weather station and any other details you might need. If worried about connectivity, store it in LocalStorage in the browser. I’m not sure how you are using the script though.

@sbp
Copy link

sbp commented Jun 17, 2024

Hi, original author here. The equation that I used was originally posted to Wikipedia by an author named "Monsieur le docteur Ralph" in March 2005. The magic values that I used were from that equation. Later, on the talk page for that article where they discuss removing the equation, they also discussed some potentially more accurate alternatives.

I posted the above code to my own website as moonphase.py, which has a Last-Modified date of 30 November 2005. I've been hosting it for nearly two decades on that site! I'm glad that people are finding the script useful. I and my friends use it in an IRC bot called saxo which I wrote about a decade ago to replace another one which I'd written a decade previously, roughly contemporaneous with moonphase.py.

If anybody comes up with an improved version of this script, with greater accuracy or ported to another language such a Go or Rust, please post the code or link to the code on this thread, and please send me a message. You can contact me on GitHub at @sbp, leave a message on my Wikipedia user talk page, or use whatever email address du jour I've got listed on my homepage.

@miklb
Copy link
Author

miklb commented Jun 18, 2024

@sbp howdy! I did leave credit in the script and I honestly don't remember where I came across it or why I originally shared it. I posted this gist 9 years ago! Thanks for pointing folks to the original source and offering support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment