web-dev-qa-db-fra.com

Quelle est la différence entre "datetime.timedelta" et "dateutil.relativedelta.relativedelta" lorsque vous travaillez uniquement avec des jours?

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)
65
Denilson Sá Maia

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.

62
Hans Then

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

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.

Une application intéressante: arrondir rapidement

Je vais maintenant vous montrer comment relativedelta est plus expressif lorsque vous arrondissez un objet datetime à la minute, à l'heure, au jour, etc.

Arrondir à l'heure la plus proche:

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.

5
shivams