sffjunkie / astral

Python calculations for the position of the sun and moon.
Apache License 2.0
242 stars 47 forks source link

ValueError: Sun never reaches an elevation of ... degrees at this location. #95

Open danielfaust opened 5 months ago

danielfaust commented 5 months ago

The following code computes the noon time and elevation of any given day.

Then it uses the elevation to compute the time of that given day at the previously obtained elevation, yet it claims that the elevation is not reached on that day.

import pytz
import datetime
from astral.sun import sun, elevation, time_at_elevation
from astral import Observer

LAT = 52.522282527
LON = 13.393107616
TIMEZONE = 'Europe/Berlin'
tz = pytz.timezone(TIMEZONE)
OBSERVER = Observer(LAT, LON, 0)

date = datetime.date(2024, 6, 20) # longest day of the year
date = datetime.date(2024, 12, 21) # shortest day of the year
date = datetime.date.today()

solar_noon = sun(OBSERVER, date=date)['noon']
solar_noon_local = solar_noon.astimezone(tz)
solar_noon_elevation = elevation(OBSERVER, solar_noon_local)

print(f"Solar noon at {solar_noon_local.strftime('%Y-%m-%d %H:%M:%S')} with an elevation of {solar_noon_elevation}\n")

# Adjusted elevation calculation
adjusted_elevation = solar_noon_elevation
# adjusted_elevation = solar_noon_elevation * 0.99 # makes it somewhat safe to compute

# Times for adjusted elevation
noon_at_2 = time_at_elevation(OBSERVER, adjusted_elevation, direction=astral.SunDirection.RISING, date=date)
noon_at_2_local = noon_at_2.astimezone(tz)
print(f"Solar noon at {noon_at_2_local.strftime('%Y-%m-%d %H:%M:%S')} with an elevation of {adjusted_elevation} (rising)\n")

noon_at_3 = time_at_elevation(OBSERVER, adjusted_elevation, direction=astral.SunDirection.SETTING, date=date)
noon_at_3_local = noon_at_3.astimezone(tz)
print(f"Solar noon at {noon_at_3_local.strftime('%Y-%m-%d %H:%M:%S')} with an elevation of {adjusted_elevation} (setting)\n")

This throws an error that ValueError: Sun never reaches an elevation of 60.55323994960828 degrees at this location.

Related LOC: https://github.com/sffjunkie/astral/blob/ac23ab5c0c69837d8fa1a5bb184c2d6d125b26b3/src/astral/sun.py#L380

lulunac27a commented 1 month ago

Python floating point numbers have double-precision type, so it can have floating-point rounding error.