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?


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'

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+

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


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

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


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.


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

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

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

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

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


-3

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

PS Mein Code ist unprofessionell


2
Hey, die Frage nach einem Format in Std.: Min.: Sek., keine einfache Unterteilung.
StupidWolf
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.