Получить часовой пояс для конкретной даты

У меня есть список дат, отформатированный следующим образом:

'2024-01-01`

Мне нужно превратить их в дату и время ISO следующим образом:

`2024-01-01T00:00:00-08:00`

Я думал, что это будет легко, я ошибался. Я видел много вопросов, посвященных этому на SO, но они склонны упускать из виду сложность перехода на летнее время (DST).

Что нельзя использовать в решении:

   datetime.now()

Использование datetime.now() даст текущий часовой пояс на сегодняшний день и не будет иметь отношения к рассматриваемой дате.

Мне нужно вернуть правильное смещение при преобразовании определенной даты в зависимости от того, какое смещение было бы по местному времени в рассматриваемую дату. Пример:

'2024-01-01' # becomes
'2024-01-01T00:00:00-08:00'

'2024-06-06' # becomes
'2024-01-01T00:00:00-07:00'

У меня есть решение, позволяющее перебрать это, рассчитав начало и конец летнего времени. Но это уродливое решение: нужно как-то манипулировать API datetime, чтобы оно работало лучше.

То, что вы пытаетесь сделать, невозможно. Учитывая дату «2024-01-01» (и это вся информация, которая у вас есть), как вы можете узнать, применялось ли летнее время в этот день, не зная, где в мире эта дата была применена к вашим данным?

SIGHUP 16.06.2024 08:35

@SIGHUP — у вас есть ОС машины, обрабатывающей данные. Вот где вы получаете часовой пояс.

Jamie Marshall 17.06.2024 18:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
from datetime import datetime
import pytz

def get_iso_datetime_with_timezone(date_str):
    date_obj = datetime.strptime(date_str, '%Y-%m-%d')

    aware_datetime_utc = pytz.utc.localize(date_obj)

    timezone = pytz.timezone('America/Los_Angeles')  # Example timezone, replace with your desired timezone

    aware_datetime_timezone = aware_datetime_utc.astimezone(timezone)

    iso_datetime_with_timezone = aware_datetime_timezone.strftime('%Y-%m-%dT%H:%M:%S%z')

    return iso_datetime_with_timezone

dates = ['2024-01-01', '2024-06-06']

for date_str in dates:
    iso_datetime_with_timezone = get_iso_datetime_with_timezone(date_str)
    print(f'{date_str} => {iso_datetime_with_timezone}')}

убедитесь, что вы заменили «Америка/Лос_Анжелес» на соответствующий часовой пояс для вашего варианта использования. Список поддерживаемых часовых поясов можно найти в документации pytz. pytz обрабатывает исторические данные часового пояса, поэтому правильно учитывает изменения летнего времени в указанную дату.

РЭШ ОТВЕТ

from datetime import datetime
from zoneinfo import ZoneInfo

def get_iso_datetime_with_timezone(date_str, tz_name='America/Los_Angeles'):
    # Parse input date string to naive datetime object
    date_obj = datetime.strptime(date_str, '%Y-%m-%d')
    
    aware_datetime = date_obj.replace(tzinfo=ZoneInfo(tz_name))
    
    iso_datetime_with_timezone = aware_datetime.isoformat()
    
    return iso_datetime_with_timezone


dates = ['2024-01-01', '2024-06-06']

for date_str in dates:
    iso_datetime_with_timezone = get_iso_datetime_with_timezone(date_str)
    print(f'{date_str} => {iso_datetime_with_timezone}')

Я тестирую это сейчас. строка, использующая astimezone, по крайней мере, неверна, потому что она фактически меняет дату и время (преобразует из utc), а не просто добавляет смещение.

Jamie Marshall 16.06.2024 05:38
aware_datetime_utc.astimezone(timezone) должно быть aware_datetime_utc.replace(tzinfo=timezone). Кроме того, мое тестирование дает смещение 07:53 независимо от летнего времени.
Jamie Marshall 16.06.2024 05:49

Итак, у меня все заработало. Оказывается питц обесценился и новый пакет здесь. Ценю, что вы направляете меня на правильный путь. Если вы хотите обновить свой ответ, я могу отметить его правильно.

Jamie Marshall 16.06.2024 05:58

Другие вопросы по теме