Use coordinate-based timezone lookup for trip destinations

This commit is contained in:
Edward Betts 2026-02-26 14:57:20 +00:00
parent ec413ac310
commit 1ee1f38a99
2 changed files with 40 additions and 0 deletions

View file

@ -10,3 +10,4 @@ ephem
flask
requests
emoji
timezonefinder

View file

@ -3,7 +3,9 @@
"""Web page to show upcoming events."""
import decimal
import functools
import hashlib
import importlib
import inspect
import json
import operator
@ -789,9 +791,35 @@ def _format_offset_from_bristol(offset_minutes: int) -> str:
return f"{sign}{hours:02d}:{mins:02d} vs Bristol"
def _timezone_from_coordinates(latitude: float, longitude: float) -> str | None:
"""Resolve IANA timezone name from coordinates."""
timezone_finder = _get_timezone_finder()
if timezone_finder is None:
return None
tz_name = timezone_finder.timezone_at(lng=longitude, lat=latitude)
return tz_name if isinstance(tz_name, str) else None
@functools.lru_cache(maxsize=1)
def _get_timezone_finder() -> typing.Any:
"""Get timezone finder instance if dependency is available."""
try:
timezonefinder_module = importlib.import_module("timezonefinder")
except ModuleNotFoundError:
return None
timezone_finder_cls = getattr(timezonefinder_module, "TimezoneFinder", None)
if timezone_finder_cls is None:
return None
return timezone_finder_cls()
def get_destination_timezones(trip: Trip) -> list[StrDict]:
"""Build destination timezone metadata for the trip page."""
per_location: dict[tuple[str, str], list[str]] = defaultdict(list)
location_coords: dict[tuple[str, str], tuple[float, float]] = {}
for item in trip.accommodation + trip.conferences + trip.events:
location = item.get("location")
country = item.get("country")
@ -803,6 +831,11 @@ def get_destination_timezones(trip: Trip) -> list[StrDict]:
if isinstance(timezone_name, str):
per_location[key].append(timezone_name)
latitude = item.get("latitude")
longitude = item.get("longitude")
if isinstance(latitude, (int, float)) and isinstance(longitude, (int, float)):
location_coords[key] = (float(latitude), float(longitude))
for field in (
"from",
"to",
@ -832,6 +865,12 @@ def get_destination_timezones(trip: Trip) -> list[StrDict]:
except Exception:
continue
if not timezone_name and key in location_coords:
latitude, longitude = location_coords[key]
coordinate_timezone = _timezone_from_coordinates(latitude, longitude)
if coordinate_timezone:
timezone_name = coordinate_timezone
if not timezone_name:
country_timezones = pytz.country_timezones.get(country_code, [])
if len(country_timezones) == 1: