Преобразование даты и времени в время POSIX

Как преобразовать объект даты и времени или даты в метку времени POSIX в python? Существуют методы создания объекта даты и времени из метки времени, но я, похоже, не нашел очевидных способов выполнить операцию в обратном порядке.


person Jason Baker    schedule 31.10.2008    source источник
comment
Ответы на этот вопрос уже не актуальны. Вы должны использовать метод .timestamp() объектов datetime.datetime, как указано ниже. Пожалуйста, отметьте это как правильный ответ.   -  person Giorgio Balestrieri    schedule 17.12.2018
comment
Также убедитесь, что при вызове .timestamp() вы используете объект даты с учетом часового пояса как наивный часовой пояс предполагает местное время.   -  person Marc    schedule 18.11.2020


Ответы (6)


Для вычислений UTC calendar.timegm является обратным time.gmtime.

import calendar, datetime
d = datetime.datetime.utcnow()
print calendar.timegm(d.timetuple())
person fixermark    schedule 03.05.2011
comment
Примечание. calendar.timegm() ожидает ввода в формате UTC, но результат (отметка времени) не относится ни к одному часовому поясу. Прошло всего несколько секунд с начала эпохи (== 1969-12-31T19:00:00-05:00 (Нью-Йорк) == 1970-01-01T00:00:00Z (UTC) == 1970-01-01T03: 00:00+03:00 (Москва)) -- единый фиксированный момент времени. - person jfs; 17.11.2013
comment
Исправление: из-за дополнительных дополнительных секунд секунды с начала Эпохи не являются прошедшими секундами СИ с 1970-01-01 00:00:00+00:00. utc_to_tai()функция может использоваться для вычисления прошедших секунд СИ. - person jfs; 06.09.2014

Обратите внимание, что Python теперь (3.5.2) включает встроенный метод для этого в datetime объектах:

>>> import datetime
>>> now = datetime.datetime(2020, 11, 18, 18, 52, 47, 874766)
>>> now.timestamp() # Local time
1605743567.874766
>>> now.replace(tzinfo=datetime.timezone.utc).timestamp() # UTC
1605725567.874766 # 5 hours delta (I'm in UTC-5)
person Clément    schedule 30.10.2017
comment
Вы уверены, что это правильно? now — это объект даты и времени, не зависящий от часового пояса, и вызов .timestamp для него сначала будет предполагать, что объект находится в локальном времени (что так и есть — неявно и, к счастью), а затем выполнить преобразование, чтобы предоставить временную метку, совместимую с posix (секунды с UTC Unix). время). - person Marc; 18.11.2020
comment
@Marc Марк, я не понимаю вашего комментария: я прямо говорю # Local time в примере рядом с вызовом now.timestamp(). Можете ли вы уточнить, в чем проблема? - person Clément; 18.11.2020
comment
now.timestamp() дает вам отметку времени, совместимую с posix, и здесь это правильная отметка времени эпохи Unix utc, поскольку now в этот момент является наивной отметкой времени с неявным использованием вашего местного часового пояса. При вызове .timestamp для наивного объекта даты и времени предполагается местный часовой пояс (что это такое) и дать вам правильную метку времени UTC unix. Однако, когда вы вызываете replace, никаких преобразований в объект datetime не выполняется, он просто преобразует now из наивного → осведомленного. И это кажется неправильным в большинстве случаев. - person Marc; 18.11.2020
comment
О, часть now не имеет значения в этом ответе. Не стесняйтесь редактировать его, чтобы вместо этого отображался литерал даты. - person Clément; 18.11.2020
comment
now актуален только из-за того, как он влияет на вывод now.timestamp(). Чтобы убрать now из этого разговора, мы можем сделать datetime.datetime.now().replace(tzinfo=datetime.timezone.utc).timestamp() это так же хорошо, как datetime.datetime.utcnow().timestamp(). У них обоих одна и та же проблема, .timestamp(), скорее всего, примет неправильный часовой пояс. Время сбивает с толку, поэтому я могу ошибаться, но я так понимаю документацию. - person Marc; 19.11.2020
comment
Все, что я говорю, это то, что вы можете просто удалить вызов now() в моем ответе, если хотите, чтобы это было так, что я только что сделал. - person Clément; 19.11.2020
comment
Внесенные изменения не устранили проблему. Он по-прежнему имеет дело с наивным объектом даты и времени часового пояса. Ваше предыдущее решение было на самом деле ближе к истине, чем эта текущая итерация. - person Marc; 19.11.2020
comment
Все, что делает этот ответ, это указывает вам на существование .timestamp(); если у вас есть наивная метка времени, Python делает предположение о том, что означает ваша дата и время; в противном случае ему не нужно угадывать. Если вы хотите убедиться, что он не угадывает, вы можете установить tzinfo вашего datetime. - person Clément; 19.11.2020

В python time.time() может возвращать секунды как число с плавающей запятой, которое включает десятичный компонент с микросекундами. Чтобы преобразовать дату и время обратно в это представление, вы должны добавить компонент микросекунд, потому что прямой timetuple не включает его.

import time, datetime

posix_now = time.time()

d = datetime.datetime.fromtimestamp(posix_now)
no_microseconds_time = time.mktime(d.timetuple())
has_microseconds_time = time.mktime(d.timetuple()) + d.microsecond * 0.000001

print posix_now
print no_microseconds_time
print has_microseconds_time
person gnu_lorien    schedule 16.01.2013
comment
не используйте местное время для поездки туда и обратно (ts -> местное -> ts). Он может сломаться во время перехода на летнее время. Вы можете легко расширить timegm(), чтобы включить микросекунды и использовать его для преобразований ts -> utc -> ts. - person jfs; 18.11.2013

Лучшее преобразование из posix/epoch в временную метку даты и времени и наоборот:

this_time = datetime.datetime.utcnow() # datetime.datetime type
epoch_time = this_time.timestamp()      # posix time or epoch time
this_time = datetime.datetime.fromtimestamp(epoch_time)
person vishal    schedule 23.09.2019
comment
utcnow выводит наивный объект даты и времени с часовым поясом, и при запуске .timestamp() на нем python будет предполагать локальный часовой пояс (даже если это наивный UTC, а не локальный наивный), и это должно дать вам неверную обратную связь. - person Marc; 18.11.2020

Это зависит

Ваш часовой пояс объекта datetime известен или наивен?

С учетом часового пояса

Если это известно, это просто

from datetime import datetime, timezone
aware_date = datetime.now(tz=timezone.utc)
posix_timestamp = aware_date.timestamp()

поскольку date.timestamp() дает временную метку POSIX

ПРИМЕЧАНИЕ: правильнее называть это временной меткой эпохи/unix как возможно, он несовместим с POSIX

Наивный часовой пояс

Если он не знает часовой пояс (наивно), вам нужно знать, в каком часовом поясе он был изначально, чтобы мы могли использовать replace(), чтобы преобразовать его в объект даты с учетом часового пояса. Предположим, что вы сохранили/извлекли его как UTC Naive. Здесь мы создаем один, в качестве примера:

from datetime import datetime, timezone
naive_date = datetime.utcnow()  # this date is naive, but is UTC based
aware_date = naive_date.replace(tzinfo=timezone.utc)  # this date is no longer naive

# now we do as we did with the last one

posix_timestamp = aware_date.timestamp()

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

ПРИМЕЧАНИЕ: также будьте осторожны с пониманием эпохи, поскольку она зависит от платформы

person Marc    schedule 18.11.2020

person    schedule
comment
Спасибо. Я знал, что это должно быть что-то до глупости простое, но не мог понять. - person Jason Baker; 01.11.2008
comment
Кажется, что в зависимости от платформы время не имеет метода mktime - person Tirno; 20.03.2009
comment
Обратите внимание, что это дает местное время, а не UTC. Для UTC см. ответ fixermark. - person Craig McQueen; 24.11.2011
comment
Чтобы быть точным: обратите внимание, что mktime ожидает в качестве входных данных местное время, а выходные данные не имеют часового пояса — это отметка времени Unix, которая представляет собой продолжительность, измеренную в секундах (и всегда от эпохи, что дает вам время ). (datetime.now() возвращает текущее местное время.) - person Thanatos; 27.04.2013
comment
существует 50% вероятность того, что он вернет неверный результат во время перехода на летнее время. См. Проблемы с локальным временем. - person jfs; 17.11.2013
comment
Обратите внимание, что, поскольку временные метки posix имеют точность только до секунды, дата и время усекаются до секунды на шаге timetuple(). Таким образом, при выполнении этого преобразования точность теряется. - person Shaun; 03.10.2016
comment
Это неправильно. time.mktime(datetime(2016,2,4,tzinfo=timezone.utc).utctimetuple()) дает 1454533200, но должен дать 1454544000 - person Dims; 04.12.2018