Sunrise and Sunset time in Python

You can also try with suntime. An example from their doc below:

import datetime
from suntime import Sun, SunTimeException

latitude = 51.21
longitude = 21.01

sun = Sun(latitude, longitude)

# Get today's sunrise and sunset in UTC
today_sr = sun.get_sunrise_time()
today_ss = sun.get_sunset_time()
print('Today at Warsaw the sun raised at {} and get down at {} UTC'.
      format(today_sr.strftime('%H:%M'), today_ss.strftime('%H:%M')))

# On a special date in your machine's local time zone
abd = datetime.date(2014, 10, 3)
abd_sr = sun.get_local_sunrise_time(abd)
abd_ss = sun.get_local_sunset_time(abd)
print('On {} the sun at Warsaw raised at {} and get down at {}.'.
      format(abd, abd_sr.strftime('%H:%M'), abd_ss.strftime('%H:%M')))

The Astral package example above appears to be dated.

Below is an example for Astral v2.2 for the San Jose, CA airport location.

First, set up the observer's location:

from astral import LocationInfo
loc = LocationInfo(name='SJC', region='CA, USA', timezone='America/Los_Angeles',
                   latitude=37.3713439, longitude=-121.944675)
print(loc)
# LocationInfo(name='SJC', region='CA, USA', timezone='America/Los_Angeles',
#   latitude=37.3713439, longitude=-121.944675)
print(loc.observer)
# Observer(latitude=37.3713439, longitude=-121.944675, elevation=0.0)

Note:

  • Only the latitude, longitude, and timezone are important.
  • The name and region are just labels.

Next, calculate the sun's info for that observer on the desired date (e.g., 2021-01-15 below):

import datetime
from astral.sun import sun
s = sun(loc.observer, date=datetime.date(2021, 1, 15), tzinfo=loc.timezone)
for key in ['dawn', 'dusk', 'noon', 'sunrise', 'sunset']:
    print(f'{key:10s}:', s[key])

Output:

dawn      : 2021-01-15 06:52:04.342105-08:00
dusk      : 2021-01-15 17:42:59.471441-08:00
noon      : 2021-01-15 12:17:05-08:00
sunrise   : 2021-01-15 07:21:04.877697-08:00
sunset    : 2021-01-15 17:13:58.467348-08:00

Notes:

  • If the timezone is not specified, it defaults to UTC.
  • Noon is solar noon -- the time when the sun crosses the meridian at the observer's location.
  • Astral is an implementation of the Excel sheets published by the NOAA.

I have compared few packages (suntime, suntimes, sunriset, astral) and times sunrise and sunset times returned by them. All of them return local time but you can easily get UTC time as well. This is the result:

from datetime import date, datetime, timezone, timedelta
import pytz
import time
from suntime import Sun, SunTimeException
from suntimes import SunTimes
import sunriset
import astral, astral.sun

latitude = 52.0691667
longitude = 19.4805556
altitude = 0
tz_poland = pytz.timezone('Europe/Warsaw')
tz_name = 'Europe/Warsaw'
for_date = date(2021, 4, 6)
print('====== suntime ======')
abd = for_date
sun = Sun(latitude, longitude)
today_sr = sun.get_sunrise_time()
today_ss = sun.get_sunset_time()
print(today_sr.astimezone(tz_poland))
print(today_ss.astimezone(tz_poland))
print('====== suntimes ======')
sun2 = SunTimes(longitude=longitude, latitude=latitude, altitude=altitude)
day = datetime(for_date.year, for_date.month, for_date.day)
print(sun2.risewhere(day, tz_name))
print(sun2.setwhere(day, tz_name))
print('====== sunriset ======')
local = datetime.now()
utc = datetime.utcnow()
local_tz = float(((local - utc).days * 86400 + round((local - utc).seconds, -1))/3600)
number_of_years = 1
start_date = for_date
df = sunriset.to_pandas(start_date, latitude, longitude, 2, number_of_years)
for index, row in df.iterrows():
    print(row['Sunrise'])
    print(row['Sunset'])
    break
print('====== astral ======')
l = astral.LocationInfo('Custom Name', 'My Region', tz_name, latitude, longitude)
s = astral.sun.sun(l.observer, date=for_date)
print(s['sunrise'].astimezone(tz_poland))
print(s['sunset'].astimezone(tz_poland))

And the return:

====== suntime ======
2021-04-06 06:05:00+02:00
2021-04-06 19:16:00+02:00
====== suntimes ======
2021-04-06 06:04:34.000553+02:00
2021-04-06 19:17:16.000613+02:00
====== sunriset ======
0 days 06:02:52.093465
0 days 19:16:49.892350
====== astral ======
2021-04-06 06:03:39.792229+02:00
2021-04-06 19:17:01.188463+02:00

Please note only suntimes package support altitude.


Check out astral. Here's a slightly modified example from their docs:

>>> from astral import Astral
>>> city_name = 'London'
>>> a = Astral()
>>> a.solar_depression = 'civil'
>>> city = a[city_name]
>>> sun = city.sun(date=datetime.date(2009, 4, 22), local=True)

>>> if (sun['sunrise'] < T < sun['sunset']) and (light < threshold):
>>>    notifyUser()

If you use something like this example, please remember to change the city_name and date provided to city.sun.