Python package for finding the timezone of any point on earth (coordinates) offline
Module-level functions that provide simple access to timezone lookup functionality using a singleton TimezoneFinder instance. These functions offer maximum convenience for simple use cases but are not thread-safe.
Primary timezone lookup functions that handle the most common use cases. All functions use a shared global TimezoneFinder instance that is created lazily on first use.
def timezone_at(*, lng: float, lat: float) -> Optional[str]:
"""
Find timezone at given coordinates using global TimezoneFinder instance.
Note: This function is not thread-safe. For multi-threaded environments,
create separate TimezoneFinder instances.
Parameters:
- lng: Longitude in degrees (-180.0 to 180.0)
- lat: Latitude in degrees (-90.0 to 90.0)
Returns:
- Timezone name of matching polygon or None
"""
def timezone_at_land(*, lng: float, lat: float) -> Optional[str]:
"""
Find land timezone only, excluding ocean timezones.
Note: This function is not thread-safe. For multi-threaded environments,
create separate TimezoneFinder instances.
Parameters:
- lng: Longitude in degrees (-180.0 to 180.0)
- lat: Latitude in degrees (-90.0 to 90.0)
Returns:
- Land timezone name or None when ocean timezone would be matched
"""
def unique_timezone_at(*, lng: float, lat: float) -> Optional[str]:
"""
Find timezone if unique within the corresponding shortcut area.
Note: This function is not thread-safe. For multi-threaded environments,
create separate TimezoneFinder instances.
Parameters:
- lng: Longitude in degrees (-180.0 to 180.0)
- lat: Latitude in degrees (-90.0 to 90.0)
Returns:
- Timezone name if unique in shortcut area, None if multiple or no zones
"""
def certain_timezone_at(*, lng: float, lat: float) -> Optional[str]:
"""
Find timezone with exhaustive polygon checking.
Note: This function is not thread-safe. For multi-threaded environments,
create separate TimezoneFinder instances.
Note: Only meaningful with custom timezone data having incomplete coverage.
Less performant than timezone_at().
Parameters:
- lng: Longitude in degrees (-180.0 to 180.0)
- lat: Latitude in degrees (-90.0 to 90.0)
Returns:
- Timezone name if point is certainly within a polygon, None otherwise
"""Advanced function for retrieving detailed timezone polygon geometry data.
def get_geometry(
tz_name: Optional[str] = "",
tz_id: Optional[int] = 0,
use_id: bool = False,
coords_as_pairs: bool = False
) -> List[Union[List[CoordPairs], List[CoordLists]]]:
"""
Retrieve geometry of a timezone polygon using global TimezoneFinder instance.
Note: This function is not thread-safe. For multi-threaded environments,
create separate TimezoneFinder instances.
Parameters:
- tz_name: Timezone name (e.g., 'Europe/Berlin')
- tz_id: Timezone ID (index in timezone_names list)
- use_id: If True, use tz_id instead of tz_name
- coords_as_pairs: If True, return coordinates as [(lng,lat), ...] pairs,
if False, return as ([longitudes], [latitudes]) lists
Returns:
- Multipolygon data structure: [[polygon1, hole1, hole2...], [polygon2, ...], ...]
Each polygon/hole formatted as coordinate pairs or separate lists based on coords_as_pairs
"""from timezonefinder import timezone_at, timezone_at_land
# Basic timezone lookup
tz = timezone_at(lng=13.358, lat=52.5061)
print(tz) # 'Europe/Berlin'
# Land timezone only (excludes ocean timezones)
land_tz = timezone_at_land(lng=0.0, lat=0.0)
print(land_tz) # None (ocean location)
ocean_tz = timezone_at(lng=0.0, lat=0.0)
print(ocean_tz) # 'Etc/GMT' (ocean timezone)from timezonefinder import unique_timezone_at, certain_timezone_at
# Unique timezone in shortcut area
unique_tz = unique_timezone_at(lng=13.358, lat=52.5061)
print(unique_tz) # 'Europe/Berlin' if unique in area, None if multiple zones
# Exhaustive polygon checking
certain_tz = certain_timezone_at(lng=13.358, lat=52.5061)
print(certain_tz) # 'Europe/Berlin' if certainly within polygonfrom timezonefinder import get_geometry
# Get geometry by timezone name
geometry = get_geometry(tz_name='Europe/Berlin', coords_as_pairs=False)
print(f"Number of polygons: {len(geometry)}")
# Each polygon contains boundary + holes
for i, polygon_with_holes in enumerate(geometry):
boundary = polygon_with_holes[0] # First is the boundary
holes = polygon_with_holes[1:] # Rest are holes
lngs, lats = boundary
print(f"Polygon {i}: {len(lngs)} boundary points, {len(holes)} holes")
# Get geometry as coordinate pairs
geometry_pairs = get_geometry(tz_name='Europe/Berlin', coords_as_pairs=True)
for i, polygon_with_holes in enumerate(geometry_pairs):
boundary = polygon_with_holes[0] # [(lng1, lat1), (lng2, lat2), ...]
print(f"Polygon {i}: First point {boundary[0]}")from timezonefinder import timezone_at
# Process multiple coordinates
coordinates = [
(13.358, 52.5061), # Berlin
(-74.0060, 40.7128), # New York
(139.6917, 35.6895), # Tokyo
(2.3522, 48.8566), # Paris
(-0.1276, 51.5074) # London
]
results = []
for lng, lat in coordinates:
tz = timezone_at(lng=lng, lat=lat)
results.append((lng, lat, tz))
print(f"({lat:.3f}, {lng:.3f}) -> {tz}")from timezonefinder import timezone_at, get_geometry
# Invalid coordinates
try:
tz = timezone_at(lng=200.0, lat=52.5061) # Invalid longitude
except ValueError as e:
print(f"Coordinate error: {e}")
# Invalid timezone name
try:
geometry = get_geometry(tz_name='Invalid/Timezone')
except ValueError as e:
print(f"Timezone error: {e}")
# Using timezone ID instead of name
try:
geometry = get_geometry(tz_id=0, use_id=True)
print("Successfully retrieved geometry by ID")
except ValueError as e:
print(f"ID error: {e}")Global functions are not thread-safe because they share a singleton TimezoneFinder instance. For concurrent access:
# ❌ NOT thread-safe
import threading
from timezonefinder import timezone_at
def worker(coordinates):
for lng, lat in coordinates:
tz = timezone_at(lng=lng, lat=lat) # Shared global instance
print(tz)
# This can cause issues with concurrent access
# ✅ Thread-safe alternative
import threading
from timezonefinder import TimezoneFinder
def safe_worker(coordinates):
tf = TimezoneFinder() # Each thread gets its own instance
for lng, lat in coordinates:
tz = tf.timezone_at(lng=lng, lat=lat)
print(tz)in_memory=TrueInstall with Tessl CLI
npx tessl i tessl/pypi-timezonefinder