Python Создать метку времени Unix через пять минут

297

Я должен создать значение «Expires» через 5 минут в будущем, но я должен предоставить его в формате метки времени UNIX. У меня это пока что, но похоже на взлом.

def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    epoch = datetime.datetime(1970, 1, 1)
    seconds_in_a_day = 60 * 60 * 24
    five_minutes = datetime.timedelta(seconds=5*60)
    five_minutes_from_now = datetime.datetime.now() + five_minutes
    since_epoch = five_minutes_from_now - epoch
    return since_epoch.days * seconds_in_a_day + since_epoch.seconds

Есть ли модуль или функция, которая выполняет преобразование метки времени для меня?

Даниэль Роден
источник
7
Я рекомендую сменить тему этого вопроса. Вопрос хороший, но речь не идет о преобразовании даты и времени в метку времени Unix. Речь идет о том, как получить метку времени Unix через 5 минут в будущем.
DA
Я не согласен, @DA Вопрос, по сути, говорит: «Мне нужно сделать X и Y. Вот что у меня сейчас. Какой лучший способ сделать Y?» Может быть, есть лучшие способы сделать X, но название и текст четко спрашивают о Y.
Роб Кеннеди
6
Я полностью согласен с вами по этому вопросу и считаю, что это хороший вопрос с хорошим ответом. Проблема в том, что «метка времени Python для Unix» не отражает ни вопрос, ни ответ. Я нашел этот пост, ищущий способ сделать преобразование, и я потерял время из-за вводящей в заблуждение строки темы. Я предлагаю: «Python, 5 минут в будущем как UNIX Timestamp»
DA
3
@JimmyKane - довольно полный ответ о том, как получить временную метку из даты, можно найти здесь: stackoverflow.com/questions/8777753/…
Тим Тисдалл
@TimTisdall да, так как название изменено, это не имеет никакого смысла
Джимми Кейн

Ответы:

349

Другой способ заключается в использовании calendar.timegm:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return calendar.timegm(future.timetuple())

Он также более переносим, ​​чем %sфлаг strftime(который не работает в Windows).

Cat Plus Plus
источник
Спасибо Д. Шоули. помощь (datetime.timedelta) не упомянул этот ярлык. У него были только дни, секунды и микросекунды.
Даниэль Роден
12
Следует отметить, что сочетание двух предыдущих комментариев, правильное решение: calendar.timegm(future.utctimetuple()). Это гарантирует, что время UTC передается в calendar.timegm.
shadowmatter
1
Невозможно поднять комментарий @ повороты. Если вы пытаетесь получить метку времени UNIX (и, следовательно, одну в UTC), используйте calendar.timegm.
Бялецкий,
@ правильно, верно. Если вы используете mktime, плюс gmtime (0) приведет к ненулевой дельте туда и обратно для любого часового пояса, кроме UTC: например, `time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))). Timetuple ())` даёт 21600.0секунды (6 часов) вместо 0.0 для TZ моей машины с Unix
hobs
Если вы хотите , чтобы получить UTC метка времени вы должны использовать это: calendar.timegm(datetime.datetime.utcnow().timetuple()). Использование метода datetime.datetime.now().utctimetuple()не работает для меня (Python 3.2).
Wookie88
155

Теперь в Python> = 3.3 вы можете просто вызвать метод timestamp (), чтобы получить метку времени как число с плавающей точкой.

import datetime
current_time = datetime.datetime.now(datetime.timezone.utc)
unix_timestamp = current_time.timestamp() # works if Python >= 3.3

unix_timestamp_plus_5_min = unix_timestamp + (5 * 60)  # 5 min * 60 seconds
Тим Тисдалл
источник
4
+1 за это. Это должно быть отображено намного выше, потому что это чистый способ, как это сделать в Python 3
Виктор Стискала
2
@ scott654 Я думал, что в начале комментария это было достаточно ясно, но я также добавил к нему немного смелости.
Тим Тисдалл
1
Я бы сделал примечание в качестве комментария в блоке кода, потому что мы все сначала сканируем код в ответах, а остальное читаем только в том случае, если код выглядит хорошо. Хороший ответ, хотя.
Мэтью Пурдон
2
местное время может быть неоднозначным . Пример ( datetime.now()) плох, потому что он поощряет использование наивных объектов даты и времени, которые представляют местное время, и может потерпеть неудачу во время переходов DST (из-за присущей неоднозначности). Вы могли бы использовать ts = datetime.now(timezone.utc).timestamp()вместо этого.
JFS
@JFSebastian - хорошая мысль. Я не хотел добавлять к импорту, поэтому я изменил его на utcnow(). Я привык работать на машинах, где часовой пояс установлен на UTC, но в этом фрагменте кода это не следует предполагать.
Тим Тисдалл
139

Просто нашел это, и это еще короче.

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)
Даниэль Роден
источник
12
Это не отвечает на вопрос.
Джесси Диллон
22
@JesseDhillon отвечает на вопрос (сделайте отметку времени UNIX через 5 минут в будущем), но не в заголовке.
2012 года
3
time.time()может быть установлен обратно. Для создания значения «Истекает» через 5 минут в будущем вам может понадобиться time.monotonic()аналог в зависимости от вашего варианта использования.
JFS
@ jf-sebastian time.monotonic () не возвращает метку времени UNIX, она возвращает метку времени с неопределенной контрольной точкой.
rspeer
@rspeer: да, как говорят в документах, допустима только разница между последовательными вызовами. Возможность monotonicиспользования зависит от вашего варианта использования, например, subprocessмодуль использует его для реализации timeoutопции.
Jfs
57

Это то, что вам нужно:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())
Али
источник
Чем это отличается или добавляет к «Cat Plus Plus»?
Дэвид
3
Например, это ответ на вопрос «Python datetime to Unix timestamp», в то время как Cat Plus Plus ответил на вопрос «Python datetime, который будет через 5 минут до Unix timestamp». Так что этот чистый и очевидный.
running.t
@ running.t: это напоминает мне: «каждая проблема имеет простое, очевидное и неправильное решение». Смотрите возможные проблемы сmktime(dt.timetuple()) . datetime.now(timezone.utc).timestamp()предоставленное @Tim Tisdall - решение в Python 3.3+. В противном случае (dt - epoch).total_seconds()может быть использовано .
JFS
@JFSebastian, что если я действительно хочу, чтобы все вычисления происходили по местному времени? Это тот случай, когда, например. проанализировать наивную строку, известную как местное время, и решить, действовал ли DST в это конкретное время?
n611x007
1
@naxa: да, некоторые локальные времена неоднозначны или вообще отсутствуют. Также смещение часового пояса может отличаться по причинам, отличным от летнего времени (вам нужна база данных tz, например, pytz, чтобы узнать правильное смещение). Местное время означает, что все, что местный политик считает хорошей идеей для измерения времени, т. Е. Оно может быть очень нерегулярным.
JFS
48

Вы можете использовать, datetime.strftimeчтобы получить время в форме Epoch, используя %sстроку формата:

def expires():
    future = datetime.datetime.now() + datetime.timedelta(seconds=5*60)
    return int(future.strftime("%s"))

Примечание: это работает только под Linux, и этот метод не работает с часовыми поясами.

mipadi
источник
32
Это несколько недокументированное поведение ( python.org/doc/current/library/datetime.html ). Кажется, работает под Linux и не работает под Win32 (генерации ValueError: Invalid format string).
Энтони Хэтчкинс
3
Этот метод не работает с часовыми поясами. Изменение часового пояса даст тот же результат datetime (2013,12,7, tzinfo = timezone ("America / Chicago")). Strftime ("% s") 1386385200 datetime (2013,12,7, tzinfo = timezone ("Europe / Рига ")). Strftime ("% s ") 1386385200
Мартинс Балодис
6
def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()
Sravan
источник
4

Ключ должен гарантировать, что все даты, которые вы используете, находятся в часовом поясе utc, прежде чем вы начнете конвертировать. Смотрите http://pytz.sourceforge.net/, чтобы узнать, как это сделать правильно. Нормализуя до utc, вы устраняете неоднозначность переходов на летнее время. Затем вы можете безопасно использовать timedelta для расчета расстояния от эпохи Unix, а затем преобразовать в секунды или миллисекунды.

Обратите внимание, что полученная метка времени Unix сама находится в часовом поясе UTC. Если вы хотите увидеть метку времени в локализованном часовом поясе, вам нужно будет выполнить другое преобразование.

Также обратите внимание, что это будет работать только для дат после 1970 года.

   import datetime
   import pytz

   UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, tzinfo = pytz.utc)
   def EPOCH(utc_datetime):
      delta = utc_datetime - UNIX_EPOCH
      seconds = delta.total_seconds()
      ms = seconds * 1000
      return ms
fawce
источник
3
примечание: я не понимаю "метку времени [unix] в локализованном часовом поясе". Отметка времени совпадает (прошедшие секунды с тех пор 1970-01-01 00:00:00+00:00). Чтобы получить наивный объект даты и времени в местном часовом поясе:datetime.fromtimestamp(ts)
JFS
4

Нижеследующее основано на ответах выше (плюс поправка на миллисекунды) и эмулируется datetime.timestamp()для Python 3 до 3.3, когда используются часовые пояса.

def datetime_timestamp(datetime):
    '''
    Equivalent to datetime.timestamp() for pre-3.3
    '''
    try:
        return datetime.timestamp()
    except AttributeError:
        utc_datetime = datetime.astimezone(utc)
        return timegm(utc_datetime.timetuple()) + utc_datetime.microsecond / 1e6

Чтобы строго ответить на вопрос в том виде, в котором он был задан, вы бы хотели:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestampявляется частью простой даты . Но если бы вы использовали этот пакет, вы, вероятно, набрали бы:

SimpleDate(my_datetime).timestamp + 5 * 60

который обрабатывает много других форматов / типов для my_datetime.

Эндрю Кук
источник
Разве вы не должны добавить (5 * 60), чтобы добавить 5 минут? Я думаю, что просто добавление 5 добавляет только 5 секунд к отметке времени.
Тим Тисдалл
1
def expiration_time():
    import datetime,calendar
    timestamp = calendar.timegm(datetime.datetime.now().timetuple())
    returnValue = datetime.timedelta(minutes=5).total_seconds() + timestamp
    return returnValue
hd1
источник
1

Обратите внимание, что решения с timedelta.total_seconds()работой на Python-2.7 +. Используйте calendar.timegm(future.utctimetuple())для более низких версий Python.

mighq
источник