Wie kann ich eine Datumszeit um einen Tag erhöhen?


151

Wie kann ich den Tag einer Datumszeit erhöhen?

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

Aber ich muss Monate und Jahre richtig durchlaufen? Irgendwelche Ideen?

Antworten:




12

Hier ist eine andere Methode, um Tage am Datum mithilfe des relativedelta von dateutil hinzuzufügen.

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

Ausgabe:

Heute: 25/06/2015 20:41:44

Nach einem Tag: 01/06/2015 20:41:44


1
warum würdest du es anstelle timedelta()von stdlib verwenden?
JFS

2
@JFSebastian Nur um einen anderen möglichen Weg zu teilen, um Tag hinzuzufügen.
Atul Arvind

1
Wenn es keinen Vorteil gibt, denke ich nicht, dass es einen Mehrwert bringt.
Tejas Manohar

10

Alle aktuellen Antworten sind in einigen Fällen falsch, da sie nicht berücksichtigen, dass Zeitzonen ihren Versatz relativ zu UTC ändern. In einigen Fällen unterscheidet sich das Hinzufügen von 24 Stunden vom Hinzufügen eines Kalendertages.

Vorgeschlagene Lösung

Die folgende Lösung funktioniert für Samoa und hält die Ortszeit konstant.

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

Getesteter Code

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

Testergebnisse

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

Die anderen Antworten sind nicht ganz falsch, sie sind vollkommen in Ordnung, wenn Sie mit UTC oder naiven ( tzinfo == None) Datumszeiten arbeiten.
Delgan

3

Dies war eine einfache Lösung für mich:

from datetime import timedelta, datetime

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


0

Sie können timedelta auch importieren, damit der Code sauberer ist.

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

Konvertieren Sie dann in Datum in Zeichenfolge

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

Python ist ein Liner

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

-2

Eine kurze Lösung ohne Bibliotheken. :) :)

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

Stellen Sie sicher, dass " Zeichenfolge d " tatsächlich die Form hat, %m/%d/%Ydamit Sie keine Probleme beim Übergang von einem Monat zum nächsten haben.


2
Wenn Sie dann einstellen d, 8/31/18wird zurückgegeben 8/32/18. Wenn Sie das Jahr von ändern 18, bricht es einfach.
Andrewsi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.