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

Преобразование unixtime в объект datetime и обратно (пара функций преобразования времени, которые являются обратными)

Я пытаюсь написать пару функций dt и ut, которые преобразуют назад и вперед между нормальным временем unix (секунды с 1970-01-01 00:00:00 UTC) и дата и время Python объект.

Если dt и ut были правильными обратными, тогда этот код дважды печатает одну и ту же метку времени:

import time, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.fromtimestamp(u)
def ut(d): return time.mktime(d.timetuple())

u = 1004260000
print u, "-->", ut(dt(u))

Увы, вторая временная метка составляет 3600 секунд (час) меньше, чем первая. Я думаю, что это происходит только в самых разных ситуациях, возможно, в тот час, когда переход на летнее время проскакивает. Но есть ли способ написать dt и ut, чтобы они были истинными инверсиями друг друга?

Связанный вопрос: Создание matplotlib's date2num и num2date совершенные обратные

4b9b3361

Ответ 1

Вы правы, что это поведение связано с летним временем. Самый простой способ избежать этого - обеспечить, чтобы вы использовали часовой пояс без летнего времени, UTC имеет наибольший смысл здесь.

datetime.datetime.utcfromtimestamp() и calendar.timegm() справиться с UTC и являются точными инверсиями.

import calendar, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.utcfromtimestamp(u)
def ut(d): return calendar.timegm(d.timetuple())

Вот несколько объяснений, почему datetime.datetime.fromtimestamp() имеет проблему с летним временем, из документов:

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

Важная часть здесь заключается в том, что вы получаете наивный объект datetime.datetime, что означает, что информация о временной зоне (или летней экономии) отсутствует как часть объекта. Это означает, что несколько различных временных меток могут отображаться в одном и том же объекте datetime.datetime при использовании fromtimestamp(), если вам приходится выбирать время, которое падает во время летнего времени, откат:

>>> datetime.datetime.fromtimestamp(1004260000) 
datetime.datetime(2001, 10, 28, 1, 6, 40)
>>> datetime.datetime.fromtimestamp(1004256400)
datetime.datetime(2001, 10, 28, 1, 6, 40)