72 lines
2.1 KiB
Python
72 lines
2.1 KiB
Python
|
|
import astral
|
||
|
|
import astral.sun
|
||
|
|
import click
|
||
|
|
import datetime
|
||
|
|
import matplotlib.dates
|
||
|
|
import matplotlib.pyplot
|
||
|
|
import operator
|
||
|
|
import sys
|
||
|
|
import timezonefinder
|
||
|
|
|
||
|
|
|
||
|
|
def days_between(start: datetime.datetime, end: datetime.datetime):
|
||
|
|
delta = end - start
|
||
|
|
for offset in range(delta.days):
|
||
|
|
yield start + datetime.timedelta(days=offset)
|
||
|
|
|
||
|
|
|
||
|
|
tf = timezonefinder.TimezoneFinder()
|
||
|
|
|
||
|
|
|
||
|
|
def sun_for(day: datetime.datetime, *, latitude: float, longitude: float):
|
||
|
|
observer = astral.Observer(latitude, longitude)
|
||
|
|
return astral.sun.sun(
|
||
|
|
observer, date=day, tzinfo=tf.timezone_at(lat=latitude, lng=longitude)
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def time_to_float(time: datetime.datetime) -> float:
|
||
|
|
return time.hour + (time.minute / 60)
|
||
|
|
|
||
|
|
|
||
|
|
@click.command()
|
||
|
|
@click.option(
|
||
|
|
"--start",
|
||
|
|
default=datetime.datetime.today(),
|
||
|
|
type=click.DateTime(),
|
||
|
|
help="Start date",
|
||
|
|
)
|
||
|
|
@click.option(
|
||
|
|
"--end",
|
||
|
|
default=datetime.datetime.today() + datetime.timedelta(days=365),
|
||
|
|
type=click.DateTime(),
|
||
|
|
help="End date",
|
||
|
|
)
|
||
|
|
@click.option("--latitude", type=float, default=52.52, help="Observer latitude")
|
||
|
|
@click.option("--longitude", type=float, default=13.4, help="Observer longitude")
|
||
|
|
def main(start, end, latitude, longitude):
|
||
|
|
print("Using", tf.timezone_at(lat=latitude, lng=longitude), file=sys.stderr)
|
||
|
|
|
||
|
|
days = list(days_between(start, end))
|
||
|
|
sun_info = [sun_for(day, latitude=latitude, longitude=longitude) for day in days]
|
||
|
|
|
||
|
|
sunrises = [time_to_float(sun["sunrise"]) for sun in sun_info]
|
||
|
|
sunsets = [time_to_float(sun["sunset"]) for sun in sun_info]
|
||
|
|
sun_hours = [set - rise for set, rise in zip(sunsets, sunrises)]
|
||
|
|
|
||
|
|
matplotlib.pyplot.gca().xaxis.set_major_formatter(
|
||
|
|
matplotlib.dates.DateFormatter("%d.%m.")
|
||
|
|
)
|
||
|
|
matplotlib.pyplot.gca().xaxis.set_major_locator(
|
||
|
|
matplotlib.dates.DayLocator(interval=30)
|
||
|
|
)
|
||
|
|
matplotlib.pyplot.plot(days, sunrises)
|
||
|
|
matplotlib.pyplot.plot(days, sunsets)
|
||
|
|
matplotlib.pyplot.plot(days, sun_hours)
|
||
|
|
matplotlib.pyplot.gcf().autofmt_xdate()
|
||
|
|
matplotlib.pyplot.savefig(sys.stdout, format="svg")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|