在Python中减去两次


117

我有两个datetime.time值,exit并且enter想做类似的事情:

duration = exit - enter

但是,我收到此错误:

TypeError:-:“ datetime.time”和“ datetime.time”的不受支持的操作数类型

如何正确执行此操作?一种可能的解决方案是将time变量转换为datetime变量,然后进行推导,但是我敢肯定你们必须有一种更好,更清洁的方法。

Answers:


91

试试这个:

from datetime import datetime, date

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

combine 建立一个可以减去的日期时间。


2
对于@ IgnacioVazquez-Abrams来说,可以使用datetime(1,1,1,0,0,0)代替date.today()
Akavall 2014年

25
不要命名为datetime exit,因为exit它是内置函数。
orokusaki

1
使用python 2.7,combine我的datetime模块中没有方法: AttributeError: 'module' object has no attribute 'combine'
mtoloo

6
mtoloo:有datetime模块,datetime内部有一个对象。里面的对象有combine方法。如果您只是在导入datetime(例如:)import datetime,那么以后需要做的就是this datetime.datetime.combine
gruszczy

1
在极少数情况下,您有时会在23:59:59:9999之类的时间调用此函数。在这种情况下,date.today() 之前和date.today()之后将返回不同的值。最好将值date.today()赋予变量。
拉姆温

44

用:

from datetime import datetime, date

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

使用起来date.min更加简洁,甚至可以在午夜使用。

date.today()如果第一个调用发生在23:59:59,而下一个调用发生在00:00:00,则可能不是这样,否则可能返回意外结果。


1
同意您。
拉姆温

27

而不是使用时间尝试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)

2
谢谢。这是很干净,胜过一切的答案在这里- stackoverflow.com/questions/3096953/...
Pushpak Dagade

7

datetime.time不支持这一点,因为以这种方式减去时间几乎没有意义。datetime.datetime如果要执行此操作,请使用完整的。


53
如果您从自己的域中知道两个datetime.time对象ab来自同一天,并且来自b > a,则该操作b - a具有完美的含义。
swalog 2014年

4
即使不是同一天,这也很有意义。至少和一样有意义arctan(0) = (0, pi, 2pi, ...),但是我们只关心第一个之后的那些值。那么,4:00 - 20:008:00-它也(32:0056:00,...),但谁在乎呢?
naught101


7
此外,Python甚至不能保持一致。如果a-b对于两个时间对象无意义,那么a> b或a <b的行为如何?比较已经在同一天进行,否则将被完全破坏。由于假设是为了进行比较,因此对差异运算进行相同假设是完全一致的。
肖恩

1
说这毫无意义是主观的,但是我知道你来自哪里。对我而言,两次相加似乎毫无意义。我认为减去两个时间值应返回一个timedelta。如果该时间差碰巧是负数,那就去吧。我想知道的是为什么python无法从时间中添加或减去timedelta以返回新的时间值。
aj.toulan

7

您有两个datetime.time对象,因此您只需使用datetime.timedetla创建两个timedelta,然后像现在一样使用“-”操作数进行减法。以下是不使用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是您的差异,您可以出于自己的原因使用它。


可以将timedelta对象转换回datetime吗?我的意思是我们有difference_delta .seconds(),有什么方法可以找回日期时间或时间对象吗?Thx
dejdej

是。 datetime.min + delta
sourcedelica

6

python timedelta库应该可以满足您的需求。timedelta当减去两个datetime实例时,将返回A。

import datetime
dt_started = datetime.datetime.utcnow()

# do some stuff

dt_ended = datetime.datetime.utcnow()
print((dt_ended - dt_started).total_seconds())

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

3

datetime.time 无法做到-但是您可以使用 datetime.datetime.now()

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

2

当您遇到类似的情况时,我最终使用了名为arrow的外部库。

看起来是这样的:

>>> import arrow
>>> enter = arrow.get('12:30:45', 'HH:mm:ss')
>>> exit = arrow.now()
>>> duration = exit - enter
>>> duration
datetime.timedelta(736225, 14377, 757451)

1
在这里,您只是演示减去完整的日期时间对象,而不是原始问题中的时间
kleptog
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.