Created
January 8, 2023 07:35
-
-
Save klausbrunner/6b41344b488c3ef5519bf9c0bcac62c4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""Parse sunrise/sunset tables as provided by the USNO website at https://aa.usno.navy.mil/data/RS_OneYear""" | |
import re | |
import argparse | |
def parse_table(filename: str): | |
def to_decimal_deg(latlon_tup) -> float: | |
assert len(latlon_tup) == 3 and re.match("[NESW]", latlon_tup[0]) | |
deg = int(latlon_tup[1]) + int(latlon_tup[2]) / 60.0 | |
if latlon_tup[0] in ("S", "W"): | |
return -deg | |
return deg | |
def time_colon(timestr: str) -> str: | |
if timestr.isdigit(): | |
return timestr[:2] + ":" + timestr[2:] | |
return timestr | |
months = [{} for i in range(12)] | |
year, location = None, None | |
with open(filename, encoding="utf8") as f: | |
for line in f: | |
if line.startswith("Location: "): | |
m = re.search(r"\s+([EW])(\d+)\s+(\d+)[\s,]+([NS])(\d+)\s+(\d+)", line) | |
assert m, "can't parse location as expected" | |
lon, lat = m.groups()[:3], m.groups()[3:] | |
location = (to_decimal_deg(lat), to_decimal_deg(lon)) | |
m = re.search("Rise and Set for the Sun for (\d+)", line) | |
assert m, "can't parse year as expected" | |
year = int(m.group(1)) | |
elif re.match(r"^\d\d ", line): | |
# this is a fixed tabular format with occasional empty "cells", so we'll just use indexes | |
day = int(line[:2]) | |
for month, slot in enumerate(range(4, 135, 11)): | |
sunrise, sunset = ( | |
line[slot : slot + 4].strip(), | |
line[slot + 5 : slot + 5 + 4].strip(), | |
) | |
if (sunrise and sunset): # ignore nonexistent or weird days with only one value | |
assert len(sunrise) == len(sunset) == 4, "unexpected format" | |
months[month][day]=(time_colon(sunrise), time_colon(sunset)) | |
assert year and location | |
return location, year, months | |
if __name__ == "__main__": | |
location, year, months = parse_table("xyz.txt") | |
for month, days in enumerate(months, start=1): | |
for day, values in days.items(): | |
print(year, month, day, values) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment