Решён
Как определить точное время по координатам?

Иван Черных Python
2.6k
5

Пишу приложение на Python, нужно по GPS-координатам (широта, долгота) определить точное местное время в этой точке. Имею в виду не просто часовой пояс UTC+N, а именно актуальное время с учетом летнего/зимнего перевода часов, если он действует в этой стране.

Пробовал через pytz с ручным маппингом, но там ад с boundaries часовых поясов. Координаты могут быть любыми, включая границы между поясами и всякие аномалии типа Китая (весь на UTC+8) или Индии (UTC+5:30).

Есть ли нормальная библиотека для Python, которая берет lat/lon и возвращает timezone? Желательно оффлайн, без API-запросов.

UPDATE: timezonefinder + zoneinfo заработало идеально, даже пограничные кейсы ловит. Спасибо всем!
Решение
47
Участник • 4 ответа

timezonefinder - то что нужно. Работает оффлайн, использует полигоны часовых поясов из базы timezone-boundary-builder (на основе OpenStreetMap).

from timezonefinder import TimezoneFinder
from datetime import datetime
from zoneinfo import ZoneInfo

tf = TimezoneFinder()

lat, lon = 55.7558, 37.6173  # Москва
tz_name = tf.timezone_at(lng=lon, lat=lat)
# 'Europe/Moscow'

now = datetime.now(ZoneInfo(tz_name))
print(now)  # текущее местное время в этой точке

Установка:

pip install timezonefinder[numba]

С флагом [numba] работает в 20 раз быстрее за счет JIT-компиляции. Без numba тоже работает, просто медленнее.

Нюансы:

  • Используй zoneinfo (стандартная библиотека с Python 3.9) вместо pytz. У pytz кривая работа с DST, zoneinfo это исправляет.
  • Для Python 3.8 и ниже ставь backports.zoneinfo.
  • timezonefinder корректно обрабатывает все аномалии: Китай, Индия, Непал (UTC+5:45), Чатемские острова (UTC+12:45).
  • На океанах и нейтральных водах вернет None, там нет timezone. Можно задать fallback через tf.certain_timezone_at() или tf.closest_timezone_at().
Аватар Иван Черных

Огонь, именно это искал. Про zoneinfo вместо pytz не знал, спасибо за наводку

9
Эксперт • 5 ответов

Если нужна максимальная скорость и не критична точность на границах поясов, посмотри tzwhere. Он легче чем timezonefinder, но давно не обновлялся (последний релиз 2017). Для большинства задач хватит.

from tzwhere import tzwhere
tz = tzwhere.tzwhere()
tz_name = tz.tzNameAt(55.7558, 37.6173)

Но если прод и нужна актуальная база, бери timezonefinder, как выше написали.

Аватар Макс

tzwhere deprecated уже лет 5 как, не советуй его людям в 2026. timezonefinder его полностью заменил и активно поддерживается

3
Участник • 3 ответа

А зачем оффлайн? Если координат не миллионы в секунду, Google Time Zone API решает задачу в одну строку. Бесплатный лимит 2500 запросов в день.

Ну или если прям бесплатно-бесплатно, через OpenStreetMap Nominatim можно получить адрес по координатам, а из адреса вытащить страну и маппить на timezone. Костыльно, зато без зависимостей.

22
Участник • 3 ответа

Осторожно с pytz, раз уж ты его упомянул. Классическая ловушка:

# НЕПРАВИЛЬНО (pytz)
import pytz
from datetime import datetime
dt = datetime(2026, 6, 15, 12, 0, tzinfo=pytz.timezone("Europe/Moscow"))
# Получишь UTC+02:30:17 вместо UTC+03:00 (!!)

# ПРАВИЛЬНО (pytz)
dt = pytz.timezone("Europe/Moscow").localize(datetime(2026, 6, 15, 12, 0))

pytz хранит историческое смещение LMT (Local Mean Time) как дефолт, и если передать timezone в конструктор datetime напрямую, получишь мусор. Поэтому да, zoneinfo это спасение. Там таких багов нет.

14
Эксперт • 5 ответов

Забавный факт: в мире существует 38 различных смещений UTC, включая UTC+5:30 (Индия), UTC+5:45 (Непал), UTC+8:45 (Юкла, Австралия) и UTC+13 (Тонга, которое фактически "завтра" относительно UTC-11 Самоа, при том что эти острова рядом).

Таймзоны это один из самых хаотичных доменов в программировании. Сохрани себе ссылку: https://www.youtube.com/watch?v=-5wpm-gesOY (Tom Scott, "The Problem with Time & Timezones"). Лучшее объяснение почему все так сложно.

Написать ответ

Премодерация гостей

Вы отвечаете как гость. Ваш ответ будет скрыт до проверки модератором. Чтобы ответ появился сразу и вы получали репутацию — войдите в аккаунт.

Будьте вежливы и соблюдайте правила платформы.