Wie berechne ich das Datum sechs Monate nach dem aktuellen Datum mit dem Python-Modul datetime?


391

Ich verwende das datetime Python-Modul. Ich möchte das Datum 6 Monate nach dem aktuellen Datum berechnen. Könnte mir jemand dabei helfen?

Der Grund, warum ich ein Datum 6 Monate nach dem aktuellen Datum generieren möchte, ist das Erstellen eines Überprüfungsdatums . Wenn der Benutzer Daten in das System eingibt, hat er ein Überprüfungsdatum von 6 Monaten ab dem Datum, an dem er die Daten eingegeben hat.


2
Sie müssen genauer sein: Wann ist sechs Monate ab dem 31. März? Und ab dem 30. August?
kmkaplan

3
Ja, die Bearbeitung hilft: Sie können ungefähr 6 Monate bis 183 Tage ohne negative Auswirkungen verbringen. Das Hinzufügen von 183 Tagen zum heutigen Tag reicht also aus.
kmkaplan

15
Die obigen Kommentare kommen mir albern vor. Das Konzept des "Hinzufügens von sechs Monaten" ist ziemlich klar: Nehmen Sie die Monatskomponente und fügen Sie 6sie hinzu, mit Unterstützung für das Überlaufen des Jahres (und das Zurückfahren des Monats zurück 1), wenn wir über den Dezember hinausgehen. Dies ist genau das relativedelta, was jede Programmiersprache mit Unterstützung für diese Art von Konzept tut und tatsächlich tut.
Kirk Woll

5
@ KirkWoll: Ich bin sicher, es ist ganz klar. Aber immer noch anders für jeden, der spricht. Python: date(2015, 3, 31) + relativedelta(months = 6)gibt datetime.date(2015, 9, 30). Perl: DateTime->new(year=>2000, month=>3, day=>31)->add(months=>6)gibt 2000-10-01T00:00:00. Php: date_create('2000-03-31', new DateTimeZone('UTC'))->add(new DateInterval('P6M'))gibt 2000-10-01. Wähle dein Gift.
kmkaplan

2
... das Hinzufügen von 182 erscheint pragmatischer, um ein Überprüfungsdatum zu generieren : Der Wochentag bleibt erhalten.
Wolf

Antworten:


1047

Ich fand diese Lösung gut. (Dies verwendet die Python-Dateutil-Erweiterung )

from datetime import date
from dateutil.relativedelta import relativedelta

six_months = date.today() + relativedelta(months=+6)

Der Vorteil dieses Ansatzes besteht darin, dass Probleme mit 28, 30, 31 Tagen usw. behoben werden. Dies ist sehr nützlich bei der Behandlung von Geschäftsregeln und -szenarien (z. B. Rechnungserstellung usw.).

$ date(2010,12,31)+relativedelta(months=+1)
  datetime.date(2011, 1, 31)

$ date(2010,12,31)+relativedelta(months=+2)
  datetime.date(2011, 2, 28)

2
Die +6 ist ein Indikator dafür, dass es -6 sein könnte, dasselbe gilt auch für Tage und Jahre :)
Securecurve

5
@sliders_alpha Sie müssen das Python-Dateutil-Paket installieren (Pip Install Python-Dateutil)
Poiuytrez

18
Dies ist die richtige Lösung. Wenn das OP 6 Jahre statt 6 Monate gefragt hätte, wäre die genehmigte Antwort kläglich gescheitert. Man sollte also bedenken, dass die Antworten umso wertvoller sind, je allgemeiner sie sind.
Daniel F

3
Bitte beachten Sie, dass die relativedeltaFunktion auch monthals Argument verwendet wird, das im Grunde den Monat im übergebenen Datum ersetzt / setzt / korrigiert, was sich stark vom Hinzufügen weiterer Monate unterscheidet. Nur eine Warnung für Leute, die sich fragen, ob die Funktion unterbrochen ist, weil sie die zusätzlichen s in Monaten vergessen haben .
Shad0w_wa1k3r

1
Ich bin neugierig: Weiß jemand, warum dies nicht standardmäßig enthalten ist? Timedelta scheint datetimestandardmäßig mit verpackt zu sein . Ich nahm tatsächlich an, dass ich "Monate" in das Zeitdelta übergehen könnte.
dTanMan

51

Nun, das hängt davon ab, was Sie mit 6 Monaten ab dem aktuellen Datum meinen.

  1. Mit natürlichen Monaten:

    (day, month, year) = (day, (month + 5) % 12 + 1, year + (month + 5)/12)
  2. Nach der Definition eines Bankiers 6 * 30:

    date += datetime.timedelta(6 * 30)

3
Könnten Sie auch die Halbjahresdefinition (183 Tage) plus die 26-Wochen-Definition einfügen? Es hilft, sie alle an einem Ort zu haben.
S.Lott

11
nur eine kurze Bemerkung: Ich denke, für Monat wäre die Formel stattdessen (Monat + 5)% 12 + 1 b / c für Juni, Ihre Formel gibt 0, während das erwartete Ergebnis 12 ist ... trotz dieses kleinen Fehlers zu Meiner Meinung nach ist Ihre Antwort diejenige, die die Frage am besten beantwortet
PierrOz

3
und das gleiche für Jahr: Es sollte Jahr + (Monat + 5) / 12 sein
PierrOz

7
Was ist, wenn das Datum 31 ist und der Monat sechs Monate später keine 31 Tage haben kann (was für die meisten Monate mit 31 Tagen der Fall ist)?
Akv

4
Downvote, weil die erste Lösung fehlerhaft sein (day, month, year) = (day, (month+6)%12, year+(month+6)/12)kann, da sie ungültige Daten wie (31, 8, 2015)->(31, 2, 2016)
ohw

37

Mit Python 3.x können Sie dies folgendermaßen tun:

from datetime import datetime, timedelta
from dateutil.relativedelta import *

date = datetime.now()
print(date)
# 2018-09-24 13:24:04.007620

date = date + relativedelta(months=+6)
print(date)
# 2019-03-24 13:24:04.007620

Sie müssen jedoch das Python-Dateutil- Modul installieren :

pip install python-dateutil

Upvoted forpip install ...
Nathan

Ich würde empfehlen from dateutil.relativedelta import relativedelta. Die Verwendung import *ist nicht explizit.
Sam Morgan

19

Für die Berechnung von Monat zu Monat:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)

18
Dies ist nicht die oben in den Kommentaren erwähnte relativedelta-Lösung. Scrollen Sie weiter mit 600+ Upvotes nach der Lösung.
Nostalg.io

15

Was meinst du mit "6 Monate"?

Ist 2009-02-13 + 6 Monate == 2009-08-13? Oder ist es 2009-02-13 + 6 * 30 Tage?

import mx.DateTime as dt

#6 Months
dt.now()+dt.RelativeDateTime(months=6)
#result is '2009-08-13 16:28:00.84'

#6*30 days
dt.now()+dt.RelativeDateTime(days=30*6)
#result is '2009-08-12 16:30:03.35'

Weitere Infos zu mx.DateTime


14

Hier ist ein Beispiel für das, dateutil.relativedeltawas ich nützlich fand, um das vergangene Jahr zu durchlaufen und jedes Mal einen Monat bis zum aktuellen Datum zu überspringen:

>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.datetime.today()
>>> month_count = 0
>>> while month_count < 12:
...  day = today - relativedelta(months=month_count)
...  print day
...  month_count += 1
... 
2010-07-07 10:51:45.187968
2010-06-07 10:51:45.187968
2010-05-07 10:51:45.187968
2010-04-07 10:51:45.187968
2010-03-07 10:51:45.187968
2010-02-07 10:51:45.187968
2010-01-07 10:51:45.187968
2009-12-07 10:51:45.187968
2009-11-07 10:51:45.187968
2009-10-07 10:51:45.187968
2009-09-07 10:51:45.187968
2009-08-07 10:51:45.187968

Wie bei den anderen Antworten müssen Sie herausfinden, was Sie unter "in 6 Monaten" verstehen. Wenn Sie "den heutigen Tag des Monats im Monat sechs Jahre in der Zukunft" meinen, dann würde dies Folgendes bewirken:

datetime.datetime.now() + relativedelta(months=6)

14

Diese Lösung funktioniert im Dezember ordnungsgemäß, was bei den meisten Antworten auf dieser Seite nicht der Fall ist. Sie müssen zuerst die Monate von Basis 1 (dh Jan = 1) auf Basis 0 (dh Jan = 0) verschieben, bevor Sie den Modul (%) oder die Ganzzahldivision (//) verwenden. Andernfalls erhalten Sie November (11) plus 1 Monat 12 , was beim Finden des Restes (12% 12) 0 ergibt.

(Und schlagen Sie nicht "(Monat% 12) + 1" oder Okt + 1 = Dezember vor!)

def AddMonths(d,x):
    newmonth = ((( d.month - 1) + x ) % 12 ) + 1
    newyear  = int(d.year + ((( d.month - 1) + x ) / 12 ))
    return datetime.date( newyear, newmonth, d.day)

Jedoch ... Dies erklärt kein Problem wie den 31. Januar + einen Monat. Also kehren wir zum OP zurück - was meinst du mit einem Monat? Eine Lösung besteht darin, einen Rückzieher zu machen, bis Sie zu einem gültigen Tag gelangen, da die meisten Leute davon ausgehen würden, dass der letzte Tag im Januar plus ein Monat dem letzten Tag im Februar entspricht. Dies funktioniert auch bei negativen Monaten. Beweis:

>>> import datetime
>>> AddMonths(datetime.datetime(2010,8,25),1)
datetime.date(2010, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),4)
datetime.date(2010, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),5)
datetime.date(2011, 1, 25)
>>> AddMonths(datetime.datetime(2010,8,25),13)
datetime.date(2011, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),24)
datetime.date(2012, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-1)
datetime.date(2010, 7, 25)
>>> AddMonths(datetime.datetime(2010,8,25),0)
datetime.date(2010, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-12)
datetime.date(2009, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-8)
datetime.date(2009, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-7)
datetime.date(2010, 1, 25)>>> 

3
Behebt das Problem "31. Januar + ein Monat": days_in_month = calendar.monthrange (newyear, newmonth) [1]; newday = min (d.day, days_in_month); (Stößt den Tag ab, wenn er zu groß ist, z. B. 31. Februar bis 28./29. Februar)
Curtis Yallop

Dies funktionierte für mich nur durch Konvertieren des neuen Jahres in einen ganzzahligen Datentyp def AddMonths (d, x): newmonth = (((d.month - 1) + x)% 12) + 1 newyear = d.year + int (( (d.month - 1) + x) / 12) return datetime.date (newyear, newmonth, d.day)
Manmeet Singh

12

Ich weiß, dass dies für 6 Monate war, aber die Antwort zeigt in Google für "Hinzufügen von Monaten in Python", wenn Sie einen Monat hinzufügen:

import calendar

date = datetime.date.today()    //Or your date

datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])

Dies würde die Tage im aktuellen Monat zählen und sie zum aktuellen Datum hinzufügen. Wenn Sie 365/12 verwenden, kann ein 1/12 eines Jahres Probleme für kurze / lange Monate verursachen, wenn Sie über das Datum iterieren.


11

Es gibt keine direkte Möglichkeit, dies mit Pythons Datum / Uhrzeit zu tun.

Überprüfen Sie den relativedelta-Typ bei python-dateutil . Hier können Sie ein Zeitdelta in Monaten angeben.


10

Verwenden Sie einfach die Timetuple- Methode, um die Monate zu extrahieren, Ihre Monate hinzuzufügen und ein neues Datumsobjekt zu erstellen. Wenn es dafür bereits eine Methode gibt, weiß ich es nicht.

import datetime

def in_the_future(months=1):
    year, month, day = datetime.date.today().timetuple()[:3]
    new_month = month + months
    return datetime.date(year + (new_month / 12), (new_month % 12) or 12, day)

Die API ist etwas ungeschickt, dient aber als Beispiel. Funktioniert natürlich auch nicht bei Eckfällen wie dem 31.01.2008 + 1 Monat. :) :)


3
Fehler in Ihrem Code: new_month % 12sollte sein (new_month % 12) or 12. Andernfalls wird eine Fehlermeldung angezeigt, wenn Sie dies im November versuchen. :)
Jordan Reiter

Dies ist tatsächlich viel sauberer als die akzeptierte Lösung. Dies erfordert keinen neuen Import, nur grundlegende Mathematik
Simon PA

Rückgabe datetime.date (Jahr + (neuer_Monat / / 12), (neuer_Monat% 12) oder 12, Tag)
paytam

9

Das Dateutil-Paket implementiert solche Funktionen. Aber sei dir bewusst, dass dies naiv sein wird , wie andere bereits betonten.


Dateutil ist großartig. Es kann auch mit easy_install installiert werden.
Soviut

Ausgezeichnet. Vielen Dank für den Vorschlag. Das scheint von Gott gesandt zu sein.
Ayaz

9

Verwenden von Python-Standardbibliotheken, dh ohne dateutiloder mit anderen, und Lösen des Problems vom 31. Februar:

import datetime
import calendar

def add_months(date, months):
    months_count = date.month + months

    # Calculate the year
    year = date.year + int(months_count / 12)

    # Calculate the month
    month = (months_count % 12)
    if month == 0:
        month = 12

    # Calculate the day
    day = date.day
    last_day_of_month = calendar.monthrange(year, month)[1]
    if day > last_day_of_month:
        day = last_day_of_month

    new_date = datetime.date(year, month, day)
    return new_date

Testen:

>>>date = datetime.date(2018, 11, 30)

>>>print(date, add_months(date, 3))
(datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))

>>>print(date, add_months(date, 14))
(datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))

Dies hat einen Fehler: Wenn der Zielmonat Dezember ist, wird ein Jahr ein Datum später als erforderlich zurückgegeben. Beispiel: add_months(datetime.date(2018, 11, 30), 1)Rendite datetime.date(2019, 12, 30)(das Jahr sollte 2018 sein, nicht 2019). Verwenden Sie dafür besser eine dedizierte, gut getestete Bibliothek! Wenn Sie wirklich nur Standardbibliotheksmodule verwenden müssen, lesen Sie meine Antwort auf eine ähnliche Frage .
Taleinat

5

Ich habe einen besseren Weg, um das Problem vom 31. Februar zu lösen:

def add_months(start_date, months):
    import calendar

    year = start_date.year + (months / 12)
    month = start_date.month + (months % 12)
    day = start_date.day

    if month > 12:
        month = month % 12
        year = year + 1

    days_next = calendar.monthrange(year, month)[1]
    if day > days_next:
        day = days_next

    return start_date.replace(year, month, day)

Ich denke, dass es auch mit negativen Zahlen funktioniert (um Monate zu subtrahieren), aber ich habe dies nicht sehr oft getestet.


1
Diese Antwort hat den Vorteil, dass das Problem nur mit integrierten Python-Bibliotheken korrekt gelöst werden kann. Unter stackoverflow.com/a/4131114/302264 finden Sie eine äquivalente, aber etwas präzisere Antwort.
Eduardo Dobay

3

Die QDate-Klasse von PyQt4 verfügt über eine Addmonths-Funktion.

>>>from PyQt4.QtCore import QDate  
>>>dt = QDate(2009,12,31)  
>>>required = dt.addMonths(6) 

>>>required
PyQt4.QtCore.QDate(2010, 6, 30)

>>>required.toPyDate()
datetime.date(2010, 6, 30)

3

Wie wäre es damit? Keine andere Bibliothek benutzen ( dateutil) oder timedelta? aufbauend auf der Antwort vartec habe ich dies getan und ich glaube, es funktioniert:

import datetime

today = datetime.date.today()
six_months_from_today = datetime.date(today.year + (today.month + 6)/12, (today.month + 6) % 12, today.day)

Ich habe es versucht timedelta, aber weil es die Tage zählt,365/2 oder 6*356/12nicht immer 6 Monate bedeutet, sondern 182 Tage. z.B

day = datetime.date(2015, 3, 10)
print day
>>> 2015-03-10

print (day + datetime.timedelta(6*365/12))
>>> 2015-09-08

Ich glaube, dass wir normalerweise davon ausgehen, dass 6 Monate ab einem bestimmten Tag am selben Tag des Monats landen, aber 6 Monate später (dh 2015-03-10 -> 2015-09-10, nicht 2015-09-08).

Ich hoffe, Sie finden das hilfreich.


1
day + datetime.timedelta(6*365/12)wird nicht immer funktionieren, da einige Jahre 365 Tage und andere 366 Tage haben.
3kstc

3

Dies beantwortet nicht die spezifische Frage ( datetimenur mit), aber da andere die Verwendung verschiedener Module vorgeschlagen haben, gibt es hier eine Lösung mit pandas.

import datetime as dt
import pandas as pd

date = dt.date.today() - \
       pd.offsets.DateOffset(months=6)

print(date)

2019-05-04 00:00:00

Was in Schaltjahren wie erwartet funktioniert

date = dt.datetime(2019,8,29) - \
       pd.offsets.DateOffset(months=6)
print(date)

2019-02-28 00:00:00

2

AddMonths () wurde für die Verwendung in Zope und die Behandlung ungültiger Tagesnummern geändert:

def AddMonths(d,x):
    days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    newmonth = ((( d.month() - 1) + x ) % 12 ) + 1
    newyear  = d.year() + ((( d.month() - 1) + x ) // 12 ) 
    if d.day() > days_of_month[newmonth-1]:
      newday = days_of_month[newmonth-1]
    else:
      newday = d.day() 
    return DateTime( newyear, newmonth, newday)

Dies scheint keine Schaltjahre (29 Tage im Februar) zu berücksichtigen.
behandeln

2
import time

def add_month(start_time, months):  

        ret = time.strptime(start_time, '%Y-%m-%d')
        t = list(ret)

        t[1] += months

        if t[1] > 12:
            t[0] += 1 + int(months / 12)

            t[1] %= 12

        return int(time.mktime(tuple(t)))

1
import datetime


'''
Created on 2011-03-09

@author: tonydiep
'''

def add_business_months(start_date, months_to_add):
    """
    Add months in the way business people think of months. 
    Jan 31, 2011 + 1 month = Feb 28, 2011 to business people
    Method: Add the number of months, roll back the date until it becomes a valid date
    """
    # determine year
    years_change = months_to_add / 12

    # determine if there is carryover from adding months
    if (start_date.month + (months_to_add % 12) > 12 ):
        years_change = years_change + 1

    new_year = start_date.year + years_change

    # determine month
    work = months_to_add % 12
    if 0 == work:
        new_month = start_date.month
    else:
        new_month = (start_date.month + (work % 12)) % 12

    if 0 == new_month:
        new_month = 12 

    # determine day of the month
    new_day = start_date.day
    if(new_day in [31, 30, 29, 28]):
        #user means end of the month
        new_day = 31


    new_date = None
    while (None == new_date and 27 < new_day):
        try:
            new_date = start_date.replace(year=new_year, month=new_month, day=new_day)
        except:
            new_day = new_day - 1   #wind down until we get to a valid date

    return new_date


if __name__ == '__main__':
    #tests
    dates = [datetime.date(2011, 1, 31),
             datetime.date(2011, 2, 28),
             datetime.date(2011, 3, 28),
             datetime.date(2011, 4, 28),
             datetime.date(2011, 5, 28),
             datetime.date(2011, 6, 28),
             datetime.date(2011, 7, 28),
             datetime.date(2011, 8, 28),
             datetime.date(2011, 9, 28),
             datetime.date(2011, 10, 28),
             datetime.date(2011, 11, 28),
             datetime.date(2011, 12, 28),
             ]
    months = range(1, 24)
    for start_date in dates:
        for m in months:
            end_date = add_business_months(start_date, m)
            print("%s\t%s\t%s" %(start_date, end_date, m))

1

Die Antwort von Johannes Wei im Fall 1new_month = 121 geändert. Dies funktioniert perfekt für mich. Die Monate können positiv oder negativ sein.

def addMonth(d,months=1):
    year, month, day = d.timetuple()[:3]
    new_month = month + months
    return datetime.date(year + ((new_month-1) / 12), (new_month-1) % 12 +1, day)

2
Es "funktioniert nicht perfekt", wenn der Tag im Startdatum größer ist als die Anzahl der Tage im Zielmonat. Beispiel: 2001-01-31 plus ein Monat versucht, ein Datum 2001-02-31 zu erstellen.
John Machin

1

Noch eine andere Lösung - hoffe, es wird jemandem gefallen:

def add_months(d, months):
    return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12)

Diese Lösung funktioniert an den Tagen 29, 30, 31 nicht in allen Fällen, daher wird eine robustere Lösung benötigt (was nicht mehr so ​​schön ist :)):

def add_months(d, months):
    for i in range(4):
        day = d.day - i
        try:
            return d.replace(day=day).replace(year=d.year+int(months)//12).replace(month=(d.month+int(months))%12)
        except:
            pass
    raise Exception("should not happen")

1

Aus dieser Antwort siehe parsedatetime . Es folgt ein Codebeispiel. Weitere Details: Komponententest mit vielen Konvertierungsbeispielen in natürlicher Sprache -> JJJJ-MM-TT und offensichtlichen Herausforderungen / Fehlern bei der Konvertierung zur Zeit .

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, calendar
from datetime import date

# from https://github.com/bear/parsedatetime
import parsedatetime as pdt

def print_todays_date():
    todays_day_of_week = calendar.day_name[date.today().weekday()]
    print "today's date = " + todays_day_of_week + ', ' + \
                              time.strftime('%Y-%m-%d')

def convert_date(natural_language_date):
    cal = pdt.Calendar()
    (struct_time_date, success) = cal.parse(natural_language_date)
    if success:
        formal_date = time.strftime('%Y-%m-%d', struct_time_date)
    else:
        formal_date = '(conversion failed)'
    print '{0:12s} -> {1:10s}'.format(natural_language_date, formal_date)

print_todays_date()
convert_date('6 months')

Der obige Code generiert Folgendes von einem MacOSX-Computer:

$ ./parsedatetime_simple.py 
today's date = Wednesday, 2015-05-13
6 months     -> 2015-11-13
$ 

1

In diesem Beispiel kann der Benutzer entscheiden, wie ein Datum zurückgegeben werden soll, bei dem der Tag größer ist als die Anzahl der Tage im Monat.

def add_months(date, months, endOfMonthBehaviour='RoundUp'):
    assert endOfMonthBehaviour in ['RoundDown', 'RoundIn', 'RoundOut', 'RoundUp'], \
        'Unknown end of month behaviour'
    year = date.year + (date.month + months - 1) / 12
    month = (date.month + months - 1) % 12 + 1
    day = date.day
    last = monthrange(year, month)[1]
    if day > last:
        if endOfMonthBehaviour == 'RoundDown' or \
            endOfMonthBehaviour == 'RoundOut' and months < 0 or \
            endOfMonthBehaviour == 'RoundIn' and months > 0:
            day = last
        elif endOfMonthBehaviour == 'RoundUp' or \
            endOfMonthBehaviour == 'RoundOut' and months > 0 or \
            endOfMonthBehaviour == 'RoundIn' and months < 0:
            # we don't need to worry about incrementing the year
            # because there will never be a day in December > 31
            month += 1
            day = 1
    return datetime.date(year, month, day)


>>> from calendar import monthrange
>>> import datetime
>>> add_months(datetime.datetime(2016, 1, 31), 1)
datetime.date(2016, 3, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2)
datetime.date(2015, 12, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2, 'RoundDown')
datetime.date(2015, 11, 30)

1

vorausgesetzt, Ihre datetime-Variable heißt date:

date=datetime.datetime(year=date.year+int((date.month+6)/12),
                       month=(date.month+6)%13 + (1 if (date.month + 
                       months>12) else 0), day=date.day)

1

Allgemeine Funktion, um das nächste Datum nach / vor x Monaten zu erhalten.

ab Datum / Uhrzeit des Importdatums

def after_month (angegebenes_Datum, Monat):
    JJJJ = int (((angegebenes_Datum.Jahr * 12 + gegebenes_Datum.Monat) + Monat) / 12)
    mm = int (((angegebenes_Datum.Jahr * 12 + gegebenes_Datum.Monat) + Monat)% 12)

    wenn mm == 0:
        JJJJ - = 1
        mm = 12
    return Given_date.replace (Jahr = JJJJ, Monat = MM)


if __name__ == "__main__":
    heute = date.today ()
    drucken (heute)

    für mm in [-12, -1, 0, 1, 2, 12, 20]:
        next_date = after_month (heute mm)
        print (nächstes_Datum)

Dies ist eindeutig die beste Antwort. Einfach und effektiv, ohne Rundungsprobleme.
jprobichaud

1

Ein kurzer Vorschlag ist Arrow

Pip Installationspfeil

>>> import arrow

>>> arrow.now().date()
datetime.date(2019, 6, 28)
>>> arrow.now().shift(months=6).date()
datetime.date(2019, 12, 28)

0

Verwenden Sie das Python-Datum / Uhrzeit-Modul, um datetime.today () ein Zeitdelta von sechs Monaten hinzuzufügen.

http://docs.python.org/library/datetime.html

Sie müssen natürlich die Frage von Johannes Weiß-- angehoben lösen , was sie meinen Sie 6 Monate?


1
timedelta unterstützt keine Monate und umgeht daher die möglichen Antworten auf die Frage "Wie viele Tage in 6 Monaten?" Der Code von Eef legt ein Überprüfungsdatum fest, daher würde ich vorschlagen, dass das Zeitdelta mit Tagen (6 * 30) festgelegt werden kann. Wenn der Zeitraum den Zugriff der Kunden auf ein Produkt / eine Dienstleistung darstellt, ist möglicherweise eine Geschäftsdefinition erforderlich / bevorzugt.
Carl

0

Das habe ich mir ausgedacht. Es bewegt sich in der richtigen Anzahl von Monaten und Jahren, ignoriert jedoch Tage (was ich in meiner Situation brauchte).

import datetime

month_dt = 4
today = datetime.date.today()
y,m = today.year, today.month
m += month_dt-1
year_dt = m//12
new_month = m%12
new_date = datetime.date(y+year_dt, new_month+1, 1)

0

Ich benutze diese Funktion, um Jahr und Monat zu ändern, aber Tag behalten:

def replace_month_year(date1, year2, month2):
    try:
        date2 = date1.replace(month = month2, year = year2)
    except:
        date2 = datetime.date(year2, month2 + 1, 1) - datetime.timedelta(days=1)
    return date2

Sie sollten schreiben:

new_year = my_date.year + (my_date.month + 6) / 12
new_month = (my_date.month + 6) % 12
new_date = replace_month_year(my_date, new_year, new_month)

0

Ich denke, es wäre sicherer, so etwas zu tun, anstatt Tage manuell hinzuzufügen:

import datetime
today = datetime.date.today()

def addMonths(dt, months = 0):
    new_month = months + dt.month
    year_inc = 0
    if new_month>12:
        year_inc +=1
        new_month -=12
    return dt.replace(month = new_month, year = dt.year+year_inc)

newdate = addMonths(today, 6)
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.