Подтвердить что ты не робот

Получить часовой пояс, используемый datetime.datetime.fromtimestamp()

Возможно ли, и если да, как получить часовой пояс (например, UTC offset или экземпляр datetime.timezone с этим смещением), который используется datetime.datetime.fromtimestamp() для преобразования временной метки POSIX (секунды с эпохи ) к объекту datetime?

datetime.datetime.fromtimestamp() преобразует временную метку POSIX в наивный объект datetime (т.е. без tzinfo), но делает это с использованием языкового стандарта системы, чтобы настроить его на локальный часовой пояс и смещение UTC, которое действовало на этом время.

Например, используя дату 2008-12-27 полуночи UTC (40 * 356 * 86400 секунд с эпохи):

>>> datetime.datetime.fromtimestamp(40 * 356 * 86400)
datetime.datetime(2008, 12, 27, 1, 0)

Эта временная метка преобразуется в объект datetime в 1 час ночи (что было тогда, здесь, в часовом поясе CET/CEST). Через 100 дней это результат:

>>> datetime.datetime.fromtimestamp((40 * 356 + 100) * 86400)
datetime.datetime(2009, 4, 6, 2, 0)

Это 2 часа ночи. Это связано с тем, что к тому времени DST был активным.

Я ожидал, что datetime.datetime.fromtimestamp() установит tzinfo, который он использует в возвращенном экземпляре datetime, но это не так.

4b9b3361

Ответ 1

datetime.fromtimestamp(ts) преобразует "секунды с эпохи" в наивный объект datetime, который представляет локальное время. tzinfo всегда None в этом случае.

Локальный часовой пояс, возможно, имел другое смещение UTC в прошлом. В некоторых системах, которые предоставляют доступ к базе данных хронологического времени, fromtimestamp() может принять это во внимание.

Чтобы получить смещение UTC, используемое fromtimestamp():

utc_offset = fromtimestamp(ts) - utcfromtimestamp(ts)

См. также Получение смещения компьютера utc в Python.

Ответ 2

Из документации Python:

classmethod datetime .fromtimestamp (timestamp, tz=None)

Возвращает локальную дату и время, соответствующие метке времени POSIX, например, возвращается time.time(). Если необязательный аргумент tz равен None или не указан, timestamp преобразуется в локальную дату и время платформы, а возвращаемый объект datetime является наивным.

В противном случае tz должен быть экземпляром подкласса класса tzinfo, а временная метка преобразуется в часовой пояс tz. В этом случае результат эквивалентен tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz)).

Ключевая часть этого описания в том, что касается вашего вопроса, состоит в том, что когда вы не указываете часовой пояс, он не только использует локальный часовой пояс, но и результат наивный. Вы, кажется, хотите, чтобы это было в курсе.

Это особое различие, сделанное Python, и обсуждается в самом верху документации datetime.

Если то, что вы хотите это datetime, который знает о местном часовом поясе, попробуйте tzlocal библиотеку. Он сосредоточен на этой конкретной проблеме. Смотрите также этот вопрос.

Ответ 3

Используя time.gmtime, вы можете извлечь часовой пояс, как описано в этом предыдущем ответе: Получить информацию TZ о системе в Python?.

>>> from __future__ import print_function
>>> from time import gmtime, strftime
>>> print(strftime("%z", gmtime()))
-0600

Печать -06: 00 для моего ноутбука CST в обоих версиях python-2.7 и python-3.3 Вы также можете использовать localtime() для создания локальной структуры времени.

>>> from __future__ import print_function
>>> from time import localtime
>>> lt = localtime()
>>> print(lt.tm_zone)
"CDT"
>>> print(lt.tm_gmtoff/(60*60))
-5.0
>>> print(lt.tm_gmtoff/(60*60) - (1 if lt.tm_isdst == 1 else 0)) # Adjusted for DST
-6.0

Надеюсь, что это поможет

Ответ 4

Если вам известен часовой пояс метки времени, которую вы хотите преобразовать, вы можете просто отправить ее во время вызова fromtimestamp:

>>> from datetime import datetime
>>> import pytz
>>>
>>> datetime.fromtimestamp(1562684265, pytz.timezone("Europe/Stockholm"))
datetime.datetime(2019, 7, 9, 16, 57, 45, tzinfo=<DstTzInfo 'Europe/Stockholm' CEST+2:00:00 DST>)
>>>
>>> datetime.fromtimestamp(1562684265, pytz.timezone("UTC"))
datetime.datetime(2019, 7, 9, 14, 57, 45, tzinfo=<UTC>)