Wie konvertiere ich Sekunden in Stunden, Minuten und Sekunden?

471

Ich habe eine Funktion, die Informationen in Sekunden zurückgibt, aber ich muss diese Informationen in Stunden: Minuten: Sekunden speichern.

Gibt es eine einfache Möglichkeit, die Sekunden in Python in dieses Format zu konvertieren?

Specto
quelle
20
Die Umkehrung dieses Problems finden Sie unter Wie konvertiere
Hughes

Antworten:

763

Sie können folgende datetime.timedeltaFunktion verwenden:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'
SilentGhost
quelle
9
Dies ist meiner Meinung nach der beste Weg, da Sie dann die Arithmetik für das Zeitdelta und alle Datums- / Uhrzeitobjekte verwenden können.
Matthew Schinckel
13
Dies funktioniert für mehrere Tage: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
Hyprnick
3
str(datetime.timedelta(seconds=round(666666.55)))rendert Tage korrekt; unterdrückt die Dezimalsekunden.
CPBL
1
timedeltaist nicht überlaufsicher und kann mathematische Operationen nicht korrekt ausführen, z. B. str(timedelta(hours=8) - timedelta(hours=10))das Ergebnis ist '-1 day, 22:00:00'und die ganzzahlige Lösung ist genau für die Situationen geeignet, in denen Sie sie benötigen '-02:00:00'.
21.
1
+1. Diese Antwort kann sehr einfach geändert werden. Wenn Sie beispielsweise beim Drucken ein Feld weglassen möchten, verwenden Sie
Folgendes
615

Wenn Sie die divmod()Funktion verwenden, die nur eine einzige Division ausführt, um sowohl den Quotienten als auch den Rest zu erzeugen, können Sie mit nur zwei mathematischen Operationen sehr schnell das Ergebnis erzielen:

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

Verwenden Sie dann die Zeichenfolgenformatierung , um das Ergebnis in die gewünschte Ausgabe zu konvertieren:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+
Brandon Rhodes
quelle
2
Wenn Sie Operatoren Funktionen vorziehen, verwenden Sie das Modulo. Zum Beispiel (nur Minuten / Sekunden):'%d:%02dmn' % (seconds / 60, seconds % 60)
Bufh
18
Und Sie können es auf Tage verlängern : d, h = divmod(h, 24).
Mark Ransom
14
@ MarkRansom: und dann zu Monaten m, d = divmod(m, 31). Hoppla, nein, das kannst du nicht. Schlimmer noch, Ihr Code wird falsch sein, wenn Schaltsekunden ins Spiel kommen. Lange Rede, kurzer timedeltaSinn : Verwenden Sie den Kalender und spielen Sie nicht mit ihm, er wird Sie beißen.
4
@Tibo befasst timedeltasich mit Schaltsekunden ? Ich vermute nicht. Es gibt viele Anwendungen, bei denen diese einfache Mathematik mehr als ausreichend ist.
Mark Ransom
1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))das Ergebnis ist '-1 Tag, 22:00:00', also ... idk, wenn es mit Schaltsekunden funktioniert, aber nicht mit negativen Zahlen.
cprn
70

Ich kann das kaum einfach benennen (zumindest kann ich mich nicht an die Syntax erinnern), aber es ist möglich, time.strftime zu verwenden , was mehr Kontrolle über die Formatierung gibt:

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 wird verwendet, um Sekunden in ein spezielles Tupelformat zu konvertieren, das strftime()erforderlich ist.

Hinweis: Wird nach 23:59:59 abgeschnitten

anatoly techtonik
quelle
Nun, die Antwort wird tatsächlich hier gegeben - stackoverflow.com/questions/1384406/…
anatoly techtonik
13
Leider beginnt diese Methode mit der Messung von Tagen ab 1, sodass sie nicht für die Darstellung des Zeitdeltas ausgelegt ist und daher ein Unfall ist, der darauf wartet, passiert zu werden. Zum Beispiel mit time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 Tag, 0:00:01'.
Riaz Rizvi
41

Verwenden von datetime:

Mit dem ':0>8' Format:

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'

Ohne das ':0>8' Format:

"{}".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'

Verwenden von 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
quelle
1
es schlägt fehl, wenn das Delta weniger als eine Sekunde ist:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs
1
An alle anderen: Im without ':0>8':Beispiel fehlt eine führende 0. {:0>8}Null-Pads links 8 Nullen.
TankorSmash
2
In Python 3.5.2 erhalte ich einen TypeError. Ich formatiere eine time.time()-startVariable. Irgendein Einblick? TypeError: non-empty format string passed to object.__format__
Medley56
Ich habe versucht, mein timedelta-Objekt datetime.now()anstelle von time.time()zu generieren, und es wird der gleiche Fehler angezeigt.
Medley56
@ medley56 Wenn Sie Python3 verwenden, müssen Sie Folgendes verwenden, str()wenn Sie ein Format wie das folgende verwenden möchten 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Überprüfen Sie diese Antwort für weitere Informationen.
Berriel
22

Das ist mein schneller Trick:

from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'

Weitere Informationen finden Sie unter: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan

Türen
quelle
Sie haben keine Ahnung, wie lange ich nach dieser Antwort gesucht habe. Ich danke dir sehr. Ich wünschte, ich könnte dir mehr als +1 geben.
Peppa
9

Wenn Sie datetime.timeWert erhalten möchten, können Sie diesen Trick verwenden:

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

Sie können nicht hinzufügen timedeltazu time, aber kann es in derdatetime .

UPD : Noch eine Variation derselben Technik:

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

Stattdessen 1können Sie eine beliebige Zahl größer als 0 verwenden. Hier verwenden wir die Tatsache, dass datetime.fromordinalimmer ein datetimeObjekt zurückgegeben wird, dessen timeKomponente Null ist.

MarSoft
quelle
6

So habe ich es bekommen.

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)

Einige Beispiele:

$ 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']
Lee
quelle
1
Was ist der Vorteil gegenüber der obigen Antwort? str(datetime.timedelta(seconds=666))
Riaz Rizvi
@RiazRizvi gibt eine konsistente Zeichenfolgenlänge für Mikrosekunden für 666.0und 666.1Werte an.
Anatoly Techtonik
6

Das folgende Set hat bei mir funktioniert.

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']
naiver Decoder
quelle
3

dateutil.relativedeltaDies ist praktisch, wenn Sie auch auf Stunden, Minuten und Sekunden als Floats zugreifen müssen. datetime.timedeltabietet keine ähnliche Schnittstelle.

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

Druckt

40.0
01:30:40
teekarna
quelle
1
Ich erhalte eine andere Ausgabe von Ihrer, was mich denken lässt, dass Sie einen Tippfehler haben. Sie wollten wahrscheinlich seconds=5440anstelle von verwenden seconds=5540. Ihre Antwort gefällt mir jedoch!
JL
2

Stunden (h) berechnet durch Bodenteilung (durch //) von Sekunden durch 3600 (60 min / h * 60 s / min)

Minuten (m) berechnet durch Bodenteilung der verbleibenden Sekunden (Rest aus Stundenberechnung, in%) durch 60 (60 s / min)

in ähnlicher Weise Sekunden nach Berechnung der restlichen Stunde und Minuten.

Rest ist nur String-Formatierung!

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
quelle
Während dieser Code eine Lösung für die Frage des OP bietet, ist es besser, einen Kontext hinzuzufügen, warum / wie er funktioniert. Dies kann zukünftigen Benutzern helfen, zu lernen und dieses Wissen auf ihren eigenen Code anzuwenden. Es ist auch wahrscheinlich, dass Sie positive Rückmeldungen von Benutzern in Form von Upvotes erhalten, wenn der Code erklärt wird.
Borchvm
2
Ich habe es gerade getan, danke @borchvm für den Hinweis!
Sam
-2

Sie können Sekunden durch 60 teilen, um die Minuten zu erhalten

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

Wenn Sie es erneut durch 60 teilen, erhalten Sie die Stunden

alosha002
quelle
-3

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

PS Mein Code ist unprofessionell

Denis Kerstens Denisik35
quelle
2
Hey, die Frage nach einem Format in Std.: Min.: Sek., keine einfache Unterteilung.
StupidWolf