Как преобразовать объект даты и времени или даты в метку времени POSIX в python? Существуют методы создания объекта даты и времени из метки времени, но я, похоже, не нашел очевидных способов выполнить операцию в обратном порядке.
Преобразование даты и времени в время POSIX
Ответы (6)
Для вычислений UTC calendar.timegm
является обратным time.gmtime
.
import calendar, datetime
d = datetime.datetime.utcnow()
print calendar.timegm(d.timetuple())
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
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)
now
— это объект даты и времени, не зависящий от часового пояса, и вызов .timestamp
для него сначала будет предполагать, что объект находится в локальном времени (что так и есть — неявно и, к счастью), а затем выполнить преобразование, чтобы предоставить временную метку, совместимую с posix (секунды с UTC Unix). время).
- person Marc; 18.11.2020
# Local time
в примере рядом с вызовом now.timestamp()
. Можете ли вы уточнить, в чем проблема?
- person Clément; 18.11.2020
now.timestamp()
дает вам отметку времени, совместимую с posix, и здесь это правильная отметка времени эпохи Unix utc, поскольку now
в этот момент является наивной отметкой времени с неявным использованием вашего местного часового пояса. При вызове .timestamp
для наивного объекта даты и времени предполагается местный часовой пояс (что это такое) и дать вам правильную метку времени UTC unix. Однако, когда вы вызываете replace
, никаких преобразований в объект datetime не выполняется, он просто преобразует now
из наивного → осведомленного. И это кажется неправильным в большинстве случаев.
- person Marc; 18.11.2020
now
не имеет значения в этом ответе. Не стесняйтесь редактировать его, чтобы вместо этого отображался литерал даты.
- person Clément; 18.11.2020
now
актуален только из-за того, как он влияет на вывод now.timestamp()
. Чтобы убрать now
из этого разговора, мы можем сделать datetime.datetime.now().replace(tzinfo=datetime.timezone.utc).timestamp()
это так же хорошо, как datetime.datetime.utcnow().timestamp()
. У них обоих одна и та же проблема, .timestamp()
, скорее всего, примет неправильный часовой пояс. Время сбивает с толку, поэтому я могу ошибаться, но я так понимаю документацию.
- person Marc; 19.11.2020
now()
в моем ответе, если хотите, чтобы это было так, что я только что сделал.
- person Clément; 19.11.2020
.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
Лучшее преобразование из 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)
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 часто предполагает, что это местное время, и может вас запутать).
ПРИМЕЧАНИЕ: также будьте осторожны с пониманием эпохи, поскольку она зависит от платформы
mktime
ожидает в качестве входных данных местное время, а выходные данные не имеют часового пояса — это отметка времени Unix, которая представляет собой продолжительность, измеренную в секундах (и всегда от эпохи, что дает вам время ). (datetime.now()
возвращает текущее местное время.)
- person Thanatos; 27.04.2013
timetuple()
. Таким образом, при выполнении этого преобразования точность теряется.
- person Shaun; 03.10.2016
time.mktime(datetime(2016,2,4,tzinfo=timezone.utc).utctimetuple())
дает 1454533200
, но должен дать 1454544000
- person Dims; 04.12.2018
.timestamp()
объектовdatetime.datetime
, как указано ниже. Пожалуйста, отметьте это как правильный ответ. - person Giorgio Balestrieri   schedule 17.12.2018.timestamp()
вы используете объект даты с учетом часового пояса как наивный часовой пояс предполагает местное время. - person Marc   schedule 18.11.2020