J'ai besoin d'incrémenter le mois d'une valeur datetime
next_month = datetime.datetime(mydate.year, mydate.month+1, 1)
quand le mois est 12, il devient 13 et pose l'erreur "le mois doit être dans 1..12". (Je m'attendais à ce que l'année augmente)
Je voulais utiliser timedelta, mais cela ne prend pas mois argument. Il existe un package relativedelta python, mais je ne souhaite pas l'installer uniquement pour cela. Il existe également une solution utilisant strtotime .
time = strtotime(str(mydate));
next_month = date("Y-m-d", strtotime("+1 month", time));
Je ne veux pas convertir datetime en str puis en time, puis en datetime; donc, c'est toujours une bibliothèque aussi
Quelqu'un a-t-il une bonne et solution simple semblable à l'utilisation de timedelta?
Edit - En fonction de votre commentaire, il faut arrondir les dates s'il y a moins de jours le mois prochain. Voici une solution:
import datetime
import calendar
def add_months(sourcedate, months):
month = sourcedate.month - 1 + months
year = sourcedate.year + month // 12
month = month % 12 + 1
day = min(sourcedate.day, calendar.monthrange(year,month)[1])
return datetime.date(year, month, day)
Utilisé:
>>> somedate = datetime.date.today()
>>> somedate
datetime.date(2010, 11, 9)
>>> add_months(somedate,1)
datetime.date(2010, 12, 9)
>>> add_months(somedate,23)
datetime.date(2012, 10, 9)
>>> otherdate = datetime.date(2010,10,31)
>>> add_months(otherdate,1)
datetime.date(2010, 11, 30)
De plus, si vous n'êtes pas inquiet pour les heures, les minutes et les secondes, vous pouvez utiliser date
plutôt que datetime
. Si vous vous inquiétez des heures, des minutes et des secondes, vous devez modifier mon code pour utiliser datetime
et copier les heures, les minutes et les secondes de la source au résultat.
C'est une méthode courte et agréable pour ajouter un mois à une date en utilisant dateutil's relativedelta
.
from datetime import datetime
from dateutil.relativedelta import relativedelta
date_after_month = datetime.today()+ relativedelta(months=1)
print 'Today: ',datetime.today().strftime('%d/%m/%Y')
print 'After Month:', date_after_month.strftime('%d/%m/%Y')
Sortie:
Aujourd'hui: 01/03/2013
Après le mois: 01/04/2013
Un mot d'avertissement : relativedelta(months=1)
et relativedelta(month=1)
ont significations différentes . Passer month=1
remplacera le mois de la date d'origine en janvier alors que passer months=1
ajoutera un mois à la date d'origine.
Remarque: cela nécessite python-dateutil
. Pour l'installer, vous devez utiliser un terminal Linux.
Sudo apt-get update && Sudo apt-get install python-dateutil
Explication: Ajouter la valeur du mois en python
Voici mon sel:
current = datetime.datetime(mydate.year, mydate.month, 1)
next_month = datetime.datetime(mydate.year + (mydate.month / 12), ((mydate.month % 12) + 1), 1)
Rapide et facile :)
puisque personne n'a suggéré de solution, voici comment j'ai résolu jusqu'à présent
year, month= divmod(mydate.month+1, 12)
if month == 0:
month = 12
year = year -1
next_month = datetime.datetime(mydate.year + year, month, 1)
Utilisez le package monthdelta , il fonctionne comme timedelta mais pour les mois calendaires plutôt que pour les jours/heures/etc.
Voici un exemple:
from monthdelta import MonthDelta
def prev_month(date):
"""Back one month and preserve day if possible"""
return date + MonthDelta(-1)
Comparez cela à l'approche DIY:
def prev_month(date):
"""Back one month and preserve day if possible"""
day_of_month = date.day
if day_of_month != 1:
date = date.replace(day=1)
date -= datetime.timedelta(days=1)
while True:
try:
date = date.replace(day=day_of_month)
return date
except ValueError:
day_of_month -= 1
Pour calculer le mois en cours, précédent et suivant:
import datetime
this_month = datetime.date.today().month
last_month = datetime.date.today().month - 1 or 12
next_month = (datetime.date.today().month + 1) % 12 or 12
from datetime import timedelta
try:
next = (x.replace(day=1) + timedelta(days=31)).replace(day=x.day)
except ValueError: # January 31 will return last day of February.
next = (x + timedelta(days=31)).replace(day=1) - timedelta(days=1)
Si vous voulez simplement le premier jour du mois prochain:
next = (x.replace(day=1) + timedelta(days=31)).replace(day=1)
Cette implémentation pourrait avoir une certaine valeur pour quelqu'un qui travaille avec la facturation.
Si vous travaillez avec la facturation, vous voudrez probablement avoir "la même date le mois prochain (si possible)" par opposition à "ajouter 1/12 d'un an".
Ce qui est tellement déroutant à ce sujet, c’est que vous devez réellement prendre en compte deux valeurs si vous le faites de manière continue. Sinon, pour les dates après le 27, vous perdrez quelques jours jusqu'à ce que vous finissiez au 27 après une année bissextile.
Les valeurs que vous devez prendre en compte:
De cette façon, si vous êtes décalé du 31 au 30 quand vous ajoutez un mois, vous serez renvoyé au 31 pour le mois suivant.
Voici comment je l'ai fait:
def closest_date_next_month(year, month, day):
month = month + 1
if month == 13:
month = 1
year = year + 1
condition = True
while condition:
try:
return datetime.datetime(year, month, day)
except ValueError:
day = day-1
condition = day > 26
raise Exception('Problem getting date next month')
paid_until = closest_date_next_month(
last_paid_until.year,
last_paid_until.month,
original_purchase_date.day) # The trick is here, I'm using the original date, that I started adding from, not the last one
Qu'en est-il de celui-ci? (ne nécessite aucune bibliothèque supplémentaire)
from datetime import date, timedelta
from calendar import monthrange
today = date.today()
month_later = date(today.year, today.month, monthrange(today.year, today.month)[1]) + timedelta(1)
Peut-être ajouter le nombre de jours du mois en cours en utilisant calendar.monthrange ()?
import calendar, datetime
def increment_month(when):
days = calendar.monthrange(when.year, when.month)[1]
return when + datetime.timedelta(days=days)
now = datetime.datetime.now()
print 'It is now %s' % now
print 'In a month, it will be %s' % increment_month(now)
La solution la plus simple est d'aller à la fin du mois (nous savons toujours que les mois ont au moins 28 jours) et d'ajouter suffisamment de jours pour passer au mois prochain:
>>> from datetime import datetime, timedelta
>>> today = datetime.today()
>>> today
datetime.datetime(2014, 4, 30, 11, 47, 27, 811253)
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
datetime.datetime(2014, 5, 30, 11, 47, 27, 811253)
Fonctionne également entre les années:
>>> dec31
datetime.datetime(2015, 12, 31, 11, 47, 27, 811253)
>>> today = dec31
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
Gardez simplement à l'esprit qu'il n'est pas garanti que le mois suivant aura le même jour. Par exemple, si vous passez du 31 janvier au 31 février, cela échouera:
>>> today
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
>>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: day is out of range for month
Il s’agit donc d’une solution valable si vous devez passer au premier jour du mois suivant, car vous savez toujours que le mois suivant a un jour 1 (.replace(day=1)
). Sinon, pour passer au dernier jour disponible, vous pouvez utiliser:
>>> today
datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
>>> next_month = (today.replace(day=28) + timedelta(days=10))
>>> import calendar
>>> next_month.replace(day=min(today.day,
calendar.monthrange(next_month.year, next_month.month)[1]))
datetime.datetime(2016, 2, 29, 11, 47, 27, 811253)
Semblable dans l’idéal à la solution de Dave Webb, mais sans toute cette arithmétique modulo délicate:
import datetime, calendar
def increment_month(date):
# Go to first of this month, and add 32 days to get to the next month
next_month = date.replace(day=1) + datetime.timedelta(32)
# Get the day of month that corresponds
day = min(date.day, calendar.monthrange(next_month.year, next_month.month)[1])
return next_month.replace(day=day)
Je cherchais à résoudre le problème lié à la recherche de la date du premier jour du mois suivant, peu importe du jour de la date indiquée. Cela ne trouve pas le même jour 1 mois plus tard.
Donc, si tout ce que vous voulez, c'est mettre le 12 décembre 2014 (ou n'importe quel jour de décembre) et revenir le 1er janvier 2015, essayez ceci:
import datetime
def get_next_month(date):
month = (date.month % 12) + 1
year = date.year + (date.month + 1 > 12)
return datetime.datetime(year, month, 1)
def add_month(d,n=1): return type(d)(d.year+(d.month+n-1)/12, (d.month+n-1)%12+1, 1)
Bien avec quelques ajustements et l'utilisation de timedelta on y va:
from datetime import datetime, timedelta
def inc_date(Origin_date):
day = Origin_date.day
month = Origin_date.month
year = Origin_date.year
if Origin_date.month == 12:
delta = datetime(year + 1, 1, day) - Origin_date
else:
delta = datetime(year, month + 1, day) - Origin_date
return Origin_date + delta
final_date = inc_date(datetime.today())
print final_date.date()
C'est ce que je suis venu avec
from calendar import monthrange
def same_day_months_after(start_date, months=1):
target_year = start_date.year + ((start_date.month + months) / 12)
target_month = (start_date.month + months) % 12
num_days_target_month = monthrange(target_year, target_month)[1]
return start_date.replace(year=target_year, month=target_month,
day=min(start_date.day, num_days_target_month))
Une solution sans calendrier:
def add_month_year(date, years=0, months=0):
year, month = date.year + years, date.month + months + 1
dyear, month = divmod(month - 1, 12)
rdate = datetime.date(year + dyear, month + 1, 1) - datetime.timedelta(1)
return rdate.replace(day = min(rdate.day, date.day))
def month_sub(year, month, sub_month):
result_month = 0
result_year = 0
if month > (sub_month % 12):
result_month = month - (sub_month % 12)
result_year = year - (sub_month / 12)
else:
result_month = 12 - (sub_month % 12) + month
result_year = year - (sub_month / 12 + 1)
return (result_year, result_month)
def month_add(year, month, add_month):
return month_sub(year, month, -add_month)
>>> month_add(2015, 7, 1)
(2015, 8)
>>> month_add(2015, 7, 20)
(2017, 3)
>>> month_add(2015, 7, 12)
(2016, 7)
>>> month_add(2015, 7, 24)
(2017, 7)
>>> month_add(2015, 7, -2)
(2015, 5)
>>> month_add(2015, 7, -12)
(2014, 7)
>>> month_add(2015, 7, -13)
(2014, 6)
Il suffit d'utiliser ceci:
import datetime
today = datetime.datetime.today()
nextMonthDatetime = today + datetime.timedelta(days=(today.max.day - today.day)+1)