diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 012a7a3..0000000 --- a/shell.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ pkgs ? import {} }: -pkgs.mkShell { - buildInputs = with pkgs; [ espeak ]; -} diff --git a/sun_hours/shell.nix b/sun_hours/shell.nix new file mode 100644 index 0000000..66451b3 --- /dev/null +++ b/sun_hours/shell.nix @@ -0,0 +1,9 @@ +{ pkgs ? import {} }: +pkgs.mkShell { + buildInputs = [ + pkgs.python3Packages.astral + pkgs.python3Packages.matplotlib + pkgs.python3Packages.click + pkgs.python3Packages.timezonefinder + ]; +} diff --git a/sun_hours/sun_hours.py b/sun_hours/sun_hours.py new file mode 100644 index 0000000..814eb79 --- /dev/null +++ b/sun_hours/sun_hours.py @@ -0,0 +1,71 @@ +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()