Python Crea un timestamp unix cinque minuti in futuro


297

Devo creare un valore "Scadenza" 5 minuti in futuro, ma devo fornirlo in formato UNIX Timestamp. Finora ho questo, ma sembra un trucco.

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

Esiste un modulo o una funzione che esegue la conversione data / ora per me?


7
Raccomando di cambiare l'oggetto di questa domanda. La domanda è buona, ma non si tratta di convertire datetime in timestamp Unix. Si tratta di come ottenere un timestamp Unix 5 minuti in futuro.
DA

Non sono d'accordo, @DA La domanda essenzialmente dice "Devo fare X e Y. Ecco cosa ho adesso. Qual è il modo migliore per fare Y?" Forse ci sono modi migliori per fare X, ma il titolo e il corpo chiedono chiaramente di Y.
Rob Kennedy,

6
Sono completamente d'accordo con te sulla domanda e la ritengo una buona risposta. Il problema è che "Python datetime to Unix timestamp" non riflette né la domanda né la risposta. Ho trovato questo post alla ricerca di un modo per eseguire la conversione e ho perso tempo a causa della linea dell'oggetto fuorviante. Suggerisco: "Python, 5 minuti nel futuro come UNIX Timestamp"
DA

3
@JimmyKane - Una risposta abbastanza completa su come ottenere un timestamp da una data può essere trovata qui: stackoverflow.com/questions/8777753/…
Tim Tisdall,

@TimTisdall sì poiché il titolo è cambiato non ha senso
Jimmy Kane,

Risposte:


349

Un altro modo è usare calendar.timegm:

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

È anche più portabile di %sflag to strftime(che non funziona su Windows).


Grazie D.Shawley. help (datetime.timedelta) non ha menzionato quella scorciatoia. Aveva solo giorni, secondi e microsecondi.
Daniel Rhoden,

12
Si noti che, combinando le due precedenti osservazioni, la soluzione giusta è: calendar.timegm(future.utctimetuple()). Ciò garantisce che venga passato un orario UTC calendar.timegm.
Shadowmatter

1
Non posso esprimere abbastanza il commento di @ tumbleweed. Se stai cercando di ottenere un timestamp UNIX (e quindi uno in UTC), usa calendar.timegm.
Bialecki,

@tumbleweed, giusto. Se usi mktime più gmtime (0) comporterà delta di andata e ritorno diverso da zero per qualsiasi fuso orario oltre a UTC: ad es. `Time.mktime (datetime.fromtimestamp (time.mktime (time.gmtime (0))). Timetuple ())` fornisce 21600.0secondi (6 ore) anziché 0,0 per la TZ della mia macchina unix
piani cottura

Se si desidera ottenere UTC timestamp si dovrebbe usare questo: calendar.timegm(datetime.datetime.utcnow().timetuple()). L'uso del metodo datetime.datetime.now().utctimetuple()non funziona per me (Python 3.2).
Wookie88,

155

Ora in Python> = 3.3 puoi semplicemente chiamare il metodo timestamp () per ottenere il timestamp come 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 per questo. Dovrebbe essere visualizzato molto più in alto, perché è il modo pulito come farlo in Python 3
Viktor Stískala

2
@ scott654 Ho pensato che averlo fatto all'inizio del commento lo rendesse abbastanza chiaro, ma ho aggiunto anche un po 'di audace.
Tim Tisdall,

1
Prenderei la nota come commento nel blocco di codice perché prima scansioniamo tutti il ​​codice nelle risposte e leggiamo il resto solo se il codice sembra buono. Buona risposta però.
Matthew Purdon,

2
l'ora locale può essere ambigua . L'esempio ( datetime.now()) è errato perché incoraggia l'uso di oggetti datetime ingenui che rappresentano l'ora locale e potrebbe non riuscire durante le transizioni dell'ora legale (a causa dell'ambiguità intrinseca). ts = datetime.now(timezone.utc).timestamp()Invece potresti usare .
jfs,

@JFSebastian - buon punto. Non volevo aggiungere altre importazioni, quindi l'ho cambiato in utcnow(). Sono abituato a lavorare su macchine in cui il fuso orario è impostato su UTC, ma ciò non dovrebbe essere assunto in questo frammento di codice.
Tim Tisdall,

139

Ho appena trovato questo ed è ancora più breve.

import time
def expires():
    '''return a UNIX style timestamp representing 5 minutes from now'''
    return int(time.time()+300)

12
Questo non risponde alla domanda.
Jesse Dhillon,

22
@JesseDhillon risponde alla domanda (fare un timestamp UNIX 5 minuti in futuro), non solo il titolo.
dbr

3
time.time()può essere arretrato. Per creare un valore "Scadenza" 5 minuti in futuro, potrebbe essere necessario un time.monotonic()analogo a seconda del caso d'uso.
jfs

@ jf-sebastian time.monotonic () non restituisce un timestamp UNIX, restituisce un timestamp con un punto di riferimento indefinito.
rspeer,

@rspeer: sì, come dicono i documenti , è valida solo la differenza tra chiamate consecutive. L'eventuale monotonicutilizzo dipende dal caso d'uso, ad es. Il subprocessmodulo lo utilizza per implementare l' timeoutopzione.
jfs,

57

Questo è quello di cui hai bisogno:

import time
import datetime
n = datetime.datetime.now()
unix_time = time.mktime(n.timetuple())

In che modo differisce o si aggiunge a quello 'Cat Plus Plus' fornito?
David,

3
Ad esempio, questa è la risposta alla domanda "Python datetime al timestamp di Unix" mentre Cat Plus Plus ha risposto alla domanda "Python datetime che sarà tra 5 minuti al timestamp di Unix". Quindi questo è pulito ed evidente.
running.t

@ running.t: mi ricorda: "ogni problema ha una soluzione semplice, ovvia e sbagliata ". Vedi possibili problemi conmktime(dt.timetuple()) . datetime.now(timezone.utc).timestamp()fornito da @Tim Tisdall è la soluzione in Python 3.3+. Altrimenti (dt - epoch).total_seconds()potrebbe essere usato .
jfs

@JFSebastian e se davvero volessi che tutti i calcoli avessero luogo in ora locale? È il caso quando ad es. analizzare una stringa ingenua che si conosce è l'ora locale e decidere se in quel determinato momento era in vigore l'ora legale?
n611x007,

1
@naxa: sì, alcune ore locali sono ambigue o inesistenti. Anche l'offset del fuso orario può essere diverso per motivi diversi dall'ora legale (è necessario un database tz come pytz per scoprire l'offset corretto). Ora locale significa che qualunque politico locale pensi sia una buona idea misurare il tempo, potrebbe essere molto irregolare.
jfs

48

È possibile utilizzare datetime.strftimeper ottenere l'ora in formato Epoch, utilizzando la %sstringa di formato:

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

Nota: funziona solo con Linux e questo metodo non funziona con i fusi orari.


32
Questo è un comportamento piuttosto non documentato ( python.org/doc/current/library/datetime.html ). Sembra funzionare su Linux e non funziona su Win32 (generazione ValueError: Invalid format string).
Antony Hatchkins il

3
Questo metodo non funziona con i fusi orari. La modifica del fuso orario darà lo stesso risultato datetime (2013,12,7, tzinfo = fuso orario ("America / Chicago")). Strftime ("% s") 1386385200 datetime (2013,12,7, tzinfo = fuso orario ("Europa / Riga ")). Strftime ("% s ") 1386385200
Martins Balodis

11

Ecco una datetimesoluzione meno rotta per convertire da oggetto datetime a timestamp posix:

future = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
return (future - datetime.datetime(1970, 1, 1)).total_seconds()

Vedi maggiori dettagli su Conversione di datetime.date in timestamp UTC in Python .


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

4

La chiave è assicurarsi che tutte le date che stai utilizzando siano nel fuso orario utc prima di iniziare la conversione. Vedi http://pytz.sourceforge.net/ per sapere come farlo correttamente. Normalizzando in utc, si elimina l'ambiguità delle transizioni di ora legale. Quindi puoi usare tranquillamente timedelta per calcolare la distanza dall'epoca unix e poi convertire in secondi o millisecondi.

Si noti che il timestamp unix risultante è esso stesso nel fuso orario UTC. Se desideri visualizzare il timestamp in un fuso orario localizzato, dovrai effettuare un'altra conversione.

Si noti inoltre che funzionerà solo per date successive al 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
nota: non capisco "il timestamp [unix] in un fuso orario localizzato". Il timestamp è lo stesso (secondi trascorsi da allora 1970-01-01 00:00:00+00:00). Per ottenere un oggetto datetime ingenuo nel fuso orario locale:datetime.fromtimestamp(ts)
jfs

4

Quanto segue si basa sulle risposte sopra (più una correzione per i millisecondi) ed emula datetime.timestamp()per Python 3 prima della 3.3 quando si usano i fusi orari.

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

Per rispondere rigorosamente alla domanda come richiesto, si desidera:

datetime_timestamp(my_datetime) + 5 * 60

datetime_timestampfa parte di simple-date . Ma se stessi usando quel pacchetto probabilmente dovresti digitare:

SimpleDate(my_datetime).timestamp + 5 * 60

che gestisce molti più formati / tipi per my_datetime.


non dovresti aggiungere (5 * 60) per aggiungere 5 minuti? Penso che l'aggiunta di 5 aggiunga solo 5 secondi al timestamp.
Tim Tisdall,

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

Si noti che le soluzioni con timedelta.total_seconds()lavoro su python-2.7 +. Utilizzare calendar.timegm(future.utctimetuple())per le versioni precedenti di Python.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.