Qual è la differenza tra "datetime.timedelta" e "dateutil.relativedelta.relativedelta" quando si lavora solo con i giorni?


90

Qual è la differenza tra datetime.timedelta(dalla libreria standard di Python) e dateutil.relativedelta.relativedeltaquando si lavora solo con i giorni?

Per quanto ho capito, timedeltasupporta solo giorni (e settimane), mentre relativedeltaaggiunge supporto per periodi definiti in termini di anni, mesi, settimane o giorni, oltre a definire valori assoluti per anno, mese o giorno. (ricorda, ai fini di questa domanda, non devo preoccuparmi di ore, minuti o secondi)

Considerando che lavoro solo con datetime.dateoggetti e sono interessato solo a periodi definiti dal numero di giorni, qual è la differenza tra timedeltae relativedelta? C'è qualche differenza?

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)

3
Se sei interessato solo ai delta nei giorni tra le date, usa semplicemente la libreria standard dateime.timedeltache otterrà ciò che desideri ed eviterà la dipendenza dal dateutilpacchetto esterno .
Pedro Romano

Vale la pena dire che oltre a salvare una dipendenza in più, calcolare i delta in giorni tra le date è più volte più veloce con timedelta rispetto a relativedelta. (~ 10 volte)
Julien B.

Risposte:


76

dateutilè un pacchetto di estensione per il datetimemodulo standard di python . Come dici tu, fornisce funzionalità extra, come le timedeltas espresse in unità più grandi di un giorno.

Questo è utile se devi porre domande come quanti mesi posso risparmiare prima che arrivi il compleanno della mia ragazza o qual è l'ultimo venerdì del mese? Ciò nasconde calcoli complessi causati dalla diversa durata dei mesi o dai giorni extra negli anni bisestili.

Nel tuo caso, ti interessa solo il numero di giorni. Quindi è meglio usarlo in timedeltaquanto ciò evita una dipendenza extra dal dateutilpacchetto.


32

A relativedeltaha molti più parametri di a 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)

con cui puoi fare cose come calcolare l'ultimo venerdì in un mese:

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)

1
Questa è una risposta fantastica che ha dato una nuova visione dell'uso di una relativedelta per cose come "ultimo venerdì del mese" :) Grazie!
PascalVKooten

10

Una delle principali differenze non evidenziate in altre risposte è la presenza di sostantivi singolari e plurali per ogni primitiva di differenza di tempo. Mentre timedeltasolo le offerte plurale nomi (ad esempio hours, days) per denotare relativa differenza di tempo, relativedeltaofferte sostantivi singolari pure (ad esempio hour, day) per indicare informazioni di tempo assoluto.

Questo risulta chiaro dalla definizione delle 2 classi:

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)

Ora, cosa fa esattamente la forma singolare? La forma singolare crea un delta che, quando aggiunto a un datetimeoggetto, imposta quella primitiva data / ora specifica datetimenell'oggetto a quella menzionata nel file relativedelta. Ecco un piccolo esempio:

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

Questo può portare ad relativedeltaessere utilizzato per alcune applicazioni interessanti, che possono essere complicate da implementare utilizzando timedelta. Uno che viene subito in mente è l'arrotondamento.

Un'applicazione interessante: arrotondamento rapido

Ora ti mostrerò come relativedeltaè più espressivo quando si arrotonda un datetimeoggetto al minuto, all'ora, al giorno più vicini, ecc.

Arrotondare all'ora più vicina:

Nota quanto è semplice arrotondare usando 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)

Altri arrotondamenti più complicati sono facilmente realizzabili utilizzando relativedelta. Tuttavia, si noti che tutti gli arrotondamenti che possono essere eseguiti relativedeltapossono essere eseguiti anche utilizzando le datetimefunzioni e timedelta, solo in un modo leggermente più complesso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.