Versuche dies:
def monthdelta(date, delta):
m, y = (date.month+delta) % 12, date.year + ((date.month)+delta-1) // 12
if not m: m = 12
d = min(date.day, [31,
29 if y%4==0 and not y%400==0 else 28,31,30,31,30,31,31,30,31,30,31][m-1])
return date.replace(day=d,month=m, year=y)
>>> for m in range(-12, 12):
print(monthdelta(datetime.now(), m))
2009-08-06 16:12:27.823000
2009-09-06 16:12:27.855000
2009-10-06 16:12:27.870000
2009-11-06 16:12:27.870000
2009-12-06 16:12:27.870000
2010-01-06 16:12:27.870000
2010-02-06 16:12:27.870000
2010-03-06 16:12:27.886000
2010-04-06 16:12:27.886000
2010-05-06 16:12:27.886000
2010-06-06 16:12:27.886000
2010-07-06 16:12:27.886000
2010-08-06 16:12:27.901000
2010-09-06 16:12:27.901000
2010-10-06 16:12:27.901000
2010-11-06 16:12:27.901000
2010-12-06 16:12:27.901000
2011-01-06 16:12:27.917000
2011-02-06 16:12:27.917000
2011-03-06 16:12:27.917000
2011-04-06 16:12:27.917000
2011-05-06 16:12:27.917000
2011-06-06 16:12:27.933000
2011-07-06 16:12:27.933000
>>> monthdelta(datetime(2010,3,30), -1)
datetime.datetime(2010, 2, 28, 0, 0)
>>> monthdelta(datetime(2008,3,30), -1)
datetime.datetime(2008, 2, 29, 0, 0)
Bearbeiten Korrigiert, um auch den Tag zu bewältigen.
Bearbeiten Siehe auch die Antwort aus der Verwirrung, die eine einfachere Berechnung für Folgendes aufzeigt d
:
d = min(date.day, calendar.monthrange(y, m)[1])
((date.month+delta-1) % 12)+1
funktioniert es und bedeutet, dass dieif not m: m = 12
Dose entfernt werden kanndt - timedelta(days=dt.day)
Wie ursprünglich formuliert gemacht werden kann, obwohl es sich anhörte, als wollten sie in der Lage sein, eine beliebige Anzahl von Monaten zu subtrahieren, und das ist etwas schwieriger.Sie können das Drittanbieter-
dateutil
Modul verwenden (PyPI-Eintrag hier ).Ausgabe:
quelle
month
undmonths
in Dateutil. Subtrahieren mit parammonth
funktioniert nicht, abermonths
funktioniertIn [23]: created_datetime__lt - relativedelta(months=1) Out[23]: datetime.datetime(2016, 11, 29, 0, 0, tzinfo=<StaticTzInfo 'Etc/GMT-8'>) In [24]: created_datetime__lt - relativedelta(month=1) Out[24]: datetime.datetime(2016, 1, 29, 0, 0, tzinfo=<StaticTzInfo 'Etc/GMT-8'>)
months
wird einen Unterschied von 1 Monat machen. Mitmonth
wird der Monat auf 1 gesetzt (z. B. Januar), unabhängig vom Monat der Eingabe.Nachdem die ursprüngliche Frage zu "einem beliebigen Datum / Uhrzeit-Objekt im vorherigen Monat" bearbeitet wurde, können Sie dies ganz einfach tun, indem Sie 1 Tag vom ersten des Monats abziehen.
quelle
dt.replace(day=1) - timedelta(1)
dt - timedelta(days=dt.day)
Eine Variation von Duncans Antwort (ich habe nicht genügend Ruf, um sie zu kommentieren), die calendar.monthrange verwendet, um die Berechnung des letzten Tages des Monats dramatisch zu vereinfachen:
Info zu monthrange von Get Last Day of the Month in Python
quelle
Eine vektorisierte Pandas-Lösung ist sehr einfach:
df['date'] - pd.DateOffset(months=1)
quelle
pandas
. Vielen Dank!Was soll das Ergebnis sein, wenn Sie einen Monat beispielsweise von einem Datum abziehen, das der 30. März ist? Das ist das Problem beim Addieren oder Subtrahieren von Monaten: Monate haben unterschiedliche Längen! In einigen Anwendungen ist in solchen Fällen eine Ausnahme angebracht, in anderen ist "der letzte Tag des Vormonats" in Ordnung (aber das ist wirklich verrückte Arithmetik, wenn man einen Monat subtrahiert und dann einen Monat addiert) dies insgesamt keine Operation!) In anderen Fällen möchten Sie zusätzlich zu dem Datum einige Hinweise auf die Tatsache behalten, z. B. "Ich sage den 28. Februar, aber ich möchte wirklich den 30. Februar, wenn er existiert", damit Sie einen weiteren Monat hinzufügen oder davon abziehen das kann die Dinge wieder in Ordnung bringen (und letzteres erfordert offensichtlich eine benutzerdefinierte Klasse, die Daten plus s / thing else enthält).
Es kann keine wirkliche Lösung geben, die für alle Anwendungen tolerierbar ist, und Sie haben uns nicht mitgeteilt, welche Anforderungen Ihre spezifische App an die Semantik dieser erbärmlichen Operation stellt. Daher können wir hier nicht viel mehr Hilfe anbieten.
quelle
datetime
Module gehen davon aus, dass ein Tag genau 24 Stunden (keine Schaltsekunden ) istIch denke, der einfache Weg ist, DateOffset von Pandas wie folgt zu verwenden:
Das Ergebnis ist ein Datum / Uhrzeit-Objekt
quelle
Wenn Sie nur einen Tag im letzten Monat wünschen, können Sie am einfachsten die Anzahl der Tage vom aktuellen Datum abziehen, um den letzten Tag des Vormonats zu erhalten.
Zum Beispiel beginnend mit einem beliebigen Datum:
Wenn wir die Tage des aktuellen Datums abziehen, erhalten wir:
Dies reicht für Ihren vereinfachten Bedarf an jedem Tag im letzten Monat.
Aber jetzt, wo Sie es haben, können Sie auch jeden Tag im Monat erhalten, einschließlich des gleichen Tages, mit dem Sie begonnen haben (dh mehr oder weniger das gleiche wie das Subtrahieren eines Monats):
Natürlich müssen Sie mit dem 31. an einem 30-Tage-Monat oder den ab Februar fehlenden Tagen vorsichtig sein (und sich um Schaltjahre kümmern), aber das ist auch einfach zu tun:
quelle
Ich benutze dies für Regierungsjahre, in denen das vierte Quartal am 1. Oktober beginnt. Hinweis Ich konvertiere das Datum in Viertel und mache es auch rückgängig.
quelle
Hier ist ein Code , um genau das zu tun. Ich habe es nicht selbst ausprobiert ...
quelle
Versuchen Sie Folgendes bei einem (Jahr, Monat) Tupel, bei dem der Monat von 1 bis 12 reicht:
Angenommen, jedes Jahr gibt es 12 Monate.
quelle
quelle
Ich habe den folgenden Code verwendet, um n Monate von einem bestimmten Datum zurück zu gehen:
Zum Beispiel: Eingabedatum = 28.12.2015 6 Monate vorheriges Datum berechnen.
I) MONAT BERECHNEN: In diesem Schritt erhalten Sie das Startdatum als 30/06/2015.
Beachten Sie, dass Sie nach dem Schritt "Monat berechnen" den letzten Tag des gewünschten Monats erhalten.
II) TAG BERECHNEN: Bedingung if (start_date.day> your_date.day) prüft, ob der Tag von input_date im erforderlichen Monat vorhanden ist. Dies behandelt Bedingungen, bei denen das Eingabedatum 31 (oder 30) ist und der erforderliche Monat weniger als 31 (oder 30 im Februar) Tage hat. Es behandelt auch Schaltjahrfälle (für Februar). Nach diesem Schritt erhalten Sie das Ergebnis als 28/06/2015
Wenn diese Bedingung nicht erfüllt ist, bleibt das Startdatum das letzte Datum des Vormonats. Wenn Sie also den 31.12.2015 als Eingabedatum angeben und 6 Monate vor dem Datum möchten, erhalten Sie den 30.06.2015
quelle
Sie können die unten angegebene Funktion verwenden, um das Datum vor / nach X Monat abzurufen.
quelle
Ich denke, diese Antwort ist gut lesbar:
quelle
Einzeiler ?
previous_month_date = (current_date - datetime.timedelta(days=current_date.day+1)).replace(day=current_date.day)
quelle
Einfachste Art und Weise, wie ich es gerade versucht habe
quelle
Vor einiger Zeit bin ich auf den folgenden Algorithmus gestoßen, der sehr gut zum Inkrementieren und Dekrementieren von Monaten auf einem
date
oder einem funktioniertdatetime
.CAVEAT : Dies schlägt fehl, wenn
day
es im neuen Monat nicht verfügbar ist. Ich benutze diese an Datum Objekte woday == 1
immer.Python 3.x:
Ändern Sie für Python 2.7 das
//12
in,/12
da die Ganzzahldivision impliziert ist.Ich habe dies kürzlich in einer Standarddatei verwendet, als ein Skript begann, diese nützlichen globalen Elemente abzurufen:
quelle
Einfache Lösung, keine speziellen Bibliotheken erforderlich.
quelle
Sie können dies in zwei Zeilen wie folgt tun:
Erinnere dich an die Importe
quelle