Quelle est la différence entre datetime.timedelta
(de la bibliothèque standard de Python) et dateutil.relativedelta.relativedelta
lorsque vous travaillez uniquement avec des jours?
Pour autant que je sache, timedelta
ne prend en charge que les jours (et semaines), tandis que relativedelta
ajoute la prise en charge des périodes définies en termes d'années, mois, semaines ou jours, ainsi que la définition de valeurs absolues pour année, mois ou jour. (rappelez-vous, pour les besoins de cette question, je n'ai pas à me soucier des heures, des minutes ou des secondes)
Étant donné que je ne travaille qu'avec datetime.date
objets, et ne s'intéressant qu'aux périodes définies par le nombre de jours, quelle est la différence entre timedelta
et relativedelta
? Y a-t-il une différence?
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)
dateutil
est un package d'extension pour le module python standard datetime
. Comme vous le dites, il fournit des fonctionnalités supplémentaires, telles que des timedeltas exprimés en unités supérieures à un jour.
Ceci est utile si vous devez poser des questions telles que combien de mois puis-je économiser avant l'anniversaire de ma petite amie, ou quel est le dernier vendredi du mois? Cela masque les calculs complexes qui sont causés par les différentes durées des mois ou les jours supplémentaires des années bissextiles.
Dans votre cas, vous n'êtes intéressé que par le nombre de jours. Il vaut donc mieux utiliser timedelta
car cela évite une dépendance supplémentaire sur le package dateutil
.
Un relativedelta
a beaucoup plus de paramètres qu'un 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)
avec lequel vous pouvez faire des choses comme calculer le dernier vendredi d'un mois:
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)
Une différence majeure non mise en évidence dans d'autres réponses est la présence de noms singuliers et pluriels pour chaque primitive de différence de temps. Alors que timedelta
ne propose que des noms pluriels (par exemple hours
, days
) pour dénoter la différence de temps relative, relativedelta
propose également des noms singuliers (par exemple hour
, day
) pour indiquer des informations temporelles absolues.
Cela ressort clairement de la définition des 2 classes:
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)
Maintenant, que fait exactement la forme singulière? La forme singulière crée un delta qui, lorsqu'il est ajouté à un objet datetime
, définit cette primitive de date/heure spécifique dans l'objet datetime
à celle mentionnée dans le relativedelta
. Voici un petit exemple:
>>> 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)
Cela peut conduire à l'utilisation de relativedelta
pour certaines applications intéressantes, qui peuvent être compliquées à implémenter à l'aide de timedelta
. Un qui me vient rapidement à l'esprit est l'arrondi.
Je vais maintenant vous montrer comment relativedelta
est plus expressif lorsque vous arrondissez un objet datetime
à la minute, à l'heure, au jour, etc.
Remarquez à quel point il est simple d'arrondir en utilisant 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)
D'autres arrondis plus compliqués sont facilement réalisables en utilisant relativedelta
. Cependant, notez que tous les arrondis qui peuvent être effectués par relativedelta
peuvent également être effectués en utilisant les fonctions datetime
et timedelta
, uniquement de manière légèrement plus compliquée.