Jaka jest różnica między „datetime.timedelta” a „dateutil.relativedelta.relativedelta”, gdy pracuje się tylko z dniami?

90

Jaka jest różnica między datetime.timedelta(ze standardowej biblioteki Pythona) a dateutil.relativedelta.relativedeltapracą tylko z dniami?

O ile rozumiem, timedeltaobsługuje tylko dni (i tygodnie), a jednocześnie relativedeltadodaje obsługę okresów określonych w latach, miesiącach, tygodniach lub dniach, a także definiuje wartości bezwzględne dla roku, miesiąca lub dnia. (pamiętaj, na potrzeby tego pytania nie muszę się martwić o godziny, minuty czy sekundy)

Biorąc pod uwagę, że pracuję tylko z datetime.dateobiektami i interesują mnie tylko okresy zdefiniowane przez liczbę dni, jaka jest różnica między timedeltai relativedelta? Czy jest jakaś różnica?

from datetime import date, timedelta
from dateutil.relativedelta import relativedelta

i = -1  # This could have been any integer, positive or negative
someday = date.today()
# Is there any difference between these two lines?
otherday = someday + timedelta(days=i)
otherday = someday + relativedelta(days=i)
Denilson Sá Maia
źródło
3
Jeśli interesują Cię tylko delty w dniach między datami, po prostu użyj biblioteki standardowej, dateime.timedeltaktóra osiągnie to, co chcesz i uniknie zależności od dateutilpakietu zewnętrznego .
Pedro Romano
Warto powiedzieć, że oprócz zapisania jednej dodatkowej zależności, obliczanie delt w dniach między datami jest wielokrotnie szybsze w przypadku timedelta niż relativedelta. (~ 10 razy)
Julien B.,

Odpowiedzi:

76

dateutiljest pakietem rozszerzającym do standardowego datetimemodułu Pythona . Jak mówisz, zapewnia dodatkową funkcjonalność, taką jak timedeltas wyrażane w jednostkach większych niż jeden dzień.

Jest to przydatne, jeśli musisz zadawać pytania, takie jak ile miesięcy mogę zaoszczędzić, zanim nadejdą urodziny mojej dziewczyny lub jaki jest ostatni piątek miesiąca? Ukrywa to złożone obliczenia, które są spowodowane różną długością miesięcy lub dodatkowymi dniami w latach przestępnych.

W Twoim przypadku interesuje Cię tylko liczba dni. Więc najlepiej użyj, timedeltaponieważ pozwala to uniknąć dodatkowej zależności od dateutilpakietu.

Hans Wtedy
źródło
32

A relativedeltama o wiele więcej parametrów niż timedelta:

Definition:   relativedelta.relativedelta(self, dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0,
seconds=0, microseconds=0, year=None, month=None, day=None,
weekday=None, yearday=None, nlyearday=None, hour=None, minute=None,
second=None, microsecond=None)

za pomocą którego możesz obliczyć ostatni piątek miesiąca:

In [14]: import datetime as dt

In [15]: import dateutil.relativedelta as relativedelta

In [16]: today = dt.date.today()

In [17]: rd = relativedelta.relativedelta(day = 31, weekday = relativedelta.FR(-1))

In [18]: today+rd
Out[18]: datetime.date(2012, 9, 28)
unutbu
źródło
1
To fantastyczna odpowiedź, która dała nowy wgląd w wykorzystanie relativedelta do takich rzeczy jak „ostatni piątek miesiąca” :) Dzięki!
PascalVKooten
10

Jedną z głównych różnic, które nie zostały podkreślone w innych odpowiedziach, jest obecność rzeczowników w liczbie pojedynczej i mnogiej dla każdego prymitywu różnicy czasowej. Podczas gdy timedeltatylko dzień mnogiej (na przykład hours, days) w celu określenia względnej różnicy czasu, relativedeltainne liczby pojedynczej rzeczowników oraz (na przykład hour, day) dla oznaczenia absolutnej godzinie.

Wynika to jasno z definicji dwóch klas:

Definition:   datetime.timedelta([days[, seconds[, microseconds[, 
milliseconds[, minutes[, hours[, weeks]]]]]]])

Definition:   relativedelta.relativedelta(self, dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0,
seconds=0, microseconds=0, year=None, month=None, day=None,
weekday=None, yearday=None, nlyearday=None, hour=None, minute=None,
second=None, microsecond=None)

Co dokładnie robi liczba pojedyncza? Forma pojedyncza tworzy deltę, która po dodaniu do datetimeobiektu ustawia określony prymityw daty / godziny w datetimeobiekcie na ten wymieniony w relativedelta. Oto mały przykład:

>>> import datetime as dt; from dateutil.relativedelta import *
>>> NOW = dt.datetime(2018, 11, 17, 9, 6, 31)
>>> NOW
datetime.datetime(2018, 11, 17, 9, 6, 31)
>>> NOW + relativedelta(hours=1) #Simply add one hour
datetime.datetime(2018, 11, 17, 10, 6, 31)
>>> NOW + relativedelta(hour=1) #Set the hour to 01:00 am
datetime.datetime(2018, 11, 17, 1, 6, 31)

Może to prowadzić do relativedeltawykorzystania w interesujących aplikacjach, których wdrożenie może być skomplikowane przy użyciu timedelta. Jeden, który szybko przychodzi na myśl, to zaokrąglanie.

Ciekawa aplikacja: szybkie zaokrąglanie

Pokażę teraz, jak relativedeltajest bardziej wyrazisty podczas zaokrąglania datetimeprzedmiotu do najbliższej minuty, godziny, dnia itp.

Zaokrąglenie do najbliższej godziny:

Zwróć uwagę, jak proste jest zaokrąglanie za pomocą relativedelta:

#Using `relativedelta`
NOW + relativedelta(hours=1, minute=0, second=0, microsecond=0)

#Using `timedelta`
dt.combine(NOW.date(),dt.time(NOW.hour,0,0)) + dt.timedelta(0,60*60,0)

Inne, bardziej skomplikowane zaokrąglenia są łatwo osiągalne przy użyciu relativedelta. Należy jednak pamiętać, że wszystkie zaokrąglenia, które można wykonać, relativedeltamożna również wykonać za pomocą datetimefunkcji i timedeltatylko w nieco bardziej zawiły sposób.

shivams
źródło