240 votes

Comment incrémenter une date d'un jour ?

Comment incrémenter le jour d'une date ?

for i in range(1, 35)
    date = datetime.datetime(2003, 8, i)
    print(date)

Mais je dois passer les mois et les années correctement ? Avez-vous des idées ?

378voto

unutbu Points 222216
date = datetime.datetime(2003,8,1,12,4,5)
for i in range(5): 
    date += datetime.timedelta(days=1)
    print(date)

11 votes

Si vous devez tenir compte de l'heure d'été, c'est plus complexe, voir par exemple Comment soustraire un jour d'une date en python ?

85voto

Piotr Duda Points 923

L'incrémentation des dates peut être réalisée à l'aide d'objets timedelta :

import datetime

datetime.datetime.now() + datetime.timedelta(days=1)

Consultez les objets timedelta dans la documentation Python : http://docs.python.org/library/datetime.html

15voto

moose Points 4945

Toutes les réponses actuelles sont fausses dans certains cas, car elles ne tiennent pas compte du fait que les fuseaux horaires modifient leur décalage par rapport à l'UTC. Ainsi, dans certains cas, l'ajout de 24h est différent de l'ajout d'un jour calendaire.

Solution proposée

La solution suivante fonctionne pour les Samoa et maintient l'heure locale constante.

def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz

Code testé

# core modules
import datetime

# 3rd party modules
import pytz

# add_day methods
def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz

def add_day_datetime_timedelta_conversion(today):
    # Correct for Samoa, but dst shift
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    return tomorrow_utc_tz

def add_day_dateutil_relativedelta(today):
    # WRONG!
    from dateutil.relativedelta import relativedelta
    return today + relativedelta(days=1)

def add_day_datetime_timedelta(today):
    # WRONG!
    return today + datetime.timedelta(days=1)

# Test cases
def test_samoa(add_day):
    """
    Test if add_day properly increases the calendar day for Samoa.

    Due to economic considerations, Samoa went from 2011-12-30 10:00-11:00
    to 2011-12-30 10:00+13:00. Hence the country skipped 2011-12-30 in its
    local time.

    See https://stackoverflow.com/q/52084423/562769

    A common wrong result here is 2011-12-30T23:59:00-10:00. This date never
    happened in Samoa.
    """
    tz = pytz.timezone('Pacific/Apia')
    today_utc = datetime.datetime(2011, 12, 30, 9, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2011-12-29T23:59:00-10:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2011-12-31T23:59:00+14:00'

def test_dst(add_day):
    """Test if add_day properly increases the calendar day if DST happens."""
    tz = pytz.timezone('Europe/Berlin')
    today_utc = datetime.datetime(2018, 3, 25, 0, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2018-03-25T01:59:00+01:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2018-03-26T01:59:00+02:00'

to_test = [(add_day_dateutil_relativedelta, 'relativedelta'),
           (add_day_datetime_timedelta, 'timedelta'),
           (add_day_datetime_timedelta_conversion, 'timedelta+conversion'),
           (add_day, 'timedelta+conversion+dst')]
print('{:<25}: {:>5} {:>5}'.format('Method', 'Samoa', 'DST'))
for method, name in to_test:
    print('{:<25}: {:>5} {:>5}'
          .format(name,
                  test_samoa(method),
                  test_dst(method)))

Résultats des tests

Method                   : Samoa   DST
relativedelta            :     0     0
timedelta                :     0     0
timedelta+conversion     :     1     0
timedelta+conversion+dst :     1     1

4 votes

Les autres réponses ne sont pas entièrement fausses, elles sont parfaitement adaptées pour travailler avec UTC ou naïf ( tzinfo == None ) des dates.

14voto

Atul Arvind Points 4264

Voici une autre méthode pour ajouter des jours à une date en utilisant le relativedelta de dateutil.

from datetime import datetime
from dateutil.relativedelta import relativedelta

print 'Today: ',datetime.now().strftime('%d/%m/%Y %H:%M:%S') 
date_after_month = datetime.now()+ relativedelta(day=1)
print 'After a Days:', date_after_month.strftime('%d/%m/%Y %H:%M:%S')

Sortie :

Aujourd'hui : 25/06/2015 20:41:44

Après un jour : 01/06/2015 20:41:44

1 votes

Pourquoi l'utiliser au lieu de timedelta() de stdlib ?

2 votes

@J.F.Sebastian Juste pour partager une autre façon possible d'ajouter un jour.

3 votes

S'il n'y a pas d'avantage, je ne pense pas que cela apporte une valeur ajoutée.

10voto

Kiran Patil Points 11

La solution la plus simple

from datetime import timedelta, datetime
date = datetime(2003,8,1,12,4,5)
for i in range(5):
    date += timedelta(days=1)
    print(date)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X