Sformatuj timedelta na ciąg

275

Mam problem z formatowaniem datetime.timedeltaobiektu.

Oto, co próbuję zrobić: Mam listę obiektów, a jednym z członków klasy obiektu jest obiekt timedelta, który pokazuje czas trwania zdarzenia. Chciałbym wyświetlić ten czas w formacie godzin: minut.

Wypróbowałem różne metody, aby to zrobić i mam trudności. Moje obecne podejście polega na dodawaniu metod do klasy dla moich obiektów, które zwracają godziny i minuty. Mogę uzyskać godziny, dzieląc timedelta.seconds przez 3600 i zaokrąglając go. Mam problem z uzyskaniem pozostałych sekund i przeliczeniem ich na minuty.

Nawiasem mówiąc, do prezentacji używam Google AppEngine z szablonami Django.

mawcs
źródło
44
Byłoby miło, gdyby timedelta miała odpowiednik metody strftime ().
JS.
@JS. Cóż, możesz to zrobić, jeśli używasz datetime.utcfromtimestamp(). Zobacz moją odpowiedź poniżej.
sjngm
@JS. - 100% się zgadza. Zatem __str__of timedeltajest całkiem przyzwoite, w przeciwieństwie do __repr__(to znaczy - dla ludzi!). Na przykład: datetime.timedelta(minutes=6, seconds=41) * 2618 / 48daje datetime.timedelta(seconds=21871, microseconds=208333), ale str(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)daje, '6:04:31.208333'co jest w porządku do przeczytania.
Tomasz Gandor

Odpowiedzi:

213

Możesz po prostu przekonwertować timedelta na ciąg za pomocą str (). Oto przykład:

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
Parand
źródło
13
Bardziej przypomina wywoływanie metody str () z argumentem timedelta.
joeforker
12
Nie potrzebujesz tam wywołania str, nastąpi to automatycznie przez wydruk.
Zitrax
5
@Zitrax, ale jest to konieczne, jeśli zamierzasz połączyć deltę z innym ciągiem. Na przykładprint 'some thing ' + str(delta)
Plinio.Santos
12
I konieczne, gdy typ danych jest zdefiniowany jako „datetime.timedelta” i używasz go w ten sposób, ConvertDuration=datetime.timedelta(milliseconds=int(254459))po prostu używasz podziału, aby wyłączyć mikrosekundy z gry. Od 0: 03: 43.765000 Mogę uzyskać 0:03:43 po prostu uruchamiającTotalDuration=str(ConvertDuration).split('.', 2)[0]
DarkXDroid
16
Może to wydrukować deltę jako ciąg, ale nie formatuje jej zgodnie z żądaniem OP.
Dannid
187

Jak wiesz, możesz uzyskać total_seconds z obiektu timedelta, uzyskując dostęp do .secondsatrybutu.

Python zapewnia wbudowaną funkcję, divmod()która pozwala na:

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

lub możesz przeliczyć na godziny i resztę, używając kombinacji modulo i odejmowania:

# 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
John Fouhy
źródło
5
W przypadku ujemnych timedeltas należy najpierw ocenić znak, a następnie zrobić abs(s).
mbarkhau
27
Zauważ, że możesz chcieć użyć '%d:%02d:%02d'początkowych zer w ciągu wyjściowym.
ShinNoNoir
12
dla Pythona 2.7 i nowszych należy użyć metody .total_seconds ()
sk8asd123
27
Nie używaj, .secondsjeśli różnica może być ujemna lub dłuższa niż 24 godziny ( .secondsatrybut ignoruje .days). .total_seconds()Zamiast tego użyj lub jego analogu.
jfs
Dla pozytywnych różnic od czasu do czasu wdrażam to ponownie. Dzięki za to, że
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

Przekazywanie timedeltaobiektu do str()funkcji wywołuje ten sam kod formatowania, który jest używany, jeśli po prostu piszemy print td. Ponieważ nie chcesz sekund, możemy podzielić ciąg na dwukropki (3 części) i złożyć z powrotem tylko dwie pierwsze części.

współpracownik
źródło
Dziękuję za odpowiedź joeforker, ale nie jestem pewien, czy rozumiem twoją odpowiedź. Uzyskuję deltę czasu za pomocą datetime - datetime. Nie znam godzin. Dodatkowo wygląda na to, że twój przykład zawiera sekundy, jak bym to usunął?
mawcs
1
Nie ma znaczenia, skąd masz obiekt timedelta, formatuje to samo.
joeforker
9
Jeśli jest dłuższy niż jeden dzień, po przetworzeniu podziału / złączenia sformatuje się jako np. „4 dni, 8:00”.
joeforker
4
str(my_timedelta)źle działa dla liczb ujemnych
Catskul
2
Pokazuje także dni, gdy> 24 godziny, np. „4 dni, 18: 48: 22.330000”. Wiele zalecanych tutaj metod nie.
Aleksiej Martianow
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)
Adam Jacob Muller
źródło
3
Naprawdę fajnie, sugerowałbym jednak zmianę if seconds > period_seconds:na if seconds >= period_seconds:.
CBenni
1
Zwraca puste ciągi dla ujemnych timedeltas, nie jesteś pewien, czy jest to zamierzone?
Dirk
31

Osobiście korzystam z humanizebiblioteki do tego:

>>> 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'

Oczywiście nie daje dokładnie takiej odpowiedzi, jakiej szukałeś (co w rzeczywistości jest, str(timeA - timeB)ale odkryłem, że gdy przekroczysz kilka godzin, wyświetlacz staje się szybko nieczytelny. humanizeMa obsługę znacznie większych wartości, które są czytelny dla człowieka, a także dobrze zlokalizowany.

contrib.humanizeNajwyraźniej jest zainspirowany modułem Django , więc skoro używasz Django, prawdopodobnie powinieneś go użyć.

anarcat
źródło
2
Fajne, + 1 Chociaż: humanize.naturaldelta (pd.Timedelta („- 10 sekund”)) -> „10 sekund”: S ...
ntg
2
to jest 10 sekundowa delta . :) chcesz czas , naturaltimeto jest to, czego chcesz użyć.
anarcat
28

Ma już obiekt timedelta, więc dlaczego nie skorzystać z wbudowanej metody total_seconds (), aby przekonwertować go na sekundy, a następnie użyć divmod (), aby uzyskać godziny i minuty?

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)

Działa to niezależnie od tego, czy delta czasu ma nawet dni, czy lata.

Bill Kidd
źródło
23

Oto funkcja ogólnego przeznaczenia do konwersji timedeltaobiektu lub zwykłej liczby (w postaci sekund lub minut itp.) Na ładnie sformatowany ciąg. Wziąłem fantastyczne odpowiedź mpounsett jest na duplikatu pytanie, czyni ją nieco bardziej elastyczne, poprawę czytelności i dodał dokumentacji.

Przekonasz się, że jest to jak dotąd najbardziej elastyczna odpowiedź, ponieważ pozwala na:

  1. Dostosuj format ciągu w locie, zamiast na stałe go kodować.
  2. Pomiń pewne przedziały czasowe bez problemu (patrz przykłady poniżej).

Funkcjonować:

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)

Próbny:

>>> 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
MarredCheese
źródło
Bardzo ładny, czysty kod! Zastanawiam się, jak ten kod można rozszerzyć, aby obsługiwał ostatnie ułamki sekundowe w formatyzatorze ...
kfmfe04
17

Wiem, że to stare pytanie, na które udzielono odpowiedzi, ale używam datetime.utcfromtimestamp()tego. Zajmuje to liczbę sekund i zwraca wartość, datetimektórą można sformatować jak każdą inną datetime.

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

Dopóki przebywasz w dozwolonych przedziałach czasowych, powinno to działać, tzn. Nie zwraca 1234: 35, ponieważ godziny wynoszą <= 23.

sjngm
źródło
2
powinieneś użyć print timedelta(seconds=end - begin)zamiast tego.
jfs
@JFSebastian Następnie godziny trzeba uzupełniać ręcznie wiodącymi zerami.
sjngm
W pytaniu nie widzę nic o wypełnieniu. Użyj, .zfill(8)jeśli potrzebujesz.
jfs
1
Wymaga wywołania .total_seconds (): >>> datetime.utcfromtimestamp ((t2-t1) .total_seconds ()). Strftime ("% H:% M:% S") <<< >>> '00: 00: 05 '
cagney
2
Zdecydowanie wolę to rozwiązanie, które pozwala kontrolować formatowanie. Uwaga: możesz także użyć formater str bezpośrednio w następujący sposób: "{0:% H}: {0:% M}". Format (czas trwania)
palce
15

Pytający chce ładniejszego formatu niż typowy:

  >>> 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'

Tak więc naprawdę istnieją dwa formaty, jeden, w którym dni mają wartość 0 i jest pominięty, a drugi, w którym jest tekst „n dni, h: m: s”. Ale sekundy mogą mieć ułamki i na wydrukach nie ma zer wiodących, więc kolumny są nieuporządkowane.

Oto moja rutyna, jeśli ci się podoba:

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

zwraca wynik w formacie dd: hh: mm: ss:

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

Zastanawiałem się nad dodaniem do tego lat, ale jest to ćwiczenie dla czytelnika, ponieważ dane wyjściowe są bezpieczne przez ponad 1 rok:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'
Kevin J. Rice
źródło
15

Poważnie rozważyłbym tutaj podejście brzytwy Ockhama:

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

Zwraca ciąg bez mikrosekund

Jeśli chcesz ponownie wygenerować obiekt datetime.timedelta, wykonaj następujące czynności:

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

Za 2 lata uwielbiam ten język!

Pyrotherm
źródło
5
Nie obejmuje to dni
Waschbaer
13

Moje datetime.timedeltaprzedmioty były większe niż jeden dzień. Oto kolejny problem. Cała powyższa dyskusja zakłada niecały dzień. A timedeltajest krotką dni, sekund i mikrosekund. Powyższa dyskusja powinna być wykorzystana td.secondstak jak Joe, ale jeśli masz dni, NIE jest ona uwzględniana w wartości sekund.

Dostaję przedział czasu między 2 czasami danych a drukowaniem dni i godzin.

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)
Alex L.
źródło
To rozwiązanie na przyszłość.
Jibin
11

Użyłem do tego humanfriendlybiblioteki Pythona, działa bardzo dobrze.

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

'5 minutes and 21 seconds'

Dostępne na https://pypi.org/project/humanfriendly/

Dhiraj Gupta
źródło
7

Podążając za powyższą przykładową wartością Joe, użyłbym operatora arytmetycznego modułu:

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

Zauważ, że podział liczb całkowitych w Pythonie domyślnie zaokrągla w dół; jeśli chcesz być bardziej precyzyjny, użyj odpowiednio math.floor () lub math.ceil ().

UltraNurd
źródło
timedelta już wie, jak się sformatować, jak w „print some_timedelta”.
stolarz
Tak, ale nie może zaakceptować ciągu o dowolnym formacie, o co pytał Michael. Chociaż teraz, gdy o tym myślę, mod dzielenia 3600 przyjmuje założenie godzin-sekund, które powoduje problemy w sekundach przestępnych.
UltraNurd
Tak, ale nie chce łańcucha o dowolnym formacie, chce prawie dokładnie zachowania domyślnego.
joeforker
2
Nie zapomnij // o obcięciu podziału w Pythonie 3000
joeforker
3
+1, ale dlaczego nie edytujesz odpowiedzi, aby użyć //? Sugeruję również używanie td.total_seconds()zamiast, .secondsaby działało w odstępach> 1 dzień.
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
Veselin Penev
źródło
Czy to napisałeś? Ile to przetestowałeś?
Thomas Ahle,
Używam tego kodu w moim projekcie o nazwie datahaven.net . Działa całkiem dobrze. Widziałeś jakieś błędy?
Veselin Penev,
Zawsze jest miło, jeśli możesz podać trochę informacji za pomocą takiego ciężkiego kodu :) Jak przykład tego, jak działa, możliwe mocne i słabe strony.
Thomas Ahle,
1
O. Pewnie!. Dodano przykład dla ciebie. :-)
Veselin Penev,
Super :) również zauważyć, że timedeltaobiekt ma pola days, secondsa microsecondsdokumentacja.
Thomas Ahle
4

Miałem podobny problem z wynikami obliczeń nadgodzin w pracy. Wartość powinna zawsze pojawiać się w GG: MM, nawet jeśli jest większa niż jeden dzień, a wartość może stać się ujemna. Połączyłem niektóre z przedstawionych rozwiązań i być może ktoś inny uzna to rozwiązanie za przydatne. Uświadomiłem sobie, że jeśli wartość timedelta jest ujemna, większość pokazanych rozwiązań metodą divmod nie działa od razu:

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 do HH: MM ciąg:

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'
nealtz
źródło
4
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))
SleX
źródło
2
w 3.7 otrzymuję AttributeError: obiekt „datetime.timedelta” nie ma atrybutu „strftime”
qubodup
4

Prosty filtr szablonów dla tego problemu. Wbudowana funkcja int () nigdy nie zaokrągla w górę. Ciągi F (tj. F '') wymagają Pythona 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
Patrick
źródło
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)

Spowoduje to:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'
Artem Wasilew
źródło
Najładniejszy moim zdaniem pod względem długości i tego, co obejmuje
Dici,
1

Sprawdź tę funkcję - konwertuje obiekt timedelta na ciąg „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)
MobilePro.pl
źródło
1

Jedna wkładka. Ponieważ timedeltas nie oferuje stretimeime datetime, przywróć timedelta do datetime i użyj stftime.

Może to nie tylko osiągnąć żądany format PO Godziny: Minuty, teraz możesz w pełni wykorzystać możliwości formatowania strtimeime datetime, jeśli twoje wymagania zmienią się na inną reprezentację.

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

To rozwiązuje również irytację, że timedeltas są formatowane w łańcuchy jako H: MM: SS zamiast HH: MM: SS, co doprowadziło mnie do tego problemu i rozwiązania, które udostępniłem.

Bill Gale
źródło
0

Jeśli masz już obiekt timedelta obj, po prostu przekonwertuj go na ciąg znaków. Usuń 3 ostatnie znaki ciągu i wydrukuj. Spowoduje to obcięcie części sekund i wydrukowanie reszty w formacie Godziny: Minuty.

t = str(timedeltaobj) 

print t[:-3]
Sima
źródło
Opcja -3 nie działa, lepiej użyćprint t.split('.')[0]
EvgenyKolyakov
0

Jeśli zdarzy ci się mieć IPythonw swoich pakietach (powinieneś), to ma (do tej pory i tak) bardzo fajny formatator na czas trwania (w sekundach zmiennoprzecinkowych). Jest to wykorzystywane w różnych miejscach, na przykład przez %%timemagię komórkową. Podoba mi się format, który produkuje przez krótki czas:

>>> 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
Pierre D.
źródło
-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)

Więc dla:

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

zwroty:

'0:03:47'
Aviad
źródło
-10

Dziękuję wszystkim za pomoc. Wziąłem wiele twoich pomysłów i zebrałem je razem, daj mi znać, co myślisz.

Dodałem do tej metody dwie metody:

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

W moim django użyłem tego (suma jest obiektem i znajduje się w słowniku):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>
mawcs
źródło
To jest trochę długie. Sugerowałbym: def hhmm (self): return ':'. Join (str (td) .split (':') [: 2]) <td> {{sum.1.hhmm}} </td>
joeforker
1
Wystarczy użyć divmod (), jak pokazano w przykładzie „Difference of Two Dates” na docs.python.org/release/2.5.2/lib/datetime-timedelta.html
Tom