Comment incrémenter une date / heure d'un jour?

152

Comment incrémenter le jour d'une date / heure?

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

Mais j'ai besoin de passer correctement des mois et des années? Des idées?

Pol
la source

Réponses:

60

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

import datetime

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

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

Piotr Duda
la source
12

Voici une autre méthode pour ajouter des jours à la date en utilisant 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')

Production:

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

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

Atul Arvind
la source
1
pourquoi l'utiliseriez-vous au lieu de timedelta()stdlib?
jfs
2
@JFSebastian Juste pour partager une autre possibilité possible d'ajouter un jour.
Atul Arvind
1
S'il n'y a pas d'avantage, je ne pense pas que cela ajoute de la valeur.
Tejas Manohar
10

Toutes les réponses actuelles sont fausses dans certains cas car elles ne considèrent pas que les fuseaux horaires changent de décalage par rapport à 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 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 de test

Method                   : Samoa   DST
relativedelta            :     0     0
timedelta                :     0     0
timedelta+conversion     :     1     0
timedelta+conversion+dst :     1     1
Martin Thoma
la source
Les autres réponses ne sont pas entièrement fausses, elles fonctionnent parfaitement avec des tzinfo == Nonedatetimes UTC ou naïfs ( ).
Delgan
3

C'était une solution simple pour moi:

from datetime import timedelta, datetime

today = datetime.today().strftime("%Y-%m-%d")
tomorrow = datetime.today() + timedelta(1)
Aus_10
la source
0

Vous pouvez également importer timedelta pour que le code soit plus propre.

from datetime import datetime, timedelta
date = datetime.now() + timedelta(seconds=[delta_value])

Puis convertissez en date en chaîne

date = date.strftime('%Y-%m-%d %H:%M:%S')

Python one liner est

date = (datetime.now() + timedelta(seconds=[delta_value])).strftime('%Y-%m-%d %H:%M:%S')
Roy
la source
-2

Une solution courte sans bibliothèques du tout. :)

d = "8/16/18"
day_value = d[(d.find('/')+1):d.find('/18')]
tomorrow = f"{d[0:d.find('/')]}/{int(day_value)+1}{d[d.find('/18'):len(d)]}".format()
print(tomorrow)
# 8/17/18

Assurez-vous que " string d " est en fait sous la forme de %m/%d/%Yafin que vous n'ayez pas de problèmes de transition d'un mois à l'autre.

Ace Pash
la source
2
si vous définissez dsur 8/31/18alors cela revient 8/32/18. Si vous changez l'année à partir de 18, ça casse simplement.
andrewsi le