Jaki jest standardowy sposób dodawania N sekund do datetime.czas w Pythonie?

Biorąc pod uwagę wartość datetime.time w Pythonie, czy istnieje standardowy sposób dodawania do niego liczby całkowitej sekund, tak aby 11:34:59 + 3 = 11:35:02, na przykład?

Te oczywiste idee nie działają:

>>> 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'

W końcu napisałem takie funkcje:

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)
Nie mogę przestać myśleć, że brakuje mi łatwiejszego sposobu, aby to zrobić.

Powiązane

Author: Community, 2008-09-19

8 answers

Możesz użyć pełnych zmiennych datetime z timedelta, i podając fałszywą datę, a następnie używając time, aby uzyskać wartość czasu.

Na przykład:

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

Daje dwie wartości w odstępie trzech sekund:

11:34:59
11:35:02

Można również zdecydować się na bardziej czytelne

b = a + datetime.timedelta(seconds=3)
Jeśli jesteś taka skłonna.

Jeśli szukasz funkcji, która może to zrobić, możesz spojrzeć na użycie addSecs poniżej:

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

To wyjście:

 09:11:55.775695
 09:16:55
 386
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 01:19:11

Jak stwierdzili inni tutaj, możesz po prostu używać pełnych obiektów datetime przez cały czas:

sometime = get_some_time() # the time to which you want to add 3 seconds
later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time()

Myślę jednak, że warto wyjaśnić, dlaczego wymagane są pełne obiekty datetime. Zastanów się, co by się stało, gdybym dodał 2 godziny do 23: 00. Jakie jest prawidłowe zachowanie? Wyjątek, bo nie możesz mieć czasu większego niż 23:59? Powinno się zawinąć?

Różni programiści będą oczekiwać różnych rzeczy, więc niezależnie od wybranego wyniku zaskoczy wielu ludzi. Gorzej jednak programiści pisali kod, który działał dobrze, gdy początkowo testowali go, a następnie łamali go później, robiąc coś nieoczekiwanego. Jest to bardzo złe, dlatego nie możesz dodawać obiektów timedelta do obiektów time.

 43
Author: Eli Courtwright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 13:47:29

Jedna mała rzecz, może dodać jasność, aby zastąpić domyślną wartość na sekundy

>>> b = a + datetime.timedelta(seconds=3000)
>>> b
datetime.datetime(1, 1, 1, 12, 24, 59)
 16
Author: unmounted,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 08:08:10

Podziękowania dla @ Pax Diablo, @bvmou i @Arachnid za sugestię wykorzystania pełnych datetimes przez cały czas. Jeśli muszę zaakceptować datetime.obiekty czasu z zewnętrznego źródła, wtedy wydaje się to być alternatywną funkcją 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()

Ten kod można skompresować do tego jednowierszowego:

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

Ale myślę, że i tak chciałbym zawinąć to w funkcję dla jasności kodu.

 9
Author: Paul Stephenson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 09:40:06

Jeśli warto dodać kolejny plik / zależność do swojego projektu, właśnie napisałem małą klasę, która rozszerza datetime.time z możliwością arytmetyki. Kiedy mijasz północ, to kończy się w okolicach zera. Teraz "Która godzina, za 24 godziny" ma wiele przypadków narożnych, w tym czas letni, sekundy przestępne, historyczne zmiany strefy czasowej i tak dalej. Ale czasami naprawdę potrzebujesz prostej sprawy i tak to zrobi.

Twoim przykładem będzie napisane:

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

nptime inherits from datetime.time, więc każda z tych metod powinna być użyteczna.

Jest dostępny w PyPi jako nptime ("non-pedantic time"), lub na Githubie: https://github.com/tgs/nptime
 6
Author: rescdsk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-04 19:31:30

Nie można po prostu dodać liczby do datetime, ponieważ nie jest jasne, jaka jednostka jest używana: Sekundy, Godziny, tygodnie...

Istnieje klasa timedelta do manipulacji z datą i czasem. datetime minus datetime daje timedelta, datetime DODATKOWO timedelta daje datetime, Dwa datetime obiekty nie mogą być dodane, chociaż dwa timedelta mogą.

Utwórz timedelta obiekt o ile sekund chcesz dodać i dodaj go do datetime obiektu:

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

W C++ jest to samo pojęcie: std::chrono::duration.

 4
Author: user2387567,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-18 12:49:26

Spróbuj dodać datetime.datetime do datetime.timedelta. Jeśli chcesz tylko porcję czasu, możesz wywołać metodę time() na wynikowym obiekcie datetime.datetime, aby ją uzyskać.

 1
Author: Nick Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-15 14:53:17

Ze względu na zakończenie, oto sposób, aby to zrobić z arrow (lepsze daty i godziny dla Pythona):

sometime = arrow.now()
abitlater = sometime.shift(seconds=3)
 1
Author: Bart Van Loon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-09 19:41:17