Come si converte un oggetto time.struct_time in un oggetto datetime?


288

Come si converte un time.struct_timeoggetto Python in un datetime.datetimeoggetto?

Ho una libreria che fornisce la prima e una seconda libreria che vuole la seconda.

Risposte:


384

Usa time.mktime () per convertire la tupla temporale (in localtime) in secondi dall'Epoca, quindi usa datetime.fromtimestamp () per ottenere l'oggetto datetime.

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))

45
Nota che questo fallisce prima del 1900. Voi moderni non ricordate mai questa limitazione!
mlissner,

3
questo perderà i tm_isdstdati? Credo così, il risultante datetime oggetto rimane naive nella misura di tornare Nonea .dst()anche se struct.tm_isdstè 1.
n611x007,

3
Questo di solito funzionerà. Tuttavia, fallirà se la tupla temporale supera i valori accettati da mktime, ad esempio per il valore (1970, 1, 1, 0, 0, 0, 0, 1, -1). Ho riscontrato questo dopo aver analizzato l'intestazione Date su una richiesta HTTP che ha restituito questa tupla.
user3820547

3
@richvdh: lo standard C specifica che mktime()dovrebbe essere preso tm_isdstin considerazione e Python time.mktime()chiama la mktime()funzione C su CPython. mktime()può scegliere l'ora locale errata quando è ambigua (ad es. durante la transizione di fine DST ("fallback") se lo struct.tm_isdstè -1o se mktime()sulla piattaforma data ignora l' input tm_isdst . Inoltre, se il fuso orario locale aveva un offset utc diverso in passato e C mktime()non utilizza un database tz storico in grado di fornire i vecchi valori di offset utc, mktime()potrebbe anche restituire un valore errato (ad esempio di un'ora).
jfs,

1
@naxa: se mktime()non ignora tm_isdstsulla piattaforma data (fa sulla mia) quindi fromtimestamp()perde definitivamente le informazioni: l' oggetto ingenuo restituito datetimeche rappresenta l'ora locale può essere ambiguo (timestamp -> l'ora locale è deterministica (se ignoriamo i secondi bisestili) ma local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp () `può scegliere un offset utc errato se non utilizza un database tz storico.
jfs

123

Come questo:

>>> structTime = time.localtime()
>>> datetime.datetime(*structTime[:6])
datetime.datetime(2009, 11, 8, 20, 32, 35)

3
Non dimenticare di #import time, datetime
jhwist

7
@jhwist - alcune cose di cui ci si può fidare delle persone per capirlo da soli :)
orip

14
@rodling the *e la **sintassi ti consentono di espandere un oggetto di tipo listy o dicty in argomenti separati - è uno dei miei pezzi preferiti di adorazione di Python. Vedi docs.python.org/2/tutorial/… per maggiori informazioni
OrganicPanda

10
Ricorda solo che questo ti darà un ValueError se il struct_time ha un salto di qualità, ad esempio:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario

7
@berdario: per restituire valori compatibili con datetime: datetime(*t[:5]+(min(t[5], 59),))ad esempio, per accettare "2015-06-30 16:59:60 PDT".
jfs,

37

Questa non è una risposta diretta alla tua domanda (a cui è già stata data una risposta abbastanza buona). Tuttavia, avendo avuto a volte mordermi più volte sul fondamento, non posso sottolineare abbastanza che ti sorprenderesti a guardare da vicino ciò che il tuo oggetto time.struct_time fornisce, rispetto a ciò che altri campi temporali potrebbero avere.

Supponendo che tu abbia sia un oggetto time.struct_time, sia un'altra stringa data / ora, confronta i due e assicurati di non perdere dati e di creare inavvertitamente un oggetto datetime ingenuo, quando puoi fare diversamente.

Ad esempio, l'eccellente modulo feedparser restituirà un campo "pubblicato" e potrebbe restituire un oggetto time.struct_time nel suo campo "publishing_parsed":

time.struct_time(tm_year=2013, tm_mon=9, tm_mday=9, tm_hour=23, tm_min=57, tm_sec=42, tm_wday=0, tm_yday=252, tm_isdst=0)

Ora nota cosa ottieni effettivamente con il campo "pubblicato".

Mon, 09 Sep 2013 19:57:42 -0400

Di Stallman 's Beard! Informazioni sul fuso orario!

In questo caso, l'uomo pigro potrebbe voler utilizzare l'eccellente modulo dateutil per conservare le informazioni sul fuso orario:

from dateutil import parser
dt = parser.parse(entry["published"])
print "published", entry["published"])
print "dt", dt
print "utcoffset", dt.utcoffset()
print "tzinfo", dt.tzinfo
print "dst", dt.dst()

che ci dà:

published Mon, 09 Sep 2013 19:57:42 -0400
dt 2013-09-09 19:57:42-04:00
utcoffset -1 day, 20:00:00
tzinfo tzoffset(None, -14400)
dst 0:00:00

Si potrebbe quindi utilizzare l'oggetto datetime sensibile al fuso orario per normalizzare tutto il tempo in UTC o qualunque cosa si pensi sia eccezionale.


7
Tutti i *_parsedcampi da feedparsed sono già normalizzati in UTC, come può essere verificato nella documentazione di analisi della data, quindi è ridondante.
Itorres

1
@itorres: se lo capisco, questa risposta non riguarda la normalizzazione in UTC, ma la conservazione delle informazioni sul fuso orario in un datetimeoggetto che viene perso quando feedparseranalizza le date delle stringhe non elaborate.
davidag,
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.