파이썬에서 두 번 빼기


117

두 가지 datetime.time값이 exit있으며 enter다음과 같이하고 싶습니다.

duration = exit - enter

그러나 다음 오류가 발생합니다.

TypeError :-에 대해 지원되지 않는 피연산자 유형 : 'datetime.time'및 'datetime.time

이 작업을 올바르게 수행하는 방법은 무엇입니까? 한 가지 가능한 해결책은 time변수를 datetime변수 로 변환 한 다음 하위 구조 로 변환하는 것입니다.하지만 여러분이 더 좋고 깨끗한 방법을 가지고 있어야한다고 확신합니다.

답변:


91

이 시도:

from datetime import datetime, date

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

combine 뺄 수있는 datetime을 빌드합니다.


2
@ IgnacioVazquez-Abrams 포인트 datetime(1,1,1,0,0,0)에 대해 date.today().
— Akavall 2014 년

25
는 내장 함수 datetime exit이므로 이름을 지정하지 마십시오 exit.
— orokusaki 2015 년

1
파이썬 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()변수에 값 을 제공하는 것이 좋습니다 .
— ramwin

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
당신과 동의.
— ramwin

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오브젝트를 a하고 b같은 날에서, 그리고 그 b > a다음 작업은 b - a완벽한 의미를 갖습니다.
— swalog

4
같은 날이 아니더라도 그래도 괜찮습니다. 최소한.만큼 의미가 arctan(0) = (0, pi, 2pi, ...)있지만 우리는 첫 번째 이후의 값에 대해서는 신경 쓰지 않습니다. 그래서 4:00 - 20:00입니다 8:00- 그건 또한 ( 32:00, 56:00, ...),하지만 누가 걱정?
— naught101


7
게다가 파이썬은 일관성을 유지하지도 않습니다. a-b가 두 시간 객체에 대해 무의미하다면 a> b 또는 a <b가 어떻게 작동합니까? 비교는 이미 같은 날을 가정하고 있습니다. 그렇지 않으면 완전히 깨졌습니다. 비교를위한 가정이므로 차이 연산에 대해 동일한 가정을하는 것은 전적으로 일관됩니다.
— Sean

1
무의미하다고 말하는 것은 주관적이지만 어디에서 왔는지 알 수 있습니다. 두 번 더하는 것은 나에게 의미없는 표현 인 것 같다. 두 시간 값을 빼면 timedelta가 반환되어야한다고 생각합니다. 해당 타임 델타가 음수이면 그렇게됩니다. 내가 알고 싶은 것은 파이썬이 새로운 시간 값을 반환하기 위해 시간에서 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

difference_delta 는 귀하의 이유로 사용할 수있는 차이 입니다.


timedelta 객체를 datetime으로 다시 변환 할 수 있습니까? 내 말은 차이 _delta .seconds ()가 있다는 것을 의미합니다. datetime 또는 time 객체를 되돌릴 수있는 방법이 있습니까? Thx
— dejdej

예. datetime.min + delta
— sourcedelica 2019

6

파이썬 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

나는 당신과 비슷한 상황을 겪었고 화살표 라는 외부 라이브러리를 사용하게되었습니다 .

다음은 다음과 같습니다.

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

1
여기에서는 원래 질문에서와 같이 시간이 아닌 완전한 datetime 객체를 빼는 것을 보여주고 있습니다
— kleptog
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.