Jak przekonwertować sekundy na godziny, minuty i sekundy?

469

Mam funkcję, która zwraca informacje w ciągu kilku sekund, ale muszę przechowywać te informacje w godzinach: minutach: sekundach.

Czy istnieje prosty sposób na konwersję sekund na ten format w Pythonie?

Specto
źródło
20
Odwrotność tego problemu można znaleźć na stronie Jak przekonwertować ciąg czasu H: MM: SS na sekundy w Pythonie?
obejmuje

Odpowiedzi:

760

Możesz użyć datetime.timedeltafunkcji:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'
SilentGhost
źródło
8
Jest to najlepszy sposób, IMHO, ponieważ można następnie zastosować arytmetykę na timedelcie i dowolnych obiektach daty i godziny.
Matthew Schinckel
12
Działa to przez wiele dni: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
hyprnick,
3
str(datetime.timedelta(seconds=round(666666.55)))poprawnie renderuje dni; pomija sekundy dziesiętne.
CPBL
1
timedeltanie jest bezpieczny przed przepełnieniem i nie może poprawnie wykonywać operacji matematycznych, np str(timedelta(hours=8) - timedelta(hours=10)). wynik jest, '-1 day, 22:00:00'a rozwiązanie oparte na liczbach całkowitych jest dokładnie w tych sytuacjach, w których potrzebujesz '-02:00:00'.
cprn
1
+1. Ta odpowiedź może być bardzo łatwo zmodyfikowana. Na przykład, jeśli chcesz pominąć pole podczas drukowania, użyj tego: stackoverflow.com/questions/7999935/…
eric_kernfeld 10.10.2018
614

Używając divmod()funkcji, która wykonuje tylko jeden podział w celu wygenerowania zarówno ilorazu, jak i reszty, możesz bardzo szybko uzyskać wynik za pomocą tylko dwóch operacji matematycznych:

m, s = divmod(seconds, 60)
h, m = divmod(m, 60)

A następnie użyj formatowania ciągów, aby przekonwertować wynik na pożądany wynik:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+
Brandon Rhodes
źródło
2
Jeśli wolisz operatory niż funkcje, użyj modulo; na przykład (tylko minuty / sekundy):'%d:%02dmn' % (seconds / 60, seconds % 60)
bufh
18
I można go przedłużyć do dni: d, h = divmod(h, 24).
Mark Ransom
14
@MarkRansom: a następnie do miesięcy m, d = divmod(m, 31). Ups, nie, nie możesz. Co gorsza, twój kod będzie nieprawidłowy, jeśli w grze pojawią się sekundy przestępne. Krótko mówiąc: używaj timedeltai nie zadzieraj z kalendarzem, to cię ugryzie.
4
@ Tibo timedeltazajmuje się sekundami przestępnymi? Nie podejrzewam Istnieje wiele aplikacji, w których ta prosta matematyka jest więcej niż wystarczająca.
Mark Ransom
1
@ MarkRansom str(timedelta(hours=8) - timedelta(hours=10))wynikiem jest „-1 dzień, 22:00:00”, więc ... idk, jeśli działa z sekundami przestępnymi, ale nie działa z liczbami ujemnymi.
cprn
69

Trudno nazwać to łatwym sposobem (przynajmniej nie pamiętam składni), ale można użyć time.strftime , który daje większą kontrolę nad formatowaniem:

from time import strftime
from time import gmtime

strftime("%H:%M:%S", gmtime(666))
'00:11:06'

strftime("%H:%M:%S", gmtime(60*60*24))
'00:00:00'

gmtime służy do konwertowania sekund na specjalny strftime()wymagany krotek .

Uwaga: Obcina po 23:59:59

anatoly techtonik
źródło
Odpowiedź jest podana tutaj - stackoverflow.com/questions/1384406/…
anatoly techtonik
13
Niestety ta metoda zaczyna mierzyć dni od 1, więc nie jest zaprojektowana do reprezentowania delty czasowej, a więc jest to wypadek, który czeka. Na przykład z time.strftime('%d %H:%M:%S', time.gmtime(1))=> „1 dzień, 0:00:01”.
Riaz Rizvi
40

Używanie datetime:

W ':0>8'formacie:

from datetime import timedelta

"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Bez ':0>8'formatu:

"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Używanie time:

from time import gmtime
from time import strftime

# NOTE: The following resets if it goes over 23:59:59!

strftime("%H:%M:%S", gmtime(125))
# Result: '00:02:05'

strftime("%H:%M:%S", gmtime(60*60*24-1))
# Result: '23:59:59'

strftime("%H:%M:%S", gmtime(60*60*24))
# Result: '00:00:00'

strftime("%H:%M:%S", gmtime(666777))
# Result: '17:12:57'
# Wrong
Marcell
źródło
1
kończy się niepowodzeniem, jeśli delta jest mniejsza niż sekunda:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs
1
Do wszystkich innych: w without ':0>8':przykładzie brakuje wiodących {:0>8}padów zerowych na lewe 8 zer.
TankorSmash
2
W python 3.5.2 dostaję błąd typu. Formatuję time.time()-startzmienną. Jakiś wgląd? TypeError: non-empty format string passed to object.__format__
medley56,
Próbowałem użyć datetime.now()zamiast time.time()wygenerować mój obiekt timedelta i otrzymuję ten sam błąd.
medley56,
@ medley56 Podczas korzystania Python3, trzeba użyć str(), jeśli masz zamiar użyć formatu takich jak 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Sprawdź tę odpowiedź, aby uzyskać więcej informacji.
Berriel,
9

Jeśli chcesz uzyskać datetime.timewartość, możesz użyć tej sztuczki:

my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()

Nie możesz dodawać timedeltado time, ale możesz dodać do datetime.

UPD : Kolejna odmiana tej samej techniki:

my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()

Zamiast tego 1możesz użyć dowolnej liczby większej niż 0. W tym przypadku wykorzystujemy fakt, że datetime.fromordinalzawsze zwróci datetimeobiekt o timeskładniku równym zero.

MarSoft
źródło
6

Tak to dostałem.

def sec2time(sec, n_msec=3):
    ''' Convert seconds to 'D days, HH:MM:SS.FFF' '''
    if hasattr(sec,'__len__'):
        return [sec2time(s) for s in sec]
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    d, h = divmod(h, 24)
    if n_msec > 0:
        pattern = '%%02d:%%02d:%%0%d.%df' % (n_msec+3, n_msec)
    else:
        pattern = r'%02d:%02d:%02d'
    if d == 0:
        return pattern % (h, m, s)
    return ('%d days, ' + pattern) % (d, h, m, s)

Kilka przykładów:

$ sec2time(10, 3)
Out: '00:00:10.000'

$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'

$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'

$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']
Zawietrzny
źródło
1
Jaka jest przewaga tego nad powyższą odpowiedzią? str(datetime.timedelta(seconds=666))
Riaz Rizvi
@RiazRizvi podaje stałą długość ciągu dla mikrosekund 666.0i 666.1wartości.
anatoly techtonik
6

Poniższy zestaw działał dla mnie.

def sec_to_hours(seconds):
    a=str(seconds//3600)
    b=str((seconds%3600)//60)
    c=str((seconds%3600)%60)
    d=["{} hours {} mins {} seconds".format(a, b, c)]
    return d


print(sec_to_hours(10000))
# ['2 hours 46 mins 40 seconds']

print(sec_to_hours(60*60*24+105))
# ['24 hours 1 mins 45 seconds']
naiwny dekoder
źródło
3

dateutil.relativedeltajest wygodny, jeśli chcesz mieć dostęp do godzin, minut i sekund jako pływaków. datetime.timedeltanie zapewnia podobnego interfejsu.

from dateutil.relativedelta import relativedelta
rt = relativedelta(seconds=5440)
print(rt.seconds)
print('{:02d}:{:02d}:{:02d}'.format(
    int(rt.hours), int(rt.minutes), int(rt.seconds)))

Wydruki

40.0
01:30:40
teekarna
źródło
1
Dostaję inne wyniki niż twoje, co sprawia, że ​​myślę, że masz literówkę. Prawdopodobnie chciałeś użyć seconds=5440zamiast seconds=5540. Jednak podoba mi się twoja odpowiedź!
JL
2

godziny (h) obliczone przez podział podłogi (przez //) sekund na 3600 (60 min / godz. * 60 sek / min)

minuty (m) obliczone przez podział podłogowy pozostałych sekund (pozostała część z obliczenia godziny, w%) o 60 (60 sekund / min)

podobnie, sekundy (s) w pozostałej części obliczenia godziny i minuty.

Reszta to tylko formatowanie ciągów!

def hms(seconds):
    h = seconds // 3600
    m = seconds % 3600 // 60
    s = seconds % 3600 % 60
    return '{:02d}:{:02d}:{:02d}'.format(h, m, s)

print(hms(7500))  # Should print 02h05m00s
Sam
źródło
Chociaż ten kod może stanowić rozwiązanie pytania PO, lepiej jest dodać kontekst wyjaśniający, dlaczego / jak to działa. Może to pomóc przyszłym użytkownikom w nauce i zastosowaniu tej wiedzy do własnego kodu. Prawdopodobnie będziesz otrzymywać pozytywne opinie od użytkowników w postaci pozytywnych opinii, gdy kod zostanie wyjaśniony.
borchvm
2
Właśnie zrobiłem, dziękuję @borchvm za wskazanie!
Sam
-2

Możesz podzielić sekundy przez 60, aby uzyskać minuty

import time
seconds = time.time()
minutes = seconds / 60
print(minutes)

Kiedy ponownie podzielisz go przez 60, dostaniesz godziny

alosha002
źródło
-3

division = 3623 // 3600 #to hours
division2 = 600 // 60 #to minutes
print (division) #write hours
print (division2) #write minutes

PS Mój kod jest nieprofesjonalny

Denis Kerstens Denisik35
źródło
2
hej, zadaj pytanie o format w godzinach: min: s, a nie prosty podział ..
StupidWolf