Formatta timedelta in stringa


275

Ho problemi a formattare un datetime.timedeltaoggetto.

Ecco cosa sto cercando di fare: ho un elenco di oggetti e uno dei membri della classe dell'oggetto è un oggetto timedelta che mostra la durata di un evento. Vorrei visualizzare quella durata nel formato di ore: minuti.

Ho provato una varietà di metodi per farlo e ho difficoltà. Il mio approccio attuale è quello di aggiungere metodi alla classe per i miei oggetti che restituiscono ore e minuti. Posso ottenere le ore dividendo il timedelta.seconds per 3600 e arrotondandolo. Sto riscontrando problemi nel recuperare i secondi rimanenti e convertirli in minuti.

A proposito, sto usando Google AppEngine con i modelli Django per la presentazione.


44
Sarebbe bello se timedelta avesse un equivalente del metodo strftime ().
JS.

@JS. Bene, puoi in qualche modo se lo usi datetime.utcfromtimestamp(). Vedi la mia risposta qui sotto.
sabato

@JS. - 100% d'accordo. Quindi, __str__di timedeltaè abbastanza decente, al contrario di __repr__(cioè - per gli umani!). Ad esempio: datetime.timedelta(minutes=6, seconds=41) * 2618 / 48datetime.timedelta(seconds=21871, microseconds=208333), ma str(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)'6:04:31.208333'quale è abbastanza OK da leggere.
Tomasz Gandor,

Risposte:


213

Puoi semplicemente convertire timedelta in una stringa con str (). Ecco un esempio:

import datetime
start = datetime.datetime(2009,2,10,14,00)
end   = datetime.datetime(2009,2,10,16,00)
delta = end-start
print(str(delta))
# prints 2:00:00

13
Più come chiamare il metodo str () con timedelta come argomento.
joeforker,

12
Non è necessaria la chiamata str qui, verrà eseguita automaticamente dalla stampa.
Zitrax,

5
@Zitrax ma è necessario se hai intenzione di concatenare il delta con un'altra stringa. Ad esempioprint 'some thing ' + str(delta)
Plinio.Santos,

13
E necessario quando il tipo di dati è definito come 'datetime.timedelta' e lo stai usando in questo modo, ConvertDuration=datetime.timedelta(milliseconds=int(254459))allora usi semplicemente split per mettere fuori gioco i microsecondi. Da 0: 03: 43.765000 Posso ottenere 0:03:43 semplicemente correndoTotalDuration=str(ConvertDuration).split('.', 2)[0]
DarkXDroid

16
Questo potrebbe stampare il delta come una stringa, ma non lo formatta come richiesto dall'OP.
Dannid,

187

Come sai, puoi ottenere total_seconds da un oggetto timedelta accedendo .secondsall'attributo.

Python offre la funzione integrata divmod()che consente di:

s = 13420
hours, remainder = divmod(s, 3600)
minutes, seconds = divmod(remainder, 60)
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

oppure puoi convertire in ore e resto usando una combinazione di modulo e sottrazione:

# arbitrary number of seconds
s = 13420
# hours
hours = s // 3600 
# remaining seconds
s = s - (hours * 3600)
# minutes
minutes = s // 60
# remaining seconds
seconds = s - (minutes * 60)
# total time
print '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
# result: 03:43:40

5
Per i tempi negativi, dovresti prima valutare il segno e poi fare abs(s).
mbarkhau,

27
Si noti che è possibile che si desideri utilizzare gli '%d:%02d:%02d'zeri iniziali nella stringa di output.
ShinNoNoir,

12
per Python 2.7 e versioni successive utilizzare il metodo .total_seconds ()
sk8asd123

27
Non utilizzare .secondsse la differenza può essere negativa o più lunga di 24 ore (l' .secondsattributo ignora .days). Usa .total_seconds()invece il suo analogo.
jfs,

Per differenze positive lo sto implementando di volta in volta. Grazie per aver dovuto cercare questa volta :)
Wolf,

59
>>> str(datetime.timedelta(hours=10.56))
10:33:36

>>> td = datetime.timedelta(hours=10.505) # any timedelta object
>>> ':'.join(str(td).split(':')[:2])
10:30

Il passaggio timedeltadell'oggetto alla str()funzione chiama lo stesso codice di formattazione utilizzato se si digita semplicemente print td. Dato che non vuoi i secondi, possiamo dividere la stringa in due punti (3 parti) e rimetterla insieme solo con le prime 2 parti.


Grazie per la tua risposta joeforker, ma non sono sicuro di aver capito la tua risposta. Sto ottenendo un delta temporale tramite datetime - datetime. Non conosco le ore. Inoltre, sembra che il tuo esempio includa secondi, come lo rimuoverò?
Mawcs,

1
Non importa dove ottieni l'oggetto timedelta, formatterà lo stesso.
Joeforker,

9
Se è più lungo di un giorno, verrà formattato come ad esempio "4 giorni, 8:00" dopo l'elaborazione di divisione / join.
Joeforker,

4
str(my_timedelta)funziona male per i numeri negativi
Catskul,

2
Mostra anche i giorni in cui> 24 ore, ad esempio "4 giorni, 18: 48: 22.330000". Molti metodi consigliati qui non lo fanno.
Alexei Martianov,

47
def td_format(td_object):
    seconds = int(td_object.total_seconds())
    periods = [
        ('year',        60*60*24*365),
        ('month',       60*60*24*30),
        ('day',         60*60*24),
        ('hour',        60*60),
        ('minute',      60),
        ('second',      1)
    ]

    strings=[]
    for period_name, period_seconds in periods:
        if seconds > period_seconds:
            period_value , seconds = divmod(seconds, period_seconds)
            has_s = 's' if period_value > 1 else ''
            strings.append("%s %s%s" % (period_value, period_name, has_s))

    return ", ".join(strings)

3
Davvero bello, vorrei suggerire cambiando if seconds > period_seconds:a if seconds >= period_seconds:comunque.
CBenni

1
Questo restituisce stringhe vuote per i timedeltas negativi, non sei sicuro se questo è destinato?
Dirk,

31

Personalmente uso la humanizelibreria per questo:

>>> import datetime
>>> humanize.naturalday(datetime.datetime.now())
'today'
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(datetime.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(datetime.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))
'an hour ago'

Naturalmente, non ti dà esattamente la risposta che stavi cercando (che è, in effetti str(timeA - timeB), ma ho scoperto che una volta che vai oltre alcune ore, il display diventa rapidamente illeggibile.humanize Ha il supporto per valori molto più grandi che sono leggibile dall'uomo ed è anche ben localizzato.

È ispirato dal contrib.humanizemodulo di Django , a quanto pare, quindi poiché stai usando Django, probabilmente dovresti usarlo.


2
Bello, + 1 sebbene: humanize.naturaldelta (pd.Timedelta ('- 10sec')) -> '10 secondi ': S ...
ntg

2
bene è un delta di 10 secondi . :) vuoi il tempo , naturaltimeè quello che vuoi usare.
Anarcat,

28

Ha già un oggetto timedelta quindi perché non usare il suo metodo integrato total_seconds () per convertirlo in secondi, quindi usare divmod () per ottenere ore e minuti?

hours, remainder = divmod(myTimeDelta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)

# Formatted only for hours and minutes as requested
print '%s:%s' % (hours, minutes)

Funziona indipendentemente dal fatto che il delta temporale abbia anche giorni o anni.


23

Ecco una funzione generica per convertire un timedeltaoggetto o un numero normale (sotto forma di secondi o minuti, ecc.) In una stringa ben formattata. Ho preso la fantastica risposta di mpounsett su una domanda duplicata, l'ho resa un po 'più flessibile, migliorata la leggibilità e aggiunta documentazione.

Scoprirai che è la risposta più flessibile qui finora poiché ti consente di:

  1. Personalizza il formato stringa al volo invece che essere hardcoded.
  2. Lasciare determinati intervalli di tempo senza problemi (vedere gli esempi seguenti).

Funzione:

from string import Formatter
from datetime import timedelta

def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02}s', inputtype='timedelta'):
    """Convert a datetime.timedelta object or a regular number to a custom-
    formatted string, just like the stftime() method does for datetime.datetime
    objects.

    The fmt argument allows custom formatting to be specified.  Fields can 
    include seconds, minutes, hours, days, and weeks.  Each field is optional.

    Some examples:
        '{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
        '{W}w {D}d {H}:{M:02}:{S:02}'     --> '4w 5d 8:04:02'
        '{D:2}d {H:2}:{M:02}:{S:02}'      --> ' 5d  8:04:02'
        '{H}h {S}s'                       --> '72h 800s'

    The inputtype argument allows tdelta to be a regular number instead of the  
    default, which is a datetime.timedelta object.  Valid inputtype strings: 
        's', 'seconds', 
        'm', 'minutes', 
        'h', 'hours', 
        'd', 'days', 
        'w', 'weeks'
    """

    # Convert tdelta to integer seconds.
    if inputtype == 'timedelta':
        remainder = int(tdelta.total_seconds())
    elif inputtype in ['s', 'seconds']:
        remainder = int(tdelta)
    elif inputtype in ['m', 'minutes']:
        remainder = int(tdelta)*60
    elif inputtype in ['h', 'hours']:
        remainder = int(tdelta)*3600
    elif inputtype in ['d', 'days']:
        remainder = int(tdelta)*86400
    elif inputtype in ['w', 'weeks']:
        remainder = int(tdelta)*604800

    f = Formatter()
    desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
    possible_fields = ('W', 'D', 'H', 'M', 'S')
    constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
    values = {}
    for field in possible_fields:
        if field in desired_fields and field in constants:
            values[field], remainder = divmod(remainder, constants[field])
    return f.format(fmt, **values)

demo:

>>> td = timedelta(days=2, hours=3, minutes=5, seconds=8, microseconds=340)

>>> print strfdelta(td)
02d 03h 05m 08s

>>> print strfdelta(td, '{D}d {H}:{M:02}:{S:02}')
2d 3:05:08

>>> print strfdelta(td, '{D:2}d {H:2}:{M:02}:{S:02}')
 2d  3:05:08

>>> print strfdelta(td, '{H}h {S}s')
51h 308s

>>> print strfdelta(12304, inputtype='s')
00d 03h 25m 04s

>>> print strfdelta(620, '{H}:{M:02}', 'm')
10:20

>>> print strfdelta(49, '{D}d {H}h', 'h')
2d 1h

Codice molto bello e pulito! Mi chiedo come questo codice possa essere espanso per gestire gli ultimi secondi frazionari del resto nel formatter ...
kfmfe04

17

So che questa è una vecchia domanda con risposta, ma io uso datetime.utcfromtimestamp()per questo. Richiede il numero di secondi e restituisce un valore datetimeche può essere formattato come qualsiasi altro datetime.

duration = datetime.utcfromtimestamp(end - begin)
print duration.strftime('%H:%M')

Fintanto che rimani negli intervalli legali per le parti temporali, ciò dovrebbe funzionare, ovvero non restituisce 1234: 35 poiché le ore sono <= 23.


2
dovresti usare print timedelta(seconds=end - begin)invece.
jfs,

@JFSebastian Quindi dovresti riempire le ore manualmente con zeri iniziali.
sabato

Non vedo nulla sull'imbottitura nella domanda. Usa .zfill(8)se ne hai bisogno.
jfs,

1
Richiede una chiamata .total_seconds (): >>> datetime.utcfromtimestamp ((t2-t1) .total_seconds ()). Strftime ("% H:% M:% S") <<< >>> '00: 00: 05 '
cagney,

2
Preferisco di gran lunga questa soluzione, ti permette di controllare la formattazione. Nota che puoi anche usare il formattatore str direttamente in questo modo: "{0:% H}: {0:% M}". Formato (durata)
dita del piede

15

Interrogatore vuole un formato migliore rispetto al tipico:

  >>> import datetime
  >>> datetime.timedelta(seconds=41000)
  datetime.timedelta(0, 41000)
  >>> str(datetime.timedelta(seconds=41000))
  '11:23:20'
  >>> str(datetime.timedelta(seconds=4102.33))
  '1:08:22.330000'
  >>> str(datetime.timedelta(seconds=413302.33))
  '4 days, 18:48:22.330000'

Quindi, in realtà ci sono due formati, uno in cui i giorni sono 0 ed è escluso, e un altro in cui è presente il testo "n giorni, h: m: s". Ma i secondi possono avere frazioni e non ci sono zeri iniziali nelle stampe, quindi le colonne sono disordinate.

Ecco la mia routine, se ti piace:

def printNiceTimeDelta(stime, etime):
    delay = datetime.timedelta(seconds=(etime - stime))
    if (delay.days > 0):
        out = str(delay).replace(" days, ", ":")
    else:
        out = "0:" + str(delay)
    outAr = out.split(':')
    outAr = ["%02d" % (int(float(x))) for x in outAr]
    out   = ":".join(outAr)
    return out

questo restituisce l'output come dd: hh: mm: ss formato:

00:00:00:15
00:00:00:19
02:01:31:40
02:01:32:22

Ho pensato di aggiungere anni a questo, ma questo è lasciato come esercizio per il lettore, poiché l'output è sicuro per oltre 1 anno:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'

15

Considererei seriamente l'approccio Occam's Razor qui:

td = str(timedelta).split('.')[0]

Ciò restituisce una stringa senza i microsecondi

Se vuoi rigenerare l'oggetto datetime.timedelta, fai semplicemente questo:

h,m,s = re.split(':', td)
new_delta = datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s))

2 anni dopo, adoro questa lingua!


5
Questo non copre i giorni
Waschbaer,

13

I miei datetime.timedeltaoggetti sono andati oltre un giorno. Quindi ecco un ulteriore problema. Tutta la discussione sopra presuppone meno di un giorno. A timedeltaè in realtà una tupla di giorni, secondi e microsecondi. La discussione sopra dovrebbe usare td.secondscome ha fatto Joe, ma se hai giorni NON è inclusa nel valore dei secondi.

Sto ottenendo un lasso di tempo tra 2 orari e giorni e ore di stampa.

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)

Questa è la soluzione a prova di futuro.
Jibin,

11

Ho usato la humanfriendlylibreria Python per farlo, funziona molto bene.

import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)

'5 minutes and 21 seconds'

Disponibile su https://pypi.org/project/humanfriendly/


7

Seguendo il valore di esempio di Joe sopra, utilizzerei l'operatore aritmetico del modulo, quindi:

td = datetime.timedelta(hours=10.56)
td_str = "%d:%d" % (td.seconds/3600, td.seconds%3600/60)

Si noti che la divisione dei numeri interi in Python viene arrotondata per impostazione predefinita; se vuoi essere più esplicito, usa math.floor () o math.ceil () come appropriato.


timedelta sa già come formattare se stesso, come in "print some_timedelta".
Joeforker,

Sì, ma non può accettare una stringa di formato arbitraria, che è ciò che Michael stava chiedendo. Anche se ora che ci penso, la mod divisione 3600 fa il presupposto ore-secondi che causa problemi ai secondi bisestili.
UltraNurd,

Sì, ma non vuole una stringa di formato arbitraria, vuole quasi esattamente il comportamento predefinito.
joeforker,

2
Non dimenticare // per aver troncato la divisione in Python 3000
joeforker,

3
+1, ma perché non modifichi la risposta per usare //? Suggerirei anche di utilizzare td.total_seconds()invece di .secondsfarlo funzionare per intervalli> 1 giorno.
Antony Hatchkins,

4
def seconds_to_time_left_string(total_seconds):
    s = int(total_seconds)
    years = s // 31104000
    if years > 1:
        return '%d years' % years
    s = s - (years * 31104000)
    months = s // 2592000
    if years == 1:
        r = 'one year'
        if months > 0:
            r += ' and %d months' % months
        return r
    if months > 1:
        return '%d months' % months
    s = s - (months * 2592000)
    days = s // 86400
    if months == 1:
        r = 'one month'
        if days > 0:
            r += ' and %d days' % days
        return r
    if days > 1:
        return '%d days' % days
    s = s - (days * 86400)
    hours = s // 3600
    if days == 1:
        r = 'one day'
        if hours > 0:
            r += ' and %d hours' % hours
        return r 
    s = s - (hours * 3600)
    minutes = s // 60
    seconds = s - (minutes * 60)
    if hours >= 6:
        return '%d hours' % hours
    if hours >= 1:
        r = '%d hours' % hours
        if hours == 1:
            r = 'one hour'
        if minutes > 0:
            r += ' and %d minutes' % minutes
        return r
    if minutes == 1:
        r = 'one minute'
        if seconds > 0:
            r += ' and %d seconds' % seconds
        return r
    if minutes == 0:
        return '%d seconds' % seconds
    if seconds == 0:
        return '%d minutes' % minutes
    return '%d minutes and %d seconds' % (minutes, seconds)

for i in range(10):
    print pow(8, i), seconds_to_time_left_string(pow(8, i))


Output:
1 1 seconds
8 8 seconds
64 one minute and 4 seconds
512 8 minutes and 32 seconds
4096 one hour and 8 minutes
32768 9 hours
262144 3 days
2097152 24 days
16777216 6 months
134217728 4 years

Hai scritto questo? Quanto l'hai provato?
Thomas Ahle,

Sto usando questo codice nel mio progetto chiamato datahaven.net . Funziona abbastanza bene. Hai visto degli errori?
Veselin Penev,

È sempre bello se puoi fornire un po 'di informazioni con una risposta così pesante al codice :) Come un esempio di come funziona, possibili punti di forza e di debolezza.
Thomas Ahle

1
Oh. Sicuro!. Aggiunto un esempio per te. :-)
Veselin Penev il

Super :) Si noti inoltre che l' timedeltaoggetto ha i campi days, secondse microsecondsdalla documentazione.
Thomas Ahle,

4

Ho avuto un problema simile con l'output del calcolo degli straordinari al lavoro. Il valore deve sempre essere visualizzato in HH: MM, anche quando è maggiore di un giorno e il valore può diventare negativo. Ho combinato alcune delle soluzioni mostrate e forse qualcun altro ha trovato utile questa soluzione. Mi sono reso conto che se il valore di timedelta è negativo, la maggior parte delle soluzioni mostrate con il metodo divmod non funziona immediatamente:

def td2HHMMstr(td):
  '''Convert timedelta objects to a HH:MM string with (+/-) sign'''
  if td < datetime.timedelta(seconds=0):
    sign='-'
    td = -td
  else:
    sign = ''
  tdhours, rem = divmod(td.total_seconds(), 3600)
  tdminutes, rem = divmod(rem, 60)
  tdstr = '{}{:}:{:02d}'.format(sign, int(tdhours), int(tdminutes))
  return tdstr

timedelta a HH: stringa MM:

td2HHMMstr(datetime.timedelta(hours=1, minutes=45))
'1:54'

td2HHMMstr(datetime.timedelta(days=2, hours=3, minutes=2))
'51:02'

td2HHMMstr(datetime.timedelta(hours=-3, minutes=-2))
'-3:02'

td2HHMMstr(datetime.timedelta(days=-35, hours=-3, minutes=-2))
'-843:02'

4
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))

2
in 3.7 ottengo AttributeError: l'oggetto 'datetime.timedelta' non ha attributo 'strftime'
qubodup

4

Un filtro modello diretto per questo problema. La funzione integrata int () non arrotonda mai. Le stringhe F (cioè f '') richiedono python 3.6.

@app_template_filter()
def diffTime(end, start):
    diff = (end - start).total_seconds()
    d = int(diff / 86400)
    h = int((diff - (d * 86400)) / 3600)
    m = int((diff - (d * 86400 + h * 3600)) / 60)
    s = int((diff - (d * 86400 + h * 3600 + m *60)))
    if d > 0:
        fdiff = f'{d}d {h}h {m}m {s}s'
    elif h > 0:
        fdiff = f'{h}h {m}m {s}s'
    elif m > 0:
        fdiff = f'{m}m {s}s'
    else:
        fdiff = f'{s}s'
    return fdiff

3
from django.utils.translation import ngettext

def localize_timedelta(delta):
    ret = []
    num_years = int(delta.days / 365)
    if num_years > 0:
        delta -= timedelta(days=num_years * 365)
        ret.append(ngettext('%d year', '%d years', num_years) % num_years)

    if delta.days > 0:
        ret.append(ngettext('%d day', '%d days', delta.days) % delta.days)

    num_hours = int(delta.seconds / 3600)
    if num_hours > 0:
        delta -= timedelta(hours=num_hours)
        ret.append(ngettext('%d hour', '%d hours', num_hours) % num_hours)

    num_minutes = int(delta.seconds / 60)
    if num_minutes > 0:
        ret.append(ngettext('%d minute', '%d minutes', num_minutes) % num_minutes)

    return ' '.join(ret)

Questo produrrà:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'

Secondo me più pulito, in termini di lunghezza e di ciò che copre
Dici il

1

Controlla questa funzione - converte l'oggetto timedelta nella stringa 'HH: MM: SS'

def format_timedelta(td):
    hours, remainder = divmod(td.total_seconds(), 3600)
    minutes, seconds = divmod(remainder, 60)
    hours, minutes, seconds = int(hours), int(minutes), int(seconds)
    if hours < 10:
        hours = '0%s' % int(hours)
    if minutes < 10:
        minutes = '0%s' % minutes
    if seconds < 10:
        seconds = '0%s' % seconds
    return '%s:%s:%s' % (hours, minutes, seconds)

1

Una fodera Poiché i timedeltas non offrono il tempo di attività di datetime, riportare il timedelta a un tempo di data e utilizzare lo stftime.

Questo non solo può raggiungere il formato richiesto dal PO Ore: minuti, ora puoi sfruttare tutta la potenza di formattazione del tempo di lavoro di datetime, se i tuoi requisiti cambiano in un'altra rappresentazione.

import datetime
td = datetime.timedelta(hours=2, minutes=10, seconds=5)
print(td)
print(datetime.datetime.strftime(datetime.datetime.strptime(str(td), "%H:%M:%S"), "%H:%M"))

Output:
2:10:05
02:10

Questo risolve anche il fastidio che i timedeltas sono formattati in stringhe come H: MM: SS piuttosto che HH: MM: SS, il che mi porta a questo problema e alla soluzione che ho condiviso.


0

Se hai già un obed timedelta, allora convertilo in stringa. Rimuovi gli ultimi 3 caratteri della stringa e stampa. Questo troncerà la parte dei secondi e stamperà il resto nel formato Ore: Minuti.

t = str(timedeltaobj) 

print t[:-3]

Il -3 non funziona, uso miglioreprint t.split('.')[0]
EvgenyKolyakov

0

Se ti capita di avere IPythonnei tuoi pacchetti (dovresti), ha (fino ad ora, comunque) un formatter molto bello per le durate (in secondi float). Viene utilizzato in vari luoghi, ad esempio dalla %%timemagia cellulare. Mi piace il formato che produce per brevi periodi:

>>> from IPython.core.magics.execution import _format_time
>>> 
>>> for v in range(-9, 10, 2):
...     dt = 1.25 * 10**v
...     print(_format_time(dt))

1.25 ns
125 ns
12.5 µs
1.25 ms
125 ms
12.5 s
20min 50s
1d 10h 43min 20s
144d 16h 13min 20s
14467d 14h 13min 20s

-3
t1 = datetime.datetime.strptime(StartTime, "%H:%M:%S %d-%m-%y")

t2 = datetime.datetime.strptime(EndTime, "%H:%M:%S %d-%m-%y")

return str(t2-t1)

Così per:

StartTime = '15:28:53 21-07-13'
EndTime = '15:32:40 21-07-13'

ritorna:

'0:03:47'

-10

Grazie a tutti per il vostro aiuto. Ho preso molte delle tue idee e le ho messe insieme, fammi sapere cosa ne pensi.

Ho aggiunto due metodi alla classe in questo modo:

def hours(self):
    retval = ""
    if self.totalTime:
        hoursfloat = self.totalTime.seconds / 3600
        retval = round(hoursfloat)
    return retval

def minutes(self):
    retval = ""
    if self.totalTime:
        minutesfloat = self.totalTime.seconds / 60
        hoursAsMinutes = self.hours() * 60
        retval = round(minutesfloat - hoursAsMinutes)
    return retval

Nel mio django l'ho usato (sum è l'oggetto ed è in un dizionario):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>

È un po 'lungo. Suggerirei: def hhmm (self): return ':'. Join (str (td) .split (':') [: 2]) <td> {{sum.1.hhmm}} </td>
joeforker,

1
Usa semplicemente divmod () come mostrato nell'esempio "Differenza di due date" su docs.python.org/release/2.5.2/lib/datetime-timedelta.html
Tom,
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.