Python에서 datetime.time에 N 초를 추가하는 표준 방법은 무엇입니까?


369

datetime.timePython 에 값이 주어지면 정수 초를 추가하는 표준 방법이 있습니까? 예를 들어 11:34:59+ 3 = 11:35:02입니까?

이 명백한 아이디어는 효과가 없습니다.

>>> datetime.time(11, 34, 59) + 3
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'int'
>>> datetime.time(11, 34, 59) + datetime.timedelta(0, 3)
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.timedelta'
>>> datetime.time(11, 34, 59) + datetime.time(0, 0, 3)
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.time'

결국 나는 다음과 같은 기능을 작성했다.

def add_secs_to_time(timeval, secs_to_add):
    secs = timeval.hour * 3600 + timeval.minute * 60 + timeval.second
    secs += secs_to_add
    return datetime.time(secs // 3600, (secs % 3600) // 60, secs % 60)

그래도 더 쉬운 방법이 없다고 생각하면 도움이되지 않습니다.

관련


관련 파이썬 문제 : datetime.time '+'및 '-'지원
jfs

답변:


499

datetime와 함께 전체 변수를 사용할 수 있으며 timedelta더미 날짜를 제공 한 다음 time시간 값을 얻기 위해 사용 합니다.

예를 들면 다음과 같습니다.

import datetime
a = datetime.datetime(100,1,1,11,34,59)
b = a + datetime.timedelta(0,3) # days, seconds, then other fields.
print(a.time())
print(b.time())

3 초 간격으로 두 값이 생성됩니다.

11:34:59
11:35:02

더 읽기 쉬운 것을 선택할 수도 있습니다

b = a + datetime.timedelta(seconds=3)

당신이 너무 기울어 있다면.


이 작업을 수행 할 수있는 기능을 수행하는 경우 addSecs아래 를 사용하여 살펴볼 수 있습니다.

import datetime

def addSecs(tm, secs):
    fulldate = datetime.datetime(100, 1, 1, tm.hour, tm.minute, tm.second)
    fulldate = fulldate + datetime.timedelta(seconds=secs)
    return fulldate.time()

a = datetime.datetime.now().time()
b = addSecs(a, 300)
print(a)
print(b)

이 결과는 다음과 같습니다.

 09:11:55.775695
 09:16:55

6
OverflowErrors를 피하기 위해 다른 더미 날짜를 사용하는 것이 좋습니다. 예를 들어 몇 년 후 : datetime (101,1,1,11,34,59). 1보다 작은 수 없습니다 날짜 시간 객체의 해로 오류 : "범위를 벗어난 날짜 값 OverflowError"위의 날짜로부터 큰 timedelta을 뺀하려고하면, 당신은 얻을 것이다
pheelicks

2
@pheelicks, 완료되었지만, 민첩한 응답 시간이 아니라 약간 늦었지만, 내 코드에서 다른 버그를 수정해야했기 때문에 제안 사항을 동시에 통합 할 것이라고 생각했습니다.
paxdiablo

53

여기에 다른 사람들이 말했듯이 전체 날짜 시간 객체를 사용할 수 있습니다.

from datetime import datetime, date, time, timedelta
sometime = time(8,00) # 8am
later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time()

그러나 왜 완전한 날짜 시간 객체가 필요한지 설명 할 가치가 있다고 생각합니다. 오후 11시에서 2 시간을 더하면 어떻게 될지 생각해보십시오. 올바른 행동은 무엇입니까? 오후 11시 59 분보다 큰 시간을 가질 수 없기 때문에 예외가 있습니까? 다시 감쌀 까?

다른 프로그래머들은 다른 것을 기대할 것이므로, 그들이 선택한 결과는 많은 사람들을 놀라게 할 것입니다. 더 나쁜 것은 프로그래머가 처음 테스트 할 때 제대로 작동하는 코드를 작성한 다음 예상치 못한 작업을 수행하여 나중에 중단되도록하는 것입니다. 이것은 매우 나쁘기 때문에 timedelta 객체를 시간 객체에 추가 할 수 없습니다.


22

한 가지 작은 점, 몇 초 동안 기본값을 무시하기 위해 선명도를 추가 할 수 있음

>>> b = a + datetime.timedelta(seconds=3000)
>>> b
datetime.datetime(1, 1, 1, 12, 24, 59)

4
난이게 좋아. 지정된 인수로 멋지고 명확합니다.
Vigrond

12

전체 날짜 시간 사용을 제안하는 @Pax Diablo, @bvmou 및 @Arachnid에게 감사합니다. 외부 소스에서 datetime.time 객체를 수락 해야하는 경우 이것은 대체 add_secs_to_time()기능 인 것 같습니다 .

def add_secs_to_time(timeval, secs_to_add):
    dummy_date = datetime.date(1, 1, 1)
    full_datetime = datetime.datetime.combine(dummy_date, timeval)
    added_datetime = full_datetime + datetime.timedelta(seconds=secs_to_add)
    return added_datetime.time()

이 자세한 코드는이 단일 라이너로 압축 될 수 있습니다.

(datetime.datetime.combine(datetime.date(1, 1, 1), timeval) + datetime.timedelta(seconds=secs_to_add)).time()

하지만 어쨌든 코드 선명도를 위해 함수로 마무리하고 싶습니다.


감사합니다-좋은 아이디어
Anupam

9

프로젝트에 다른 파일 / 종속성을 추가 할 가치가 있다면, datetime.time산술 기능으로 확장 되는 작은 클래스를 작성했습니다 . 자정이 지나면 0이됩니다. 이제 "현재 몇시, 24 시간이 지 날까"는 일광 절약 시간, 윤초, 역사적인 시간대 변경 등을 포함하여 많은 경우가 있습니다. 그러나 때로는 간단한 경우가 필요하며 이것이 그렇게 할 것입니다.

귀하의 예는 다음과 같습니다.

>>> import datetime
>>> import nptime
>>> nptime.nptime(11, 34, 59) + datetime.timedelta(0, 3)
nptime(11, 35, 2)

nptime에서 상속 받으 datetime.time므로 해당 메소드도 사용할 수 있어야합니다.

PyPi에서 nptime( "비 보행 시간") 또는 GitHub에서 사용할 수 있습니다 : https://github.com/tgs/nptime


6

datetime어떤 단위가 사용되는지 확실하지 않기 때문에 단순히 숫자를 추가 할 수 없습니다 : 초, 시간, 주 ...

timedelta날짜와 시간을 다루는 수업 이 있습니다 . datetime마이너스 datetime제공 timedelta, datetime플러스 timedelta제공 datetime, 두 개의 datetime객체는 추가 timedelta할 수 있지만 두 개의 객체는 추가 할 수 없습니다 .

만들기 timedelta당신은 추가에 추가하는 방법을 몇 초에 개체 datetime개체를 :

>>> from datetime import datetime, timedelta
>>> t = datetime.now() + timedelta(seconds=3000)
>>> print(t)
datetime.datetime(2018, 1, 17, 21, 47, 13, 90244)

C ++에는 동일한 개념이 있습니다 std::chrono::duration.


4
항상 설명을 추가하십시오. 새로 온 사람들은 여기서 무엇을하고 있는지 알지 못할 수도 있습니다.
Gerhard Barnard

3

완벽을 기하기 위해 다음과 같이하는 방법이 있습니다 arrow(파이썬의 날짜와 시간이 더 낫습니다).

sometime = arrow.now()
abitlater = sometime.shift(seconds=3)

1

를 추가하십시오 datetime.datetimeA를 datetime.timedelta. 시간 부분 만 원하는 경우 time()결과 datetime.datetime객체 에서 메소드를 호출하여 가져올 수 있습니다.


0

오래된 질문이지만 시간대를 처리하는 함수를 던질 것이라고 생각했습니다. 주요 부분은 datetime.time객체의 tzinfo속성을 결합으로 전달한 다음 결과 더미 날짜 시간 timetz()대신에 사용하는 것입니다 time(). 이 답변은 다른 답변에서 부분적으로 영감을 얻었습니다.

def add_timedelta_to_time(t, td):
    """Add a timedelta object to a time object using a dummy datetime.

    :param t: datetime.time object.
    :param td: datetime.timedelta object.

    :returns: datetime.time object, representing the result of t + td.

    NOTE: Using a gigantic td may result in an overflow. You've been
    warned.
    """
    # Create a dummy date object.
    dummy_date = date(year=100, month=1, day=1)

    # Combine the dummy date with the given time.
    dummy_datetime = datetime.combine(date=dummy_date, time=t, tzinfo=t.tzinfo)

    # Add the timedelta to the dummy datetime.
    new_datetime = dummy_datetime + td

    # Return the resulting time, including timezone information.
    return new_datetime.timetz()

그리고 여기에 정말 간단한 테스트 케이스 클래스가 있습니다 (내장 사용 unittest).

import unittest
from datetime import datetime, timezone, timedelta, time

class AddTimedeltaToTimeTestCase(unittest.TestCase):
    """Test add_timedelta_to_time."""

    def test_wraps(self):
        t = time(hour=23, minute=59)
        td = timedelta(minutes=2)
        t_expected = time(hour=0, minute=1)
        t_actual = add_timedelta_to_time(t=t, td=td)
        self.assertEqual(t_expected, t_actual)

    def test_tz(self):
        t = time(hour=4, minute=16, tzinfo=timezone.utc)
        td = timedelta(hours=10, minutes=4)
        t_expected = time(hour=14, minute=20, tzinfo=timezone.utc)
        t_actual = add_timedelta_to_time(t=t, td=td)
        self.assertEqual(t_expected, t_actual)


if __name__ == '__main__':
    unittest.main()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.