Essaye ça:
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)
Modifier Corrigé pour gérer la journée également.
Edit Voir aussi la réponse de la perplexité qui souligne un calcul plus simple pour d
:
d = min(date.day, calendar.monthrange(y, m)[1])
((date.month+delta-1) % 12)+1
fonctionne et signifie que leif not m: m = 12
peut être retirédt - timedelta(days=dt.day)
Tel que formulé à l'origine, bien que cela sonnait comme s'ils voulaient être en mesure de soustraire un nombre arbitraire de mois et c'est un peu plus difficile.Vous pouvez utiliser le
dateutil
module tiers (entrée PyPI ici ).production:
la source
month
etmonths
dans dateutil. Soustraire avec parammonth
ne fonctionne pas maismonths
fonctionneIn [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
fera une différence d'un mois. L'utilisationmonth
définira le mois sur 1 (par exemple, janvier), quel que soit le mois de la saisie.Après la modification de la question d'origine sur "n'importe quel objet datetime du mois précédent", vous pouvez le faire assez facilement en soustrayant 1 jour du premier du mois.
la source
dt.replace(day=1) - timedelta(1)
dt - timedelta(days=dt.day)
Une variante de la réponse de Duncan (je n'ai pas assez de réputation pour commenter), qui utilise calendar.monthrange pour simplifier considérablement le calcul du dernier jour du mois:
Informations sur la plage mensuelle de Obtenir le dernier jour du mois en Python
la source
Une solution pandas vectorisée est très simple:
df['date'] - pd.DateOffset(months=1)
la source
pandas
. Merci!Que voulez-vous que le résultat soit lorsque vous soustrayez un mois, par exemple, à une date qui est le 30 mars? C'est le problème de l'addition ou de la soustraction de mois: les mois ont des durées différentes! Dans certaines applications, une exception est appropriée dans de tels cas, dans d'autres, le "dernier jour du mois précédent" est correct à utiliser (mais c'est une arithmétique vraiment folle, quand on soustrait un mois, puis en ajoutant un mois, ce n'est pas globalement une opération!) , dans d'autres encore, vous voudrez garder en plus de la date une indication sur le fait, par exemple, "Je dis le 28 février mais je voudrais vraiment le 30 février s'il existait", afin d'ajouter ou de soustraire un autre mois à qui peut redéfinir les choses correctement (et ce dernier nécessite évidemment une classe personnalisée contenant une donnée plus une autre chose).
Il ne peut y avoir de vraie solution tolérable pour toutes les applications, et vous ne nous avez pas dit quels sont les besoins de votre application spécifique pour la sémantique de cette opération misérable, donc nous ne pouvons pas fournir beaucoup plus d'aide ici.
la source
datetime
modules supposent qu'un jour est exactement 24 heures (pas de secondesJe pense que le moyen le plus simple est d'utiliser DateOffset de Pandas comme ceci:
Le résultat sera un objet datetime
la source
Si tout ce que vous voulez est n'importe quel jour du mois dernier, la chose la plus simple que vous pouvez faire est de soustraire le nombre de jours de la date actuelle, ce qui vous donnera le dernier jour du mois précédent.
Par exemple, à partir de n'importe quelle date:
En soustrayant les jours de la date actuelle, nous obtenons:
Cela suffit pour votre besoin simplifié de n'importe quel jour du mois dernier.
Mais maintenant que vous l'avez, vous pouvez également obtenir n'importe quel jour du mois, y compris le même jour que vous avez commencé (c'est-à-dire plus ou moins la même chose que de soustraire un mois):
Bien sûr, vous devez faire attention avec le 31e sur un mois de 30 jours ou les jours manquants à partir de février (et prendre soin des années bissextiles), mais c'est aussi facile à faire:
la source
Je l'utilise pour les exercices gouvernementaux où le quatrième trimestre commence le 1er octobre. Notez que je convertis la date en trimestres et je l'annule également.
la source
Voici un code pour faire exactement cela. Je n'ai pas essayé moi-même ...
la source
Étant donné un tuple (année, mois), où le mois va de 1 à 12, essayez ceci:
Suppose qu'il y a 12 mois dans chaque année.
la source
la source
J'ai utilisé le code suivant pour remonter n mois à partir d'une date spécifique:
Par exemple: date d'entrée = 28/12/2015 Calculer la date précédente de 6 mois.
I) CALCULER LE MOIS: Cette étape vous donnera la date de début au 30/06/2015.
Notez qu'après l'étape de calcul du mois, vous obtiendrez le dernier jour du mois requis.
II) CALCULER DAY: Condition if (start_date.day> your_date.day) vérifie si le jour de input_date est présent dans le mois requis. Cela gère la condition où la date d'entrée est 31 (ou 30) et le mois requis a moins de 31 (ou 30 en cas de février) jours. Il gère également le cas des années bissextiles (pour février). Après cette étape, vous obtiendrez le résultat du 28/06/2015
Si cette condition n'est pas remplie, start_date reste la dernière date du mois précédent. Donc, si vous donnez 31/12/2015 comme date d'entrée et que vous voulez une date antérieure de 6 mois, cela vous donnera 30/06/2015
la source
Vous pouvez utiliser la fonction ci-dessous pour obtenir la date avant / après X mois.
la source
Je pense que cette réponse est assez lisible:
la source
Bon mot ?
previous_month_date = (current_date - datetime.timedelta(days=current_date.day+1)).replace(day=current_date.day)
la source
La manière la plus simple que j'ai essayée tout à l'heure
la source
Il y a quelque temps, je suis tombé sur l'algorithme suivant qui fonctionne très bien pour incrémenter et décrémenter des mois sur a
date
oudatetime
.CAVEAT : Cela échouera s'il
day
n'est pas disponible dans le nouveau mois. J'utilise ceci sur les objets de date oùday == 1
toujours.Python 3.x:
Pour Python 2.7, remplacez le
//12
par juste/12
car la division entière est implicite.J'ai récemment utilisé ceci dans un fichier par défaut lorsqu'un script a commencé à obtenir ces globaux utiles:
la source
Solution simple, pas besoin de bibliothèques spéciales.
la source
Vous pouvez le faire en deux lignes comme ceci:
rappelez-vous les importations
la source