subtrahiere zweimal in Python

115

Ich habe zwei datetime.timeWerte exitund entermöchte etwas tun wie:

duration = exit - enter

Ich erhalte jedoch diesen Fehler:

TypeError: Nicht unterstützte Operandentypen für -: 'datetime.time' und 'datetime.time

Wie mache ich das richtig? Eine mögliche Lösung besteht darin, die timeVariablen in datetimeVariablen umzuwandeln und dann zu subtruieren, aber ich bin sicher, dass Sie einen besseren und saubereren Weg haben müssen.

Chaggster
quelle

Antworten:

90

Versuche dies:

from datetime import datetime, date

datetime.combine(date.today(), exit) - datetime.combine(date.today(), enter)

combine erstellt eine datetime, die subtrahiert werden kann.

gruszczy
quelle
2
Zu @ IgnacioVazquez-Abrams Punkt könnte man beispielsweise datetime(1,1,1,0,0,0)anstelle von verwenden date.today().
Akavall
24
Nennen Sie nicht a datetime exit, da dies exiteine integrierte Funktion ist.
Orokusaki
1
Mit Python 2.7 habe ich keine combineMethode in meinem datetimeModul: AttributeError: 'module' object has no attribute 'combine'
Mtoloo
6
mtoloo: Es gibt ein datetimeModul und es enthält ein datetimeObjekt. Das Objekt im Inneren hat eine combineMethode. Wenn Sie einfach importieren datetime(wie import datetimefolgt :), müssen Sie dies später tun datetime.datetime.combine.
gruszczy
1
Es gibt einen sehr seltenen Fall, wenn Sie diese Funktion zu einem bestimmten Zeitpunkt wie 23: 59: 59: 9999 aufrufen. In diesem Fall geben das date.today() Vorher und das date.today()Spätere einen anderen Wert zurück. Es wäre besser, den Wert date.today()einer Variablen zu geben .
Ramwin
44

Verwenden:

from datetime import datetime, date

duration = datetime.combine(date.min, end) - datetime.combine(date.min, beginning)

Die Verwendung date.minist etwas prägnanter und funktioniert sogar um Mitternacht.

Dies ist möglicherweise nicht der Fall date.today(), da dies zu unerwarteten Ergebnissen führen kann, wenn der erste Anruf um 23:59:59 Uhr und der nächste um 00:00:00 Uhr erfolgt.

Alexpirin
quelle
1
Ich stimme dir zu.
Ramwin
27

Anstatt Zeit zu verwenden, versuchen Sie es mit timedelta:

from datetime import timedelta

t1 = timedelta(hours=7, minutes=36)
t2 = timedelta(hours=11, minutes=32)
t3 = timedelta(hours=13, minutes=7)
t4 = timedelta(hours=21, minutes=0)

arrival = t2 - t1
lunch = (t3 - t2 - timedelta(hours=1))
departure = t4 - t3

print(arrival, lunch, departure)
Edmilson Junior
quelle
2
Vielen Dank. Dies ist sehr sauber und besser als alle Antworten hier - stackoverflow.com/questions/3096953/…
Pushpak Dagade
7

datetime.timeunterstützt dies nicht, da es nahezu bedeutungslos ist, Zeiten auf diese Weise zu subtrahieren. Verwenden Sie eine vollständige, datetime.datetimewenn Sie dies tun möchten.

Ignacio Vazquez-Abrams
quelle
53
Wenn Sie von Ihrer Domain wissen , dass zwei datetime.timeObjekte aund bsind aus dem gleichen Tag, und das b > a, dann geht der Vorgang b - ahat eine perfekte Bedeutung.
Swalog
4
Auch wenn sie nicht am selben Tag sind, macht es dennoch Sinn. Mindestens so viel Sinn wie arctan(0) = (0, pi, 2pi, ...), aber wir kümmern uns einfach nicht um einen dieser Werte nach dem ersten. So 4:00 - 20:00ist 8:00- es ist auch ( 32:00, 56:00, ...), aber wen stört das schon?
naught101
7
Darüber hinaus bleibt Python nicht einmal konsistent. Wenn a - b für zwei Zeitobjekte bedeutungslos ist, wie verhält sich dann a> b oder a <b so wie es ist? Der Vergleich geht bereits vom selben Tag aus, sonst ist er komplett kaputt. Da die Annahme zum Vergleich gemacht wird, ist es völlig konsistent, dieselbe Annahme für Differenzoperationen zu machen.
Sean
1
Zu sagen, dass es bedeutungslos ist, ist subjektiv, aber ich sehe, woher du kommst. Das zweimalige Addieren scheint mir eine bedeutungslose Darstellung zu sein. Ich denke, das Subtrahieren von zwei Zeitwerten sollte ein Zeitdelta ergeben. Wenn dieses Zeitdelta negativ ist, soll es so sein. Ich möchte wissen, warum Python ein Zeitdelta nicht zu einer Zeit addieren oder von dieser subtrahieren kann, um einen neuen Zeitwert zurückzugeben.
Aj.toulan
7

Die Python- Timedelta- Bibliothek sollte das tun, was Sie brauchen. A timedeltawird zurückgegeben, wenn Sie zwei datetimeInstanzen subtrahieren .

import datetime
dt_started = datetime.datetime.utcnow()

# do some stuff

dt_ended = datetime.datetime.utcnow()
print((dt_ended - dt_started).total_seconds())
Ben
quelle
6

Sie haben zwei datetime.time-Objekte, sodass Sie mit datetime.timedetla nur zwei timedelta erstellen und dann wie jetzt mit dem Operanden "-" subtrahieren. Im Folgenden finden Sie ein Beispiel für die zweimalige Subtraktion ohne Verwendung von datetime.

enter = datetime.time(hour=1)  # Example enter time
exit = datetime.time(hour=2)  # Example start time
enter_delta = datetime.timedelta(hours=enter.hour, minutes=enter.minute, seconds=enter.second)
exit_delta = datetime.timedelta(hours=exit.hour, minutes=exit.minute, seconds=exit.second)
difference_delta = exit_delta - enter_delta

different_delta ist Ihr Unterschied, den Sie aus Ihren Gründen verwenden können.

Hardik Patel
quelle
Ist es möglich, das timedelta-Objekt zurück in datetime zu konvertieren? Ich meine, wir haben different_delta .seconds (). Gibt es eine Möglichkeit, ein Datum / Uhrzeit- oder Zeitobjekt zurückzugewinnen? Thx
dejdej
Ja. datetime.min + delta
Sourcedelica
4
import datetime

def diff_times_in_seconds(t1, t2):
    # caveat emptor - assumes t1 & t2 are python times, on the same day and t2 is after t1
    h1, m1, s1 = t1.hour, t1.minute, t1.second
    h2, m2, s2 = t2.hour, t2.minute, t2.second
    t1_secs = s1 + 60 * (m1 + 60*h1)
    t2_secs = s2 + 60 * (m2 + 60*h2)
    return( t2_secs - t1_secs)

# using it
diff_times_in_seconds( datetime.datetime.strptime( "13:23:34", '%H:%M:%S').time(),datetime.datetime.strptime( "14:02:39", '%H:%M:%S').time())
Jacanterbury
quelle
4

datetime.time kann es nicht - aber du könntest es benutzen datetime.datetime.now()

start = datetime.datetime.now()
sleep(10)
end = datetime.datetime.now()
duration = end - start
gies0r
quelle
2

Ich hatte eine ähnliche Situation wie Sie und habe am Ende eine externe Bibliothek namens Pfeil verwendet .

So sieht es aus:

>>> import arrow
>>> enter = arrow.get('12:30:45', 'HH:mm:ss')
>>> exit = arrow.now()
>>> duration = exit - enter
>>> duration
datetime.timedelta(736225, 14377, 757451)
rominf
quelle
1
Hier demonstrieren Sie nur das Subtrahieren vollständiger datetime-Objekte, nicht der Tageszeit wie in der ursprünglichen Frage
kleptog