convert track timestamps to airport-local; capture per-leg UTC offsets

This commit is contained in:
2026-09-15 22:48:34 +10:00
parent 8a2fb25897
commit 480b896d39
5 changed files with 278 additions and 12 deletions
+36
View File
@@ -71,6 +71,36 @@ def _sanitize(flight_number: str) -> str:
return re.sub(r"[\s-]", "", flight_number).upper()
def _utc_offset(local: str | None) -> str | None:
"""Pull the UTC offset out of an AeroDataBox 'local' string
('2026-06-22 13:45+10:00' -> '+10:00').
This is the airport's *actual* offset on the day of the flight (so DST
is already accounted for), and it's the only timezone information this
pipeline has - the bundled airports.csv carries IATA/ICAO/name only.
scheduler.py needs it to convert the FlightAware track's UTC timestamps
into the airport-local wall clock AirTrail expects."""
if not local:
return None
try:
dt = datetime.strptime(local, "%Y-%m-%d %H:%M%z")
except ValueError:
return None
offset = dt.strftime("%z") # '+1000'
return f"{offset[:3]}:{offset[3:]}" if len(offset) == 5 else None
def _first_offset(leg: dict) -> str | None:
"""The UTC offset for one leg, from whichever of its timestamps exists.
All of a leg's times share the same airport and day, so any of them
gives the same offset."""
for key in ("scheduledTime", "revisedTime", "actualTime", "runwayTime"):
offset = _utc_offset((leg.get(key) or {}).get("local"))
if offset:
return offset
return None
def _parse_local(local: str | None) -> str | None:
"""AeroDataBox 'local' strings look like '2026-06-22 13:45+10:00' -
already carrying their own UTC offset, no separate airport-timezone
@@ -155,4 +185,10 @@ def lookup_gate_times(flight_number: str, flight_date: date) -> dict | None:
),
"takeoffActual": _parse_local((dep.get("runwayTime") or {}).get("local")),
"landingActual": _parse_local((arr.get("runwayTime") or {}).get("local")),
# Each leg's real UTC offset on the day, taken from whichever local
# timestamp that leg actually has. Not sent to AirTrail directly -
# scheduler.py uses these to put the FlightAware track's UTC times
# into the same airport-local terms as everything else here.
"departureUtcOffset": _first_offset(dep),
"arrivalUtcOffset": _first_offset(arr),
}