Python's time.time () restituisce il timestamp locale o UTC?


562

Non time.time()nel modulo Python tempo tornare ora del sistema o il tempo in UTC?


87
I timestamp non hanno fusi orari. Rappresentano un numero di secondi dall'epoca. L'epoca è un momento specifico nel tempo che non dipende dal fuso orario.
jwg

2
@jwg: i timestamp POSIX comunemente usati non contano i secondi bisestili e quindi non sono il "numero di [SI] trascorsi dall'epoca" (sono vicini).
jfs,

7
Non penso che questa sia un'obiezione accurata @JFSebastian. I secondi bisestili non sono "secondi trascorsi dall'epoca". Sono cambiamenti nelle rappresentazioni del tempo registrate dagli orologi che non corrispondono ai secondi trascorsi.
jwg

4
@JFSebastian Ci scusiamo per la confusione. I secondi saltati non sono "secondi trascorsi". Pertanto i timestamp, che sono "numeri di secondi trascorsi", non includono e non devono includere secondi bisestili.
jwg

2
@jwg sbagliato. Non puoi cancellare il tempo fisico. Il timestamp POSIX non è il numero di secondi SI trascorsi. Ecco un esempio: 3 secondi trascorsi tra "31 dicembre 2016 alle 18:59:59" e "31 dicembre 2016 alle 7:01:01" a New York, ma la differenza nei corrispondenti timestamp POSIX è di soli 2 secondi (il il secondo bisestile non viene conteggiato).
jfs,

Risposte:


781

La time.time()funzione restituisce il numero di secondi dall'epoca, in secondi. Si noti che l '"epoca" è definita come l'inizio del 1 ° gennaio 1970 in UTC. Quindi l'epoca è definita in termini di UTC e stabilisce un momento globale nel tempo. Indipendentemente da dove vi troviate "epoche passate" (time.time ()) restituisce lo stesso valore nello stesso momento.

Ecco alcuni esempi di output che ho eseguito sul mio computer, convertendoli anche in una stringa.

Python 2.7.3 (default, Apr 24 2012, 00:00:54) 
[GCC 4.7.0 20120414 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> ts = time.time()
>>> print ts
1355563265.81
>>> import datetime
>>> st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
>>> print st
2012-12-15 01:21:05
>>>

La tsvariabile è il tempo restituito in secondi. L'ho quindi convertito in una stringa utilizzando la datetimelibreria rendendola una stringa leggibile dall'uomo.


72
Perché dovremmo import timequando il datetime sostanzialmente ti dà il timestamp. Rimuovi i millisecondi -str(datetime.datetime.now()).split('.')[0]
Hussain,

17
L'epoca di @Alexis Unix è definita abbastanza chiaramente qui . Indica persino un esempio di Python in fondo alla pagina. Non capisco il tuo commento.
squiguy

9
@squiguy a dire il vero non ricordo cosa mi abbia fatto dire questo. Devo aver letto male qualcosa, e stavo lottando per scoprire perché alcuni test si stavano rompendo mentre mi sono trasferito tra Francia e Stati Uniti per scoprire finalmente che il problema era dovuto all'ora legale che allungava la settimana in questo periodo dell'anno. Mi dispiace e grazie per averlo sottolineato.
Alexis,

5
non è "secondi in UTC". . Il timestamp restituito da time.time()non è in alcun fuso orario . "secondi dall'epoca" è un termine; non sono trascorsi secondi da un certo momento (epoca). Puoi convertirlo facilmente nell'ora locale (con database tz) e / o fuso orario UTC. tra l'altro, se si rilascia .strftime()il risultato è (quasi) lo stesso (+/- microsecondi).
jfs,

3
appena provato, time.time () non dà l'ora UTC, dà l'ora del mio fuso orario locale
sliders_alpha

302

Questo è per la forma testuale di un timestamp che può essere usato nei tuoi file di testo. (Il titolo della domanda era diverso in passato, quindi l'introduzione di questa risposta è stata modificata per chiarire come potrebbe essere interpretata come l'ora. [Aggiornato il 01-01-2016])

È possibile ottenere il timestamp come stringa utilizzando il .now()o .utcnow()del datetime.datetime:

>>> import datetime
>>> print datetime.datetime.utcnow()
2012-12-15 10:14:51.898000

Le nowdifferisce da utcnowcome previsto - altrimenti funzionano allo stesso modo:

>>> print datetime.datetime.now()
2012-12-15 11:15:09.205000

È possibile eseguire il rendering della data / ora nella stringa in modo esplicito:

>>> str(datetime.datetime.now())
'2012-12-15 11:15:24.984000'

Oppure puoi essere ancora più esplicito nel formattare il timestamp nel modo che preferisci:

>>> datetime.datetime.now().strftime("%A, %d. %B %Y %I:%M%p")
'Saturday, 15. December 2012 11:19AM'

Se si desidera il formato ISO, utilizzare il .isoformat()metodo dell'oggetto:

>>> datetime.datetime.now().isoformat()
'2013-11-18T08:18:31.809000'

Puoi usarli nelle variabili per i calcoli e la stampa senza conversioni.

>>> ts = datetime.datetime.now()
>>> tf = datetime.datetime.now()
>>> te = tf - ts
>>> print ts
2015-04-21 12:02:19.209915
>>> print tf
2015-04-21 12:02:30.449895
>>> print te
0:00:11.239980

1
Volevo l'ora dell'epoca ... non nel formato della data ... come era evidente dalla mia menzione del comando time.time ()
Saransh Mohapatra,

34
Ok nessun problema. Qualcun altro potrebbe aver bisogno di timestamp dire per l'inserimento in file di testo.
pepr

1
Sono un altro, reindirizzato qui probabilmente a causa del numero irragionevole di voti. La domanda non è corretta e la risposta accettata è fuorviante per la necessità tipica: ottenere un suffisso leggibile dall'uomo - diciamo per i nomi dei file - nel fuso orario del server più utilizzato.

Per stampare un timestamp come parte di una stringa, utilizzare questo: Python2: import datetime; print "%s: My timestamp message" % datetime.datetime.utcnow()Python3:import datetime; print ("%s: My timestamp message" % datetime.datetime.utcnow())
Mr-IDE

datetime.datetime.utcnow()è malvagio. Crea un datetime ingenuo che non è l'ora locale. A meno che l'ora locale non sia UTC, sarà SBAGLIATA. Usa datetime.datetime.now(datetime.timezone.utc)invece. Ciò crea un datetime consapevole del fuso orario che rappresenta l'ora corrente.
Terrel Shumway,

139

Basandomi sulla risposta di #squiguy, per ottenere un vero timestamp vorrei digitare cast da float.

>>> import time
>>> ts = int(time.time())
>>> print(ts)
1389177318

Almeno questo è il concetto.


1
Qual è il motivo per cui è stato inserito il fuso orario? Qual è il tipo di default?
Tizzee,

3
@Tizzee type(time.time())<type 'float'>
famosogarkin

4
Ma se hai bisogno di un tempo più preciso che in secondi, il galleggiante ha senso.
pepr

3
@RudiStrydom: Python è fortemente tipizzato. Non confonderlo con la digitazione statica.
jfs

1
@CheokYanCheng: int()è polimorfico. Restituirebbe longse necessario su vecchie versioni di Python - tutti gli interi sono lunghi sulle nuove versioni di Python.
jfs

30

La risposta potrebbe essere né l'una né l'altra.

  • nessuno dei due: time.time()restituisce approssimativamente il numero di secondi trascorsi dall'epoca. Il risultato non dipende dal fuso orario, quindi non è né UTC né l'ora locale. Ecco la definizione POSIX per "Seconds Since the Epoch" .

  • entrambi: time.time()non richiede che l'orologio del sistema sia sincronizzato, quindi riflette il suo valore (anche se non ha nulla a che fare con il fuso orario locale). Computer diversi possono ottenere risultati diversi contemporaneamente. D'altra parte se l'ora del computer è sincronizzata, è facile ottenere l'ora UTC dal timestamp (se ignoriamo i secondi bisestili):

    from datetime import datetime
    
    utc_dt = datetime.utcfromtimestamp(timestamp)

Su come ottenere i timestamp dall'ora UTC in varie versioni di Python, vedi Come posso ottenere una data convertita in secondi dall'epoca secondo UTC?


4
Questa è l'unica risposta che è correttamente menzionata datetime.utcfromtimestampmentre ci sono 308 voti positivi su una risposta con datetime.fromtimestamp:-(

@TerrelShumway la domanda riguarda cosa time.time()restituisce la funzione (è molto breve). Il tuo commento affronta qualche altra domanda (hai cambiato il tuo commento da quando ho iniziato a rispondere. In peggio). Una nota a parte; la parola "corretto" dovrebbe essere usata con parsimonia (i fusi orari sono complicati - non esiste un proiettile d'argento - solo compromessi per un particolare caso d'uso).
jfs,

Non usare datetime.datetime.utcfromtimestamp(ts). A meno che l'ora locale non sia UTC, sarà SBAGLIATA, poiché crea un datetime ingenuo che non è l'ora locale. Usa datetime.datetime.fromtimestamp(ts,datetime.timezone.utc)invece. Ciò crea un datetime consapevole del fuso orario che rappresenta lo stesso istante del timestamp.
Terrel Shumway,

Sì. Il mio commento precedente era completamente sbagliato. La maggior parte del codice nel modulo datetime considera gli orari di dati ingenui come ora locale. Usare orari di dati ingenui è come aprire un file di testo senza conoscere la codifica.
Terrel Shumway,

@TerrelShumway È errato supporre che l'ora UTC possa essere utilizzata solo su sistemi in cui è l'ora locale. È vero che alcune parti di stdlib trattano oggetti datetime ingenui come aventi il ​​fuso orario locale (purtroppo). Preferirei che naive_dt.astimezone()non esistesse come implicito bytes.encode()non esiste più in Python 3. È vero che in molti casi è utile lavorare con l'ora UTC internamente. Ci sono molte cose che si possono dire sul modulo datetime (ho risposto a abbastanza domande per ottenere un badge d'oro) la maggior parte sono fuori portata per la domanda: cosa time.time()ritorna.
jfs

4

Alla fine mi sono accontentato di:

>>> import time
>>> time.mktime(time.gmtime())
1509467455.0

1
Ciò può soddisfare le tue esigenze locali, ma può essere fuorviante per le persone che si aspettano che i numeri in quell'intervallo siano secondi dall'epoca del [GMT]. time.time()restituisce decimale / float come 1574115250.818733e millisecondi-poiché-epoca è facilmente int(time.time() * 1000)ad esempio1574115254915
MarkHu

3

Non esiste una "epoca" in un fuso orario specifico. L'epoca è ben definita come un momento specifico nel tempo, quindi se si modifica il fuso orario, anche il tempo stesso cambia. In particolare, questa volta lo è Jan 1 1970 00:00:00 UTC. Quindi time.time()restituisce il numero di secondi dall'epoca.


Mentre è vero che UTC è uno standard orario e non un fuso orario, lo standard è che condivide lo stesso orario GMT. Quindi ....
Craig Hicks il

3

il timestamp è sempre time in utc, ma quando lo chiami datetime.datetime.fromtimestamp ti restituisce il tempo nel tuo fuso orario locale corrispondente a questo timestamp, quindi il risultato dipende dal tuo locale.

>>> import time, datetime

>>> time.time()
1564494136.0434234

>>> datetime.datetime.now()
datetime.datetime(2019, 7, 30, 16, 42, 3, 899179)
>>> datetime.datetime.fromtimestamp(time.time())
datetime.datetime(2019, 7, 30, 16, 43, 12, 4610)

Esiste una bella libreria arrowcon comportamenti diversi. Nello stesso caso restituisce l'oggetto time con fuso orario UTC.

>>> import arrow
>>> arrow.now()
<Arrow [2019-07-30T16:43:27.868760+03:00]>
>>> arrow.get(time.time())
<Arrow [2019-07-30T13:43:56.565342+00:00]>
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.