feat(Q5): NOAA sunset calculator (stdlib only)

This commit is contained in:
Aaron D. Lee 2026-04-03 18:42:26 -04:00
parent a5dd15d0a1
commit e75a9a9d71
2 changed files with 49 additions and 0 deletions

18
tests/unit/test_solar.py Normal file
View File

@ -0,0 +1,18 @@
import datetime
from vigilar.detection.solar import get_sunset
def test_sunset_returns_time():
result = get_sunset(45.0, -85.0, datetime.date(2026, 6, 21))
assert isinstance(result, datetime.time)
def test_sunset_equator():
result = get_sunset(0.0, 0.0, datetime.date(2026, 3, 20))
assert 17 <= result.hour <= 19
def test_sunset_different_dates_vary():
d1 = get_sunset(45.0, -85.0, datetime.date(2026, 3, 1))
d2 = get_sunset(45.0, -85.0, datetime.date(2026, 9, 1))
assert d1 != d2

View File

@ -0,0 +1,31 @@
"""Sunset calculation using NOAA solar equations. Stdlib only."""
import datetime
import math
def get_sunset(latitude: float, longitude: float, date: datetime.date) -> datetime.time:
n = date.timetuple().tm_yday
gamma = 2 * math.pi / 365 * (n - 1)
eqtime = 229.18 * (
0.000075 + 0.001868 * math.cos(gamma) - 0.032077 * math.sin(gamma)
- 0.014615 * math.cos(2 * gamma) - 0.040849 * math.sin(2 * gamma)
)
decl = (
0.006918 - 0.399912 * math.cos(gamma) + 0.070257 * math.sin(gamma)
- 0.006758 * math.cos(2 * gamma) + 0.000907 * math.sin(2 * gamma)
- 0.002697 * math.cos(3 * gamma) + 0.00148 * math.sin(3 * gamma)
)
lat_rad = math.radians(latitude)
zenith = math.radians(90.833)
cos_ha = (
math.cos(zenith) / (math.cos(lat_rad) * math.cos(decl))
- math.tan(lat_rad) * math.tan(decl)
)
cos_ha = max(-1.0, min(1.0, cos_ha))
ha = math.degrees(math.acos(cos_ha))
sunset_minutes = 720 - 4 * (longitude - ha) - eqtime
sunset_minutes = sunset_minutes % 1440
hours = int(sunset_minutes // 60)
minutes = int(sunset_minutes % 60)
return datetime.time(hour=hours, minute=minutes)