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?

Réponses:




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


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

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)

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

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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.