Python Forum
Information about api.sunrise-sunset please
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Information about api.sunrise-sunset please
#1
I'm having some difficulties understanding this python code I found on the Internet. It is suppose to return sunrise and sunset time relative the the longitude and latitude given, but what it returns isn't correct compared to the location in my browser, plus the times returned are just not correct. Sunrise in my part of the world isn't 1:14:58 PM. I'm 6 hours ahead of zulu time, but I sent my longitude and latitude information in the parm. Yes, the minutes are a little off because of when I ran the programs.

The results from the api look to be correct but way different from what the program shows.

Looks like the api is expecting something that I'm not sending or sending in the wrong format. I just don't know where to go to find out.

Please help with suggestions.

Here is the sample code:
import requests
import json
import webbrowser
params = {"lat":28.262222, "lng":-96.747165, "date":"2022-01-28"}

f = r"https://api.sunrise-sunset.org/json?"

def sunrisesunset(f, params):
    a = requests.get(f, params=params)
    a = json.loads(a.text)
    print("text = ",a)
    a = a["results"]
    return (a["sunrise"], a["sunset"], a["day_length"])

print(sunrisesunset(f, params))
Output from this program is:
Output:
('text = ', {u'status': u'OK', u'results': {u'civil_twilight_end': u'12:28:24 AM', u'nautical_twilight_end': u'12:56:43 AM', u'civil_twilight_begin': u'12:51:31 PM', u'sunset': u'12:04:56 AM', u'sunrise': u'1:14:58 PM', u'astronomical_twilight_begin': u'11:55:15 AM', u'astronomical_twilight_end': u'1:24:39 AM', u'nautical_twilight_begin': u'12:23:12 PM', u'solar_noon': u'6:39:57 PM', u'day_length': u'10:49:58'}}) (u'1:14:58 PM', u'12:04:56 AM', u'10:49:58')
And the output from going to the api using my browser is:
Output:
{"results":{"sunrise":"6:08:16 AM","sunset":"6:17:34 PM","solar_noon":"12:12:55 PM","day_length":"12:09:18","civil_twilight_begin":"5:47:39 AM","civil_twilight_end":"6:38:10 PM","nautical_twilight_begin":"5:22:22 AM","nautical_twilight_end":"7:03:28 PM","astronomical_twilight_begin":"4:57:01 AM","astronomical_twilight_end":"7:28:49 PM"},"status":"OK"}
Reply
#2
I don't see anything suspicious with your program and the output seems reasonable except that the times aren't local. It's almost certainly reporting in UTC so your local sunrise would be calculated as 13:14 - 6:00 => 7:14. That's within 2 minutes of another calculator I checked.

I can't tell what inputs you've given to the browser, but if that's supposed to be for a location in Texas in January, there's no way the day length is greater than 12 hours so that seems very suspect.

Meanwhile if I put https://api.sunrise-sunset.org/json?lat=28.262222&lng=-96.747165&date=2022-01-28 into my browser, it agrees with your program.

Ah yes, this is on the page:
Quote:NOTE: All times are in UTC and summer time adjustments are not included in the returned data.
Reply
#3
Please help a novices programmer out here.

How do I extract the sunrise and sunset information from the string returned, subtract 6 hours then compare to current time? In one of my programs, I want to do something different between sunrise and sunset. I'm not concerned with total daylight hours, just sunrise and sunset.
Reply
#4
(Jan-28-2022, 06:01 PM)bill_z Wrote: How do I extract the sunrise and sunset information from the string returned
If use this the correct way then a dictionary is returned and no need to import json.
Request has json decoder build in and return a Python dictionary.
import requests

url = 'https://api.sunrise-sunset.org/json?'
response = requests.get(url)
resp_json = response.json()
>>> resp_json
{'results': {'astronomical_twilight_begin': '4:57:01 AM',
             'astronomical_twilight_end': '7:28:49 PM',
             'civil_twilight_begin': '5:47:39 AM',
             'civil_twilight_end': '6:38:10 PM',
             'day_length': '12:09:18',
             'nautical_twilight_begin': '5:22:22 AM',
             'nautical_twilight_end': '7:03:28 PM',
             'solar_noon': '12:12:55 PM',
             'sunrise': '6:08:16 AM',
             'sunset': '6:17:34 PM'},
 'status': 'OK'}
>>> sunrise = resp_json['results']['sunrise']
>>> sunrise
'6:08:16 AM'
Quote:subtract 6 hours then compare to current time?
Now have string and need to make it to a date object,i would suggested Pendulum it make this easier.

To give a example.
>>> import pendulum
>>> 
>>> sunrise = resp_json['results']['sunrise']
>>> # Parse to a date object
>>> sunrise_date = pendulum.parse(sunrise, strict=False)
>>> sunrise_date
DateTime(2022, 1, 28, 6, 8, 16, tzinfo=Timezone('UTC'))
>>> print(sunrise_date)
2022-01-28T06:08:16+00:00
>>> 
>>> # Subtract 6 hours
>>> sunrise_date.subtract(hours=6)
DateTime(2022, 1, 28, 0, 8, 16, tzinfo=Timezone('UTC'))
>>> print(sunrise_date.subtract(hours=6))
2022-01-28T00:08:16+00:00
Reply
#5
Seems I don't have pendulum to import. I tried both python and python3 with the same result.

So I tried pip3 to install it and got another error.

Suggestions please.

Error:
pi@raspberrypi:~ $ python sunrise.py Traceback (most recent call last): File "sunrise.py", line 6, in <module> import pendulum ImportError: No module named pendulum
Error:
pi@raspberrypi:~ $ pip3 install pendulum Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Collecting pendulum Downloading https://files.pythonhosted.org/packages/db/15/6e89ae7cde7907118769ed3d2481566d05b5fd362724025198bb95faf599/pendulum-2.1.2.tar.gz (81kB) 100% |\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 81kB 1.3MB/s Installing build dependencies ... done Complete output from command python setup.py egg_info: Traceback (most recent call last): File "<string>", line 1, in <module> File "/usr/lib/python3.7/tokenize.py", line 447, in open buffer = _builtin_open(filename, 'rb') FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-install-b5zzhvrl/pendulum/setup.py' ---------------------------------------- Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-b5zzhvrl/pendulum/ pi@raspberrypi:~ $
Reply
#6
Look that there something wrong or not updated with your pip3 version.
Also i guess you use a version of Raspberry Pi OS?

Check your versions:
python3 --version
pip3 --version
pip3 install --upgrade pip
sudo pip3 install --upgrade setuptools pip
From Python3
python3 -m pip install --upgrade pip
# Install
python3 -m pip install pendulum
Reply
#7
Not able to figure out anything about pendulum, I kept on trying to make something work (work arounds).

And, I ran into another snag that I wasn't able to overcome, so, I'm asking for some help.

Even if it seems obvious, please allow me to say that I'm self taught in Python (never been to a class) and I find it difficult to know what variables I can subscript and not. Also, I don't know what I don't know much of the time.

With that said, after I execute datetime.strptime, the sunset value has a '-1 day, ' value in it that I can't use or need when comparing sunset to current local time. And, because sunset is the result of datetime.strptime, it can't be subscripted (I can't figure how). Yes, I do know why '-1 day, ' is there but, again, I don't need it. The sunset time would be correct if the '-1 day, ' were not there.

What do I do to end up with my local sunset time?


# return sunrise and sunset local time for this longitude and latitude
import requests
from datetime import datetime

url = r"https://api.sunrise-sunset.org/json?lat=28.262222&lng=-96.747165&formatted=0&date=today"
format   = '%H:%M:%S'
six_hours  = "06:00:00"
eighteen_hours = "18:00:00"

response = requests.get(url)
resp_json = response.json()
sunrise_date_time = resp_json["results"]["sunrise"]
sunset_date_time  = resp_json["results"]["sunset"]
print("sunrise_date_time ", sunrise_date_time)
print("sunset_date_time  ",  sunset_date_time)
sunrise_time = sunrise_date_time[11:-6]
sunset_time  =  sunset_date_time[11:-6]
print("sunrise_time ", sunrise_time)
print("sunset_time  ",  sunset_time)
sunrise = datetime.strptime(sunrise_time, format) - datetime.strptime(six_hours, format)
sunset  = datetime.strptime(sunset_time,  format) - datetime.strptime(six_hours, format)
print("sunrise ", sunrise)
print("sunset  ",  sunset)
Output:
pi@raspberrypi:~ $ sudo python3 sunrise.py sunrise_date_time 2022-01-29T13:14:31+00:00 sunset_date_time 2022-01-30T00:05:45+00:00 sunrise_time 13:14:31 sunset_time 00:05:45 sunrise 7:14:31 sunset -1 day, 18:05:45 <<-------- Notice this pi@raspberrypi:~ $
Reply
#8
Handy to keep your API parameters in a separate params dictionary and let the request module assemble them for you.

If you're already using strptime to parse the format, parse the first one. Don't do part of the work yourself and have it do more later.

By subtracting two datetime objects, you got a timedelta object. Don't do that. Instead, ask it to subtract the 6 hours directly (handing you back a datetime object).

# return sunrise and sunset local time for this longitude and latitude
import requests
from datetime import datetime,timedelta

latitude = 28.262222
longitude = -96.747165
timezone_hour_offset = -6

url = "https://api.sunrise-sunset.org/json"
params = {
        "lat": latitude,
        "lng": longitude,
        "formatted": 0,
        "date": "today",
        }

input_format   = "%Y-%m-%dT%H:%M:%S+00:00" # works for this site because UTC is guaranteed.
output_format  = "%H:%M:%S"

resp_json = requests.get(url, params=params).json()
sunset_date_time  = resp_json["results"]["sunset"]

sunset = datetime.strptime(sunset_date_time, input_format)
local_sunset = sunset + timedelta(hours=timezone_hour_offset)
print(f"Local sunset is at {local_sunset.strftime(output_format)}")
Reply
#9
Thanks!!! That works great.

Because it worked, I tried to use your code to figure out if the current time is between sunrise and sunset. Yes, probably a better way because, I get a error about instances between 'str' and 'datetime' not supported.

What do I do to compare current time with sunrise and sunset?

Here is my code built on yours and the error:

# return sunrise and sunset local time for this longitude and latitude
import requests
from datetime import datetime,timedelta
 
latitude = 28.262222
longitude = -96.747165
timezone_hour_offset = -6
 
url = "https://api.sunrise-sunset.org/json"
params = {
        "lat": latitude,
        "lng": longitude,
        "formatted": 0,
        "date": "today",
        }
 
input_format   = "%Y-%m-%dT%H:%M:%S+00:00" # works for this site because UTC is guaranteed.
output_format  = "%H:%M:%S"
 
resp_json = requests.get(url, params=params).json()
sunrise_date_time  = resp_json["results"]["sunrise"]
sunset_date_time  = resp_json["results"]["sunset"]
sunrise = datetime.strptime(sunrise_date_time, input_format)
sunset = datetime.strptime(sunset_date_time, input_format)
local_sunrise = sunrise + timedelta(hours=timezone_hour_offset)
local_sunset = sunset + timedelta(hours=timezone_hour_offset)
print(f"Local sunrise is at {local_sunrise.strftime(output_format)}")
print(f"Local sunset is at {local_sunset.strftime(output_format)}")
now = datetime.now ()
current_time = now.strftime (output_format)
print("Current Time =", current_time) #Output Current Time = 07:41:19
if current_time <= local_sunrise and current_time <= local_sunset:
    print('It is night')
else:
    print('Its day time')
 
Error:
pi@raspberrypi:~ $ python3 sunset.py Local sunrise is at 07:14:31 Local sunset is at 18:05:45 Current Time = 15:36:59 Traceback (most recent call last): File "sunset.py", line 33, in <module> if current_time <= local_sunrise and current_time <= local_sunset: TypeError: '<=' not supported between instances of 'str' and 'datetime.datetime' pi@raspberrypi:~ $
Reply
#10
Stick with the datetime objects. You're trying to use current_time in a calculation, but it's just a string with the correct format. now() or utcnow() would be better.

import requests
from datetime import datetime,timedelta

latitude = 28.262222
longitude = -96.747165
timezone_hour_offset = -6

url = "https://api.sunrise-sunset.org/json"
params = {
        "lat": latitude,
        "lng": longitude,
        "formatted": 0,
        "date": "today",
        }

input_format   = "%Y-%m-%dT%H:%M:%S+00:00"
output_format  = "%H:%M:%S"

resp_json = requests.get(url, params=params).json()
sunrise_date_time  = resp_json["results"]["sunrise"]
sunset_date_time  = resp_json["results"]["sunset"]

sunrise = datetime.strptime(sunrise_date_time, input_format)
sunset = datetime.strptime(sunset_date_time, input_format)

now = datetime.utcnow()
if now < sunrise:
    print(f"Sun not up yet. Check in {(sunrise - now).total_seconds()/3600:.1f} hours")
elif sunrise < now < sunset:
    print(f"Enjoy the {(sunset - now).total_seconds()/3600:.1f} hours of sunlight left")
else:
    print(f"The sun set {(now - sunset).total_seconds()/3600:.1f} hours ago")
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020