Calculating Sunrise and Sunset in Python from GPS Coordinates

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

  1. 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()

Leave a Reply

Your email address will not be published. Required fields are marked *