Calculate sunrise and sunset with PyEphem

PyEphem (from the Greek word ephemeris) is the way to calculate the positions of all sorts of astronomical bodies in Python.

I used it recently to calculate a year’s worth of sunrise and sunset times. Using something as advanced as PyEphem for something this astronomically simple might be overkill, but it works well. Here’s how I did it:

import ephem
import datetime

obs = ephem.Observer()
obs.lat = '38.8'
obs.long= '-75.2'

start_date = datetime.datetime(2008, 1, 1)
end_date = datetime.datetime(2008, 12, 31)
td = datetime.timedelta(days=1)

sun = ephem.Sun()

sunrises = []
sunsets = []
dates = []

date = start_date
while date < end_date:
    date += td
    dates.append(date)
    obs.date = date

    rise_time = obs.next_rising(sun).datetime()
    sunrises.append(rise_time)

    set_time = obs.next_setting(sun).datetime()
    sunsets.append(set_time)

To plot day length in hours over the course of a year, first run the above code. Then (assuming you have matplotlib):

from pylab import *
daylens = []
for i in range(len(sunrises)):
    timediff = sunsets[i] - sunrises[i]
    hours = timediff.seconds / 60. / 60.  # to get it in hours
    daylens.append(hours)

plot(dates, daylens)

# if you have an older version of matplotlib, you may need
# to convert dates into numbers before plotting:
# dates = [date2num(i) for i in dates]

xlabel('Date')
ylabel('Hours')
title('Day length in 2008')
show()

3 Responses to “Calculate sunrise and sunset with PyEphem”


  • Thanks for posting this. I needed something similar to this exact information. You could have used the next feature to step through the dates though. for example:

    import ephem
    import datetime

    obs = ephem.Observer()
    obs.lat = ’38.8′
    obs.long=’-75.2′

    start_date = datetime.datetime(2008,1,1)
    end_date = datetime.datetime(2008, 12, 31)
    length = (end_date – start_date).days
    rise_times = []
    set_times = []
    count = 0
    while count < length:
    rise_times.append(obs.next_rising(ephem.Sun()))
    set_times.append(obs.next_setting(ephem.Sun()))
    count += 1

  • Xaviar:
    Good call. After updating my PyEphem version to the most recent one, I got a warning that the rise_time and set_time attributes are now deprecated, and next_rising and next_setting should be used instead. I’ve updated the post to reflect that change, just like you’ve shown.

  • I am trying to run this in Python 2.5. I only get a result for the last day of the year (end_date). How do I get a full years result and have it written to a text file, plus add 10 hours for Australian timezone.

Leave a Reply