Обработка даты/времени с учётом часового пояса в Python

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для сохранения сведений о часовом поясе используйте функцию parse из библиотеки python-dateutil. В отличие от strptime(), входящей в стандартную библиотеку и создающей объекты без учета часового пояса, функция parse корректно обрабатывает смещение часового пояса:

Python
Скопировать код
from dateutil import parser
dt = parser.parse("2023-02-20T14:30:00-05:00") # Экземпляр datetime с учетом часового пояса!

В этом случае функция parse учитывает смещение -05:00 и возвращает "осведомленный" объект datetime.

Кинга Идем в IT: пошаговый план для смены профессии

Работа со strftime и strptime

С использованием strptime() и директивы %z можно получить объекты datetime, которые содержат информацию о часовом поясе:

Python
Скопировать код
from datetime import datetime
datetime_obj = datetime.strptime("2023-04-01T14:30:00-0500", "%Y-%m-%dT%H:%M:%S%z")

Рекомендуется избегать использование директивы %Z с функцией strptime(), поскольку она может вызвать ошибки из-за неоднозначности обозначений часовых поясов (например, «EST»).

Ручная настройка часового пояса в объекте datetime

Если для объектов datetime используется известный фиксированный часовой пояс, можно вручную установить tzinfo:

Python
Скопировать код
from datetime import datetime, timezone, timedelta
naive_datetime = datetime.strptime("2023-04-01 14:30:00", "%Y-%m-%d %H:%M:%S")
aware_datetime = naive_datetime.replace(tzinfo=timezone(timedelta(hours=-5)))

Данный подход подходит в случае, когда не требуется динамичный разбор часового пояса из строки.

Разбор временных меток электронной почты с помощью функции parsedate_tz

Функция parsedate_tz из модуля email.utils идеально приспособлена для работы с часовыми поясами в строках с датами из email:

Python
Скопировать код
from email.utils import parsedate_tz, mktime_tz
date_tuple = parsedate_tz('Mon, 20 Feb 2023 14:30:00 -0500')
timestamp = mktime_tz(date_tuple) # Получаем корректную Unix-метку времени

В результате получаем временную метку с учетом сведений о часовом поясе.

Оценка использования альтернативных библиотек

Помимо python-dateutil, существуют другие библиотеки, например, pendulum, предоставляющие дополнительные возможности для работы с часовыми поясами:

Python
Скопировать код
import pendulum
dt = pendulum.parse("2023-02-20T14:30:00-05:00")

Визуализация

Представьте себе стену с часами, где указаны часы для различных городов и их часовых поясов, чтобы убедиться в правильности часового пояса:

Markdown
Скопировать код
Стена мировых часов:
| Город      | Время       | Часовой пояс               |
| ---------- | ------------ | -------------------------- |
| Нью-Йорк   | 12:00 PM     | EST 🗽                     |
| Лондон     | 05:00 PM     | GMT 🎡                     |
| Токио      | 02:00 AM     | JST 🗼                     |

Чтобы установить часовой пояс для объекта datetime, можно также воспользоваться модулем pytz:

Python
Скопировать код
from datetime import datetime
from pytz import timezone
new_york_time_str = "2023-04-01 12:00:00 EST"
pattern = "%Y-%m-%d %H:%M:%S %Z"
time_with_zone = timezone('US/Eastern').localize(datetime.strptime(new_york_time_str[:-4], pattern[:-3]))

Теперь у вас есть точное "время", синхронизированное с его часовым поясом.

Применение названий и смещений часовых поясов

Проверяйте сокращения различных часовых поясов. Чтобы вывести название часового пояса из объекта datetime, используйте функцию tzname():

Python
Скопировать код
from datetime import datetime, timezone
dt = datetime.now(timezone.utc)
print(dt.tzname())  # Выводит 'UTC'

Метод tzname() помогает извлечь название часового пояса из "осведомленных" объектов.

Корректировка временных меток для специфических случаев

Временами потребовать корректировки временных меток, особенно при работе с неоднозначными аббревиатурами, например, EST:

Python
Скопировать код
import pytz
timestamp = "2023-04-01 14:30:00 EST"
aus_tz = pytz.timezone('Australia/Sydney')
corrected_time = aus_tz.localize(datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S %Z"))

Полезные материалы

  1. datetime — Базовые типы даты и времени — Официальная документация Python по функциям strptime() и strftime().
  2. dateutil – расширения стандартного модуля datetime — Упрощенная работа с датами в Python.
  3. ISO 8601 – стандарт форматирования даты и времени — Википедия.
  4. Arrow: Даты и времена в Python без головной боли — Библиотека Python для работы с датами и временем.
  5. Документация Pendulum – удобство работы со временем в Python — Документация по API Pendulum для работы с datetime.
  6. Лучшие open-source инструменты для разработки 2024 — Подбор инструментов для работы с датами и временем.