3
\$\begingroup\$

The script calls the sunrise-sunset API to get one of the possible values, then converts it to 24-Hour format and MET time (as the times from the API are 12-hour and UTC). At the end, it joins the list to a string and prints it. I know this isn't commented very well, but are there any significant flaws in this code? I neither have any experience with Python nor with programming in general, this is just for a personal project and Python seemed to be the best way to do this, so I'm open for any advice and help.

import json
import urllib.request as request
def apiGetList(key):
 """ Function twilightApiGetList(key):
 Calls the sunrise-sunset api to return the value of a given key
 Possible keys: sunrise, sunset, solar_noon, day_length, civil_twilight_begin, civil_twilight_end,
 nautical_twilight_begin, nautical_twilight_end, astronomical_twilight_begin, astronomical_twilight_end
 All times returned are a list in 12-hour format, UTC time
 """
 with request.urlopen('https://api.sunrise-sunset.org/json?lat=44.244622&lng=-7.768863&date=today') as response:
 if response.getcode() == 200:
 source = response.read()
 data = json.loads(source)
 out = list(f"{data['results'][key]}")
 if len(out) == 10:
 out.insert(0, '0')
 else:
 pass
 return(out)
 else:
 print("Not successful")
 return
def convert12To24(lst):
 """ Function convert12To24(lst):
 Converts from 12-hour format to 24-hour format, input and output types are lists
 """
 if lst[9] == "A" and "".join(lst[0:2]) == "12":
 del lst[8:12]
 lst[0:2] = '00'
 elif lst[9] == "A":
 del lst[8:12]
 elif lst[9] == "P" and "".join(lst[0:2]) == "12":
 del lst[8:12]
 else:
 del lst[8:12]
 lst[0:2] = str(int("".join(lst[0:2])) + 12)
 return(lst)
def convertUtcToMet(time):
 """ Function convertUtcToMet(time):
 Converts from UTC time to MET time by adding two hours. Input and output time is in 24-hour format, type is a list
 """
 if int("".join(time[0:2])) < 8:
 time[0:2] = str(int("".join(time[0:2])) + 2)
 time.insert(0, '0')
 elif "".join(time[0:2]) == '22':
 time[0:2] = '00'
 elif "".join(time[0:2]) == '23':
 time[0:2] = '01'
 else:
 time[0:2] = str(int("".join(time[0:2])) + 2)
 return(time)
if __name__ == "__main__":
 ctb = apiGetList("civil_twilight_begin")
 cte = apiGetList("civil_twilight_end")
 print("".join(convertUtcToMet(convert12To24(ctb))))
 print("".join(convertUtcToMet(convert12To24(cte))))
asked Apr 13, 2020 at 10:22
\$\endgroup\$
5
  • \$\begingroup\$ Is MET Middle-European Time? \$\endgroup\$ Commented Apr 13, 2020 at 15:18
  • \$\begingroup\$ If so, MET only has a one-hour offset from UTC, not 2.... \$\endgroup\$ Commented Apr 13, 2020 at 15:22
  • \$\begingroup\$ Also, are you on a boat? Those coordinates are in the Atlantic Ocean north of Portugal - which is not in MET. \$\endgroup\$ Commented Apr 13, 2020 at 16:05
  • \$\begingroup\$ I'm guessing now, but it might be that you have an accidental negative sign in your longitude - the positive longitude would put you in Italy south of Turin, which is probably (?) in the timezone that you indicate. \$\endgroup\$ Commented Apr 13, 2020 at 16:16
  • \$\begingroup\$ @Reinderien Don't worry about these coordinates, I changed the real location for random numbers so that I wouldn't reveal my location! I'm actually located in Germany. Also, you are right, I didn't look up the time difference between UTC and MET because I thought I remembered it correctly, thanks for clarifying! I will work through your answer and try to understand it correctly before accepting it, but already thanks a lot for the help! \$\endgroup\$ Commented Apr 14, 2020 at 8:12

1 Answer 1

3
\$\begingroup\$

Welcome to CodeReview! This is a great first question.

Do not do your own time math

...nor your own formatting when possible. Tell Python to do it for you. Some example code:

from dataclasses import dataclass
from datetime import timedelta, datetime, timezone
import requests, pytz
@dataclass(frozen=True)
class DayInfo:
 day_length: timedelta
 sunrise: datetime
 sunset: datetime
 solar_noon: datetime
 civil_twilight_begin: datetime
 civil_twilight_end: datetime
 nautical_twilight_begin: datetime
 nautical_twilight_end: datetime
 astronomical_twilight_begin: datetime
 astronomical_twilight_end: datetime
 @classmethod
 def get(cls, lat: float, long: float, tz: timezone) -> 'DayInfo':
 """ Function twilightApiGetList(key):
 Calls the sunrise-sunset api to return the value of a given key
 All times returned are in the provided timezone.
 """
 with requests.get(
 'https://api.sunrise-sunset.org/json',
 params={
 'lat': lat,
 'lng': long,
 'date': 'today', # technically this can be omitted
 'formatted': 0, # we want ISO8601 ("machine-readable")
 },
 ) as response:
 response.raise_for_status()
 data = response.json()
 if data['status'] != 'OK':
 raise requests.HTTPError(data['status'], response=response)
 results = data['results']
 return cls(
 day_length=timedelta(seconds=int(results['day_length'])),
 **{
 k: datetime.fromisoformat(results[k]).astimezone(tz)
 for k in (
 'sunrise',
 'sunset',
 'solar_noon',
 'civil_twilight_begin',
 'civil_twilight_end',
 'nautical_twilight_begin',
 'nautical_twilight_end',
 'astronomical_twilight_begin',
 'astronomical_twilight_end',
 )
 },
 )
if __name__ == "__main__":
 day_info = DayInfo.get(44.244622, -7.768863, pytz.timezone('MET'))
 print(f'{day_info.civil_twilight_begin:%H:%m}')
 print(f'{day_info.civil_twilight_end:%H:%m}')

Notes:

  • You didn't parameterize the right things. Parameters should be coordinates and timezone.
  • Ask the API for machine-readable (ISO) dates.
  • Might as well parse everything from the API.
  • Do not use string manipulation to get your desired format. What is shown is string interpolation with standard Python time fields.
  • Use requests - it has a lot of niceties that make this easier.
  • Only issue one call to the API, returning an object that has both of the keys you care about. If you're never, ever going to use the other keys, you can delete them from this class, but they're inexpensive to generate - compared to a second HTTP call, which is much more expensive.
answered Apr 13, 2020 at 15:28
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.