2013-10-25 9 views
9

Sto cercando di capire come funziona il modulo datetime. Conosco l'epoca ora come un'epoca e il momento in cui un evento è accaduto per l'ultima volta (come un'epoca). Quello che devo fare è capire se quell'evento si è verificato tra mezzanotte e mezzanotte di ieri.Che cosa era la mezzanotte di ieri come un'epoca?

t = time.time() # is now 
t2 = 1234567890 # some arbitrary time from my log 

24 ore fa è t - 86400, ma come posso arrotondarlo su e giù a mezzanotte. Sto avendo problemi a trovare un modo per ottenere data e ora di data/ora o di manipolare un datetime per impostare l'ora.

+1

Sembra che potrebbe essere necessario convertirlo in * regular * tempo da qualche parte lì dentro, poiché i divisori come giorni/mezzanotte/ecc non fanno parte di epoche. – Gray

risposta

30

Generare l'ultima mezzanotte è facile:

from datetime import datetime, date, time 

midnight = datetime.combine(date.today(), time.min) 

che unisce la data odierna, insieme con time.min per formare un oggetto datetime a mezzanotte.

Con un timedelta() è possibile calcolare il precedente mezzanotte:

from datetime import timedelta 

yesterday_midnight = midnight - timedelta(days=1) 

Ora tutto quello che dovete fare è di verificare se il timestamp è tra questi due punti:

timestamp = datetime.fromtimestamp(some_timestamp_from_your_log) 
if yesterday_midnight <= timestamp < midnight: 
    # this happened between 00:00:00 and 23:59:59 yesterday 

combinati in una funzione:

from datetime import datetime, date, time, timedelta 

def is_yesterday(timestamp): 
    midnight = datetime.combine(date.today(), time.min) 
    yesterday_midnight = midnight - timedelta(days=1) 
    timestamp = datetime.fromtimestamp(some_timestamp_from_your_log) 
    return yesterday_midnight <= timestamp < midnight: 
+0

Come puoi sapere quando è mezzanotte senza specificare il fuso orario? – sdanzig

+0

@sdanzig: per impostazione predefinita, il modulo 'datetime' non è sensibile al fuso orario. Può restituire ora locale o UTC, come previsto dal sistema operativo. Questo codice utilizza l'ora locale. –

+1

In questo caso non è un problema dato che tutto viene eseguito in UTC. – t0mmyt

1

Dato come un timestamp, è possibile utilizzare divmod per calcolare il numero di giorni fin dall'epoca (che non si cura di), e quanti secondi sono avanzi (che si fa):

days_since, remaining_seconds = divmod(t, 24*3600) # Divide by number of seconds in one day 

Quindi, si sottraggono i secondi rimanenti dal timestamp originale, che produce la mezzanotte del giorno corrente.

t -= remaining_seconds 

Arrotondare è semplice come spostare il timestamp di destinazione in avanti esattamente un giorno prima di arrotondare.

tomorrow_t = t + 24 * 3600 
days_since, remaining_seconds = divmod(tomorrow_t, 24*3600) 
t = tomorrow_t - remaining_seconds 
+0

Ho pensato a questo approccio, in realtà stavo andando a mod 86400, ma poi ho ricordato il salto di secondi. – t0mmyt

+1

Questi timestamp non sono influenzati dai secondi bisestili. Quando si verifica un secondo intercalare, il timestamp UNIX epoch si ripete semplicemente, quindi è garantito avere 86400 secondi al giorno. La ripetizione di un timestamp è solo un'altra etichetta arbitraria per il secondo intercalare, come '23: 59: 60' è un'etichetta arbitraria per il secondo intercalare tra 23:59:59 e 00:00:00 (o ogni volta che vengono applicati i secondi bisestili). – chepner

0

A mio avviso, molte manipolazioni di data e ora sono più facili da fare, e per capire, utilizzando il freccia biblioteca. Questo è uno di loro.

Creare una data e un'ora arbitrarie.

>>> import arrow 
>>> arbitrary = arrow.get(2017,8,16,11,5) 

Calcolare midnight_yesterday: prima, a mezzanotte di arbitrary come il suo 'giorno' floor; quindi shift questo indietro di un giorno. Mostra il risultato.

>>> midnight_yesterday = arbitrary.floor('day').shift(days=-1) 
>>> midnight_yesterday 
<Arrow [2017-08-15T00:00:00+00:00]> 

Uso timestamp per il risultato complessivo desiderato, per Python 3.3+.

>>> midnight_yesterday.datetime.timestamp() 
1502755200.0 

Oppure utilizzare questa espressione per Python 2.7. (Credito: https://stackoverflow.com/a/11743262/131187 per le ultime due espressioni.

>>> (midnight_yesterday-arrow.get(1970,1,1)).total_seconds() 
1502755200.0 
Problemi correlati