As part of a project to control the lights in a house, I have used some Energenie Remote Control Sockets and a RPi. I fitted the RPi with the Energenie Pi-mote Remote Control board. This allows the RPi to wirelessly turn on the sockets using the GPIO pins. To provide a night light, I needed to calculate sunrise and sunset from my GPS coordinates. Here is the code which might be useful. The time is returned as UTC.
#!/usr/bin/env python2.7
from datetime import date, timedelta, datetime, time, tzinfo
import math
def sinrad(deg):
return math.sin(deg * math.pi/180)
def cosrad(deg):
return math.cos(deg * math.pi/180)
def calculatetimefromjuliandate(jd):
jd=jd+.5
secs=int((jd-int(jd))*24*60*60+.5)
mins=int(secs/60)
hour=int(mins/60)
return time(hour, mins % 60, secs % 60)
def calcsunriseandsunset(dt):
a=math.floor((14-dt.month)/12)
y = dt.year+4800-a
m = dt.month+12*a -3
julian_date=dt.day+math.floor((153*m+2)/5)+365*y+math.floor(y/4)-math.floor(y/100)+math.floor(y/400)-32045
nstar= (julian_date - 2451545.0 - 0.0009)-(longitude/360)
n=round(nstar)
jstar = 2451545.0+0.0009+(longitude/360) + n
M=(357.5291+0.98560028*(jstar-2451545)) % 360
c=(1.9148*sinrad(M))+(0.0200*sinrad(2*M))+(0.0003*sinrad(3*M))
l=(M+102.9372+c+180) % 360
jtransit = jstar + (0.0053 * sinrad(M)) - (0.0069 * sinrad(2 * l))
delta=math.asin(sinrad(l) * sinrad(23.45))*180/math.pi
H = math.acos((sinrad(-0.83)-sinrad(latitude)*sinrad(delta))/(cosrad(latitude)*cosrad(delta)))*180/math.pi
jstarstar=2451545.0+0.0009+((H+longitude)/360)+n
jset=jstarstar+(0.0053*sinrad(M))-(0.0069*sinrad(2*l))
jrise=jtransit-(jset-jtransit)
return (calculatetimefromjuliandate(jrise), calculatetimefromjuliandate(jset))
longitude=LONGITUDE #West
latitude=LATITUDE #North
def main():
today=date.today()
rise,set = calcsunriseandsunset(today)
print rise, set
if __name__ == '__main__':
main()
The calculation was taken from Wikipedia with help from here
One thought on “Calculating Sunrise and Sunset in Python from GPS Coordinates”
Thank you for this piece of code. I have change to use only time module. I have done it to use it with the rest of my current project code. I also change it a bit to auto-correct to default system time zone and DST.
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
from time import mktime, localtime, gmtime
import math
def sinrad(deg):
return math.sin(deg * math.pi/180)
def cosrad(deg):
return math.cos(deg * math.pi/180)
def calculatetimefromjuliandate(jd,td,zone):
jd=jd+.5
secs=int((jd-int(jd))*24*60*60+.5)
mins=int(secs/60)
hour=int(mins/60)-zone
r_time=mktime((td[0], td[1], td[2],hour, mins % 60, secs % 60, td[6],td[7], -1))
return r_time
def calcsunriseandsunset(dt, tz):
a=math.floor((14-dt[1])/12)
y = dt[0]+4800-a
m = dt[1]+12*a -3
julian_date=dt[2]+math.floor((153*m+2)/5)+365*y+math.floor(y/4)-math.floor(y/100)+math.floor(y/400)-32045
nstar= (julian_date – 2451545.0 – 0.0009)-(longitude/360)
n=round(nstar)
jstar = 2451545.0+0.0009+(longitude/360) + n
M=(357.5291+0.98560028*(jstar-2451545)) % 360
c=(1.9148*sinrad(M))+(0.0200*sinrad(2*M))+(0.0003*sinrad(3*M))
l=(M+102.9372+c+180) % 360
jtransit = jstar + (0.0053 * sinrad(M)) – (0.0069 * sinrad(2 * l))
delta=math.asin(sinrad(l) * sinrad(23.45))*180/math.pi
H = math.acos((sinrad(-0.83)-sinrad(latitude)*sinrad(delta))/(cosrad(latitude)*cosrad(delta)))*180/math.pi
jstarstar=2451545.0+0.0009+((H+longitude)/360)+n
jset=jstarstar+(0.0053*sinrad(M))-(0.0069*sinrad(2*l))
jrise=jtransit-(jset-jtransit)
return (calculatetimefromjuliandate(jrise,dt,tz), calculatetimefromjuliandate(jset,dt,tz))
longitude=-21.46 #West
latitude=52.25 #North
def main():
today=gmtime()
tzc=gmtime().tm_hour-localtime().tm_hour
r_sunrise,r_sunset = calcsunriseandsunset(today,tzc)
print(“today: “)
print (“sunrise and sunset in seconds since epoch: “r_sunrise, r_sunset)
print (“sunrise and sunset local time: “, localtime(r_sunrise)[3:5], localtime(r_sunset)[3:5])
print (“sunrise and sunset UTC : “, gmtime(r_sunrise)[3:5], gmtime(r_sunset)[3:5])
if __name__ == ‘__main__’:
main()