Konvertieren Sie ein Zeitdelta in Tage, Stunden und Minuten

242

Ich habe ein Zeitdelta. Ich möchte die Tage, Stunden und Minuten davon - entweder als Tupel oder als Wörterbuch ... Ich bin nicht aufgeregt.

Ich muss dies im Laufe der Jahre ein Dutzend Mal in einem Dutzend Sprachen getan haben, aber Python hat normalerweise eine einfache Antwort auf alles, also dachte ich, ich würde hier fragen, bevor ich eine widerlich einfache (und dennoch ausführliche) Mathematik herausbringe.

Herr Fooz spricht einen guten Punkt an.

Ich habe es mit "Listings" zu tun (ein bisschen wie bei eBay-Listings), bei denen jeder eine Dauer hat. Ich versuche, die verbleibende Zeit zu findenwhen_added + duration - now

Habe ich Recht, wenn ich sage, dass die Sommerzeit nicht berücksichtigt wird? Wenn nicht, wie lässt sich eine Stunde am einfachsten addieren / subtrahieren?

Oli
quelle
Wenn Sie es nur als Zeichenfolge im Format HH: mm: ss erhalten möchten , sagen Sie "0:19:37" aus dem timedeltaObjekt "datetime.timedelta (Sekunden = 1177)" : Verwenden Sie
Peter Mortensen,

Antworten:

342

Wenn Sie einen datetime.timedeltaWert haben td, erhalten Sie td.daysbereits die gewünschten "Tage". timedeltaWerte halten den Bruchteil des Tages als Sekunden (nicht direkt Stunden oder Minuten), sodass Sie in der Tat "widerlich einfache Mathematik" durchführen müssen, z.

def days_hours_minutes(td):
    return td.days, td.seconds//3600, (td.seconds//60)%60
Alex Martelli
quelle
1
Denken Sie daran, dass wenn tdnegativ ist, -1 // 3600ist -1.
jcrs
4
Warum // ? anstelle von /
Mohammed Shareef C
10
//wird verwendet /, um eine Ganzzahl zu erhalten, keinen Gleitkommawert. //ist ein Floor-Division-Operator: "Division, die zu einer ganzen Zahl führt, die in der Zahlenreihe links angepasst ist", siehe hier .
Eerik Sven Puudist
1
@EerikSvenPuudist wie jcrserwähnt, -1//3600ist -1, warum also nicht verwenden , int(td.seconds/3600)anstatt zu drehen -1in der zweiten 0Stunden anstatter 1Stunde nach hinten?
Simpleuser
Wie wäre es, wenn Sie auch die verbleibenden Sekunden hinzufügen? days, hours, minutes = x.days, x.seconds // 3600, x.seconds %3600//60und dann seconds = x.seconds - hours*3600 - minutes*60
Raphael
73

Dies ist etwas kompakter, Sie erhalten die Stunden, Minuten und Sekunden in zwei Zeilen.

days = td.days
hours, remainder = divmod(td.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# If you want to take into account fractions of a second
seconds += td.microseconds / 1e6
Mberacochea
quelle
7
Es ist falsch, wenn td.dayses nicht Null ist. Du brauchst hours += td.days*24. Wenn Sie Sekundenbruchteile berücksichtigen möchten (OP nicht); seconds += td.microseconds / 1e6könnte verwendet werden.
JFS
30
days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

Was die Sommerzeit betrifft, denke ich, ist es am besten, beide datetimeObjekte in Sekunden umzuwandeln . Auf diese Weise berechnet das System die Sommerzeit für Sie.

>>> m13 = datetime(2010, 3, 13, 8, 0, 0)  # 2010 March 13 8:00 AM
>>> m14 = datetime(2010, 3, 14, 8, 0, 0)  # DST starts on this day, in my time zone
>>> mktime(m14.timetuple()) - mktime(m13.timetuple())     # difference in seconds
82800.0
>>> _/3600                                                # convert to hours
23.0
Jason Orendorff
quelle
1
mktime()kann fehlschlagen, wenn die lokale Zeitzone zu unterschiedlichen Zeiten einen anderen utc-Offset aufweist (viele tun dies) - Sie können das pytzModul verwenden, um auf tragbare deteministische Weise auf die tz-Datenbank zuzugreifen. Außerdem kann die Ortszeit nicht eindeutig sein (50% Fehlerwahrscheinlichkeit) - Sie benötigen einige zusätzliche Informationen, um eindeutig zu sein, z. B. sind häufig (nicht immer) Daten in einer Protokolldatei eintönig . Siehe Wie kann ich einen Tag von einem Python-Datum abziehen? das muss sich möglicherweise mit ähnlichen Problemen befassen.
JFS
7

Ich verstehe nicht

days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

Wie wäre es damit

days, hours, minutes = td.days, td.seconds // 3600, td.seconds % 3600 / 60.0

Sie erhalten Minuten und Sekunden einer Minute als Schwimmer.

Campbell
quelle
0

Ich habe folgendes verwendet:

delta = timedelta()
totalMinute, second = divmod(delta.seconds, 60)
hour, minute = divmod(totalMinute, 60)
print(f"{hour}h{minute:02}m{second:02}s")
Mathieu CAROFF
quelle
-2

timedeltas haben ein daysund secondsAttribut .. Sie können sie mit Leichtigkeit selbst konvertieren.

Jochen Ritzel
quelle