Python Створіть часову позначку Unix п'ять хвилин у майбутньому


297

У майбутньому я повинен створити значення "Закінчується" за 5 хвилин, але мені потрібно надати його у форматі UNIX Timestamp. У мене це є поки що, але це здається хаком.

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).


Дякую Д.Шоулі. довідка (datetime.timedelta) не вказала про цей ярлик. У ньому були лише дні, секунди та мікросекунди.
Даніель Роден

12
Слід зазначити, що поєднання двох попередніх коментарів, правильне рішення: calendar.timegm(future.utctimetuple()). Це забезпечує передачу часу на UTC calendar.timegm.
shadowmatter

1
Неможливо підтвердити коментар @ tumbleweed. Якщо ви намагаєтеся отримати часову позначку UNIX (і, отже, одну в UTC), використовуйте Calendar.timegm.
Bialecki

@tumbleweed, right. Якщо використовувати mktime плюс gmtime (0), це призведе до ненульової дельти в обидва часові пояси, крім UTC: наприклад, `time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))). Timetuple ())` дає 21600.0секунди (6 годин) замість 0,0 для TZ моєї машини Unix
варильні панелі

Якщо ви хочете , щоб отримати UTC мітка часу ви повинні використовувати це: calendar.timegm(datetime.datetime.utcnow().timetuple()). Використання методу datetime.datetime.now().utctimetuple()для мене не працює (Python 3.2).
Wookie88

155

Тепер у Python> = 3.3 ви можете просто зателефонувати методу timetamp (), щоб отримати позначку як float.

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 хвилин у майбутньому), тільки не заголовок.
дбр

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
EG це відповідь на питання "Час дати дати Python до часової позначки Unix", а Cat Plus Plus відповів на запитання "Час дати Python, який буде через 5 хвилин до часової позначки Unix". Тож ця чиста і очевидна.
працює.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: так, деякі місцеві часи неоднозначні чи не існують. Також зсув часового поясу може відрізнятися з інших причин, ніж DST (для встановлення правильного зміщення вам потрібна база даних tz, наприклад pytz). Місцевий час означає те, що місцевий політик вважає гарною ідеєю для вимірювання часу, тобто може бути дуже нерегулярним.
jfs

48

Ви можете використовувати час, datetime.strftimeщоб отримати час у формі епохи, використовуючи %sрядок формату:

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

Примітка. Це працює лише під Linux, і цей метод не працює з часовими поясами.


32
Це дещо недокументована поведінка ( python.org/doc/current/library/datetime.html ). Здається, працює під Linux та не працює під win32 (генерує ValueError: Invalid format string).
Антоні Хеткінс

3
Цей метод не працює з часовими поясами. Зміна часового поясу дасть такий самий результат datetime (2013,12,7, tzinfo = часовий пояс ("Америка / Чикаго")). Строку ("% s") 1386385200 datetime (2013,12,7, tzinfo = часовий пояс ("Європа / Рига ")). Стрімкінг ("% s ") 1386385200
Мартінс


6
def in_unix(input):
  start = datetime.datetime(year=1970,month=1,day=1)
  diff = input - start
  return diff.total_seconds()

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

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

1

Зауважте, що рішення з timedelta.total_seconds()роботою на python-2.7 +. Використовуйте calendar.timegm(future.utctimetuple())для нижчих версій Python.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.