Converti un timedelta in giorni, ore e minuti


243

Ho un timedelta. Voglio i giorni, le ore e i minuti da quello - sia come tupla che come dizionario ... Non sono agitato.

Devo averlo fatto una dozzina di volte in una dozzina di lingue nel corso degli anni, ma Python di solito ha una risposta semplice a tutto, quindi ho pensato di chiedere qui prima di svelare un po 'di matematica semplice ma allo stesso tempo prolissa.

L'onorevole Fooz solleva un buon punto.

Ho a che fare con "elenchi" (un po 'come gli elenchi eBay) in cui ognuno ha una durata. Sto cercando di trovare il tempo rimasto facendowhen_added + duration - now

Ho ragione nel dire che non spiegherebbe l'ora legale? In caso contrario, qual è il modo più semplice per aggiungere / sottrarre un'ora?


Se è solo per ottenere come una stringa di in hh: mm: ss, dire "00:19:37" dalla timedeltaoggetto "datetime.timedelta (secondi = 1177)" : è sufficiente utilizzare str ()
Peter Mortensen

Risposte:


344

Se hai un datetime.timedeltavalore td, td.daysti dà già i "giorni" che desideri. timedeltai valori mantengono la frazione del giorno in secondi (non direttamente ore o minuti), quindi dovrai effettivamente eseguire "matematica nauseabamente semplice", ad esempio:

def days_hours_minutes(td):
    return td.days, td.seconds//3600, (td.seconds//60)%60

1
Tieni presente che se tdè negativo, lo -1 // 3600è -1.
jcrs

4
perché // ? invece di /
Mohammed Shareef C

10
//viene utilizzato invece di /ottenere un numero intero, non un float. //è un operatore di divisione del piano: "divisione che risulta in un numero intero adattato a sinistra nella riga del numero", vedere qui .
Eerik Sven Puudist,

1
@EerikSvenPuudist, come jcrssottolineato, -1//3600è -1, quindi perché non utilizzare int(td.seconds/3600)invece per trasformare i -1secondi in 0ore anziché in 1ore indietro?
simpleuser

che ne dici di aggiungere anche i secondi rimanenti? days, hours, minutes = x.days, x.seconds // 3600, x.seconds %3600//60e poi seconds = x.seconds - hours*3600 - minutes*60
raphael

73

Questo è un po 'più compatto, ottieni ore, minuti e secondi in due righe.

days = td.days
hours, remainder = divmod(td.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# If you want to take into account fractions of a second
seconds += td.microseconds / 1e6

7
non è corretto se td.daysè diverso da zero. Hai bisogno hours += td.days*24. Se si desidera prendere in considerazione le frazioni di secondo (OP no); seconds += td.microseconds / 1e6potrebbe essere usato.
jfs,

30
days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

Per quanto riguarda l'ora legale, penso che la cosa migliore sia convertire entrambi gli datetimeoggetti in secondi. In questo modo il sistema calcola l'ora legale per te.

>>> m13 = datetime(2010, 3, 13, 8, 0, 0)  # 2010 March 13 8:00 AM
>>> m14 = datetime(2010, 3, 14, 8, 0, 0)  # DST starts on this day, in my time zone
>>> mktime(m14.timetuple()) - mktime(m13.timetuple())     # difference in seconds
82800.0
>>> _/3600                                                # convert to hours
23.0

1
mktime()potrebbe non riuscire se il fuso orario locale può avere un offset utc diverso in momenti diversi (molti lo fanno) - è possibile utilizzare il pytzmodulo per ottenere l'accesso al database tz in modo deteministico portatile. Inoltre, l'ora locale può essere ambigua (50% di probabilità di errore): per chiarire le esigenze, ad esempio, sono necessarie alcune informazioni aggiuntive, ad esempio, spesso (non sempre) le date in un file di registro sono monotone . Vedi Come posso sottrarre un giorno da una data in pitone? che potrebbe avere a che fare con problemi simili.
jfs,

7

Non capisco

days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

cosa ne pensi di questo

days, hours, minutes = td.days, td.seconds // 3600, td.seconds % 3600 / 60.0

Ottieni minuti e secondi di un minuto come un galleggiante.


0

Ho usato il seguente:

delta = timedelta()
totalMinute, second = divmod(delta.seconds, 60)
hour, minute = divmod(totalMinute, 60)
print(f"{hour}h{minute:02}m{second:02}s")

-3

i timedeltas hanno un dayse un secondsattributo .. puoi convertirli tu stesso con facilità.

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.