Получить часовой пояс, используемый 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
, но это не так.
Ответы
Ответ 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>)