Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare datetime.now() with sunrise/sunset times from Sunrise-Sunset API in Python?

I'm working on a Python script that checks whether it's currently dark outside based on my location (Barishal, Bangladesh). I use the Sunrise-Sunset API to get sunrise and sunset times, and then compare those to datetime.now().

import requests
from datetime import datetime

# My location
MY_LAT = 22.712647
MY_LNG = 90.351848

parameters = {
    "lat": MY_LAT,
    "lng": MY_LNG,
    "formatted": 0  # To get ISO 8601 format for easy datetime comparison
}

response = requests.get("https://api.sunrise-sunset.org/json", params=parameters)
data = response.json()

sunrise_utc = data["results"]["sunrise"]
sunset_utc = data["results"]["sunset"]

# Convert strings to datetime objects
sunrise_time = datetime.fromisoformat(sunrise_utc)
sunset_time = datetime.fromisoformat(sunset_utc)

# Current time
now = datetime.utcnow()

# Compare
if now < sunrise_time or now > sunset_time:
    print("It's dark outside")
else:
    print("It's daytime")

Even though it's nighttime here, my old script was returning "It's daytime" because the sunrise/sunset times were in UTC and not adjusted to my local time.

like image 348
Mdjayed Gazi Avatar asked Oct 14 '25 03:10

Mdjayed Gazi


1 Answers

Documentation for sunrise-sunset.org suggests that you can use
tzid (string): A timezone identifier

parameters = {
    "lat": MY_LAT,
    "lng": MY_LNG,
    "formatted": 0,  # To get ISO 8601 format for easy datetime comparison
    "tzid": "Asia/Dhaka",
}

And this gives me values with UTC+06:00 instead of UTC

And to get current time with the same timezone I needed

from zoneinfo import ZoneInfo

zone_info = ZoneInfo("Asia/Dhaka")

now = datetime.now(zone_info)

or

time_zone = datetime.timezone(datetime.timedelta(hours=6)) #, "UTC+06:00")

now = datetime.datetime.now(time_zone)

Without this I get error when it compares now < sunrise_time because datetime.utcnow() gives me time without timezone and it doesn't know how to compare times.


Command datetime.datetime.utcnow() gives warning that it is deprecated and it should be used datetime.datetime.now(datetime.UTC)


Full working code with extra info:

import requests
import datetime
from zoneinfo import ZoneInfo

# My location
MY_LAT = 22.712647
MY_LNG = 90.351848

zone_name = "Europe/Warsaw"
zone_name = "Asia/Dhaka"
#zone_name = "UTC+06:00"  # doesn't work in API and ZoneInfo

parameters = {
    "lat": MY_LAT,
    "lng": MY_LNG,
    "formatted": 0,  # To get ISO 8601 format for easy datetime comparison
    "tzid": zone_name,
}

response = requests.get("https://api.sunrise-sunset.org/json", params=parameters)
data = response.json()
#print(data)

sunrise_utc = data["results"]["sunrise"]
sunset_utc = data["results"]["sunset"]

# Convert strings to datetime objects
sunrise_time = datetime.datetime.fromisoformat(sunrise_utc)
sunset_time = datetime.datetime.fromisoformat(sunset_utc)

# Current time
now = datetime.datetime.utcnow().replace(microsecond=0)
print('\n--- utcnow() ---')
print(f"{now = }")
print(f"{now.tzinfo = }")
print(now)

now = datetime.datetime.now(datetime.UTC).replace(microsecond=0)
print('\n--- now(datetime.UTC) ---')
print(f"{now = }")
print(f"{now.tzinfo = }")
print(now)

zone_info = ZoneInfo(zone_name)
now = datetime.datetime.now(zone_info).replace(microsecond=0)
print('\n--- now(ZoneInfo) ---')
print(f"{now = }")
print(f"{now.tzinfo = }")
print(now)

zone_info = datetime.timezone(datetime.timedelta(hours=6)) #, "UTC+06:00")
now = datetime.datetime.now(zone_info).replace(microsecond=0)
print('\n--- now(timezone) ---')
print(f"{now = }")
print(f"{now.tzinfo = }")
print(now)

print('\n------')
print(f'now: {now} | {now.tzinfo}')
print(f'sr : {sunrise_time} | {sunrise_time.tzinfo}')
print(f'ss : {sunset_time} | {sunset_time.tzinfo}')

# Compare
if now < sunrise_time or now > sunset_time:
    print("It's dark outside")
else:
    print("It's daytime")

Result:

./main.py:38: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
  now = datetime.datetime.utcnow().replace(microsecond=0)

--- utcnow() ---
now = datetime.datetime(2025, 8, 8, 7, 38, 5)
now.tzinfo = None
2025-08-08 07:38:05

--- now(datetime.UTC) ---
now = datetime.datetime(2025, 8, 8, 7, 38, 5, tzinfo=datetime.timezone.utc)
now.tzinfo = datetime.timezone.utc
2025-08-08 07:38:05+00:00

--- now(ZoneInfo) ---
now = datetime.datetime(2025, 8, 8, 13, 38, 5, tzinfo=zoneinfo.ZoneInfo(key='Asia/Dhaka'))
now.tzinfo = zoneinfo.ZoneInfo(key='Asia/Dhaka')
2025-08-08 13:38:05+06:00

--- now(timezone) ---
now = datetime.datetime(2025, 8, 8, 13, 38, 5, tzinfo=datetime.timezone(datetime.timedelta(seconds=21600), 'UTC+06:00'))
now.tzinfo = datetime.timezone(datetime.timedelta(seconds=21600), 'UTC+06:00')
2025-08-08 13:38:05+06:00

------
now: 2025-08-08 13:38:05+06:00 | UTC+06:00
sr : 2025-08-08 05:31:36+06:00 | UTC+06:00
ss : 2025-08-08 18:36:54+06:00 | UTC+06:00
It's daytime

By The Way:

There is also Python module Astral which can calculate it without using Internet.

Difference is ~1.5 minutes.

You create location (if it doesn't have it in "database") and it can calculate sun position for your timezone.

import datetime
from astral import LocationInfo
from astral.sun import sun

MY_LAT = 22.712647
MY_LNG = 90.351848

city = LocationInfo(latitude=MY_LAT, longitude=MY_LNG)

time_zone = datetime.timezone(datetime.timedelta(hours=6))  # "UTC+06:00"

info = sun(city.observer, tzinfo=time_zone)

print('sunrise:', info['sunrise'])
print('sunset :', info['sunset'])
print('length :', info['sunset'] - info['sunrise'])

Longer version which calculates also for tomorrow and yesterday

import datetime
#import astral
from astral import LocationInfo
from astral.sun import sun
from astral.geocoder import database, lookup

# My location
MY_LAT = 22.712647
MY_LNG = 90.351848

#city = LocationInfo("Barishal", "Asia", "Asia/Barishal", 22.712647, 90.351848)
#city = LocationInfo(name="Barishal", region="Asia", timezone="Asia/Barishal", latitude=MY_LAT, longitude=MY_LNG)
#city = LocationInfo(latitude=MY_LAT, longitude=MY_LNG)
db = database()
#city = db['asia']['dhaka'][0]  # lowercase
city = lookup('Dhaka', db)     
print(city)

time_zone = datetime.timezone(datetime.timedelta(hours=6)) 

one_day = datetime.timedelta(days=1)
today = datetime.date.today() 

print('--- today ---')

info = sun(city.observer, tzinfo=time_zone)
#info = sun(city.observer, date=today, tzinfo=time_zone)

print('sunrise:', info['sunrise'].replace(microsecond=0))
print('sunset :', info['sunset'].replace(microsecond=0))
print('length :', info['sunset'] - info['sunrise'])

print('--- tomorrow ---')

tomorrow = today + one_day
info = sun(city.observer, date=tomorrow, tzinfo=time_zone)

print('sunrise:', info['sunrise'].replace(microsecond=0))
print('sunset :', info['sunset'].replace(microsecond=0))
print('length :', info['sunset'] - info['sunrise'])

print('--- yesterday ---')

yesterday = today - one_day
info = sun(city.observer, date=yesterday, tzinfo=time_zone)

print('sunrise:', info['sunrise'].replace(microsecond=0))
print('sunset :', info['sunset'].replace(microsecond=0))
print('length :', info['sunset'] - info['sunrise'])

Result:

--- today ---
sunrise: 2025-08-08 05:32:53+06:00
sunset : 2025-08-08 18:35:20+06:00
length : 13:02:26.340931
--- tomorrow ---
sunrise: 2025-08-09 05:33:17+06:00
sunset : 2025-08-09 18:34:39+06:00
length : 13:01:22.427021
--- yesterday ---
sunrise: 2025-08-07 05:32:30+06:00
sunset : 2025-08-07 18:35:59+06:00
length : 13:03:29.519594
like image 104
furas Avatar answered Oct 16 '25 17:10

furas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!